تعدد العملاء في Qdrant ليس فلترًا واحدًا يضاف إلى استعلام بحث مشترك. يحتاج التصميم الإنتاجي ثلاثة حدود واضحة: يحدد التفويض أي عميل يحق للمتصل الوصول إليه، ويقيّد الاسترجاع المرشحين بهذا العميل، وتحسب Sparse Search ندرة الكلمات من Corpus الصحيح. يمكن لـCustom Shards أن تضيف التحكم في موضع البيانات ونطاق العطل للعملاء الكبار أو المنظمين، لكنها لا تستبدل تفويض التطبيق. البداية الآمنة لكثير من منتجات SaaS هي Collection متجانسة واحدة، وفلتر `tenant_id` موثوق في كل عملية، وKeyword Payload Index يحمل `is_tenant=true`، واختبارات عزل تفشل إذا ظهرت نقطة لعميل آخر.
تم التحقق في 7 أكتوبر 2026 من وثائق Qdrant حول Multitenancy وIndexing وSearch. توفر الخصائص وسلوك المحرك الموثق حقائق من Qdrant، أما خدمة التفويض وبوابات النشر واختبارات العزل وسياسة ترقية العملاء فهي توصيات هندسية، وليست ضمانًا لعزل حسابات Qdrant Cloud أو لنشر لم يُختبر.
افصل أربعة معانٍ للعزل
تستخدم الفرق عبارة «عزل العملاء» لوصف ضوابط مختلفة. Query Isolation يعني ألا يعيد الطلب Points لعميل آخر. Administrative Isolation يمنع مشغّل عميل من عرض بيانات عميل آخر أو حذفها أو إعادة تهيئتها. Performance Isolation يحد أثر الجار الصاخب. Placement Isolation يحدد Shard أو Node أو Region التي تخزن البيانات. لا توفر آلية واحدة الحدود الأربعة.
يدعم Payload Filter عزل الاستعلام فقط عندما يبنيه كود موثوق من هوية مصادق عليها ويرفقه بكل Read وWrite وUpdate وScroll وCount وDelete. يساعد `is_tenant` في Locality وأداء البحث المفلتر. يحدد Shard Key الأجزاء الفيزيائية التي تصل إليها العملية. وتقدم Collection مستقلة حدًا أقوى للتهيئة ودورة الحياة. أما Rate Limits وQuotas وAdmission Control فتعالج عدالة الموارد.
اكتب هذه الضمانات في مصفوفة قبل اختيار Topology. إذا احتاج عميل منظم مفتاح تشفير خاصًا أو Backup مستقلًا أو Region محددة، فقد لا يلبي Payload Partition مشترك العقد الإداري حتى لو كانت الفلاتر صحيحة. وإذا شارك آلاف العملاء الصغار Schema ونموذج Embedding نفسه، فقد تضيف Collection لكل عميل كلفة تشغيلية غير لازمة.
المطلب الضابط الأساسي
منع ظهور نقطة لعميل آخر Payload Filter موثوق وإلزامي
تجميع Vectors العميل على التخزين Keyword Index مع is_tenant=true
عزل ندرة الكلمات في Sparse Search Tenant-scoped params.idf.corpus
توجيه العمليات إلى أجزاء محددة Custom shard_key_selector
فصل Schema أوModel أوLifecycle Collection مستقلة
ضبط استهلاك عميل صاخب Quota وRate Limit وAdmission Controlثبّت سياق العميل قبل Vector Database
يجب ألا يختار العميل الخارجي `tenant_id` بنفسه. احسم السياق بعد Authentication من Membership أوEntitlement Store. تمرر API Gateway هوية داخلية موقعة، ثم تبني Retrieval Service فلتر Qdrant منها. وإذا انتمى المستخدم إلى عدة مؤسسات، فاطلب مؤسسة فعالة واحدة لكل طلب أو Workflow عابرًا للمؤسسات بتفويض مستقل.
استخدم المسار نفسه للكتابة. Update بواسطة Point ID دون شرط العميل لا يقل خطرًا عن Search غير مفلتر. اجعل Point IDs فريدة عالميًا أو مرتبطة بالعميل، لكن لا تعامل شكل ID كأنه Authorization. عند حذف مستند ضمّن شروط العميل والمستند والنسخة. وعند Hydration من PostgreSQL أوObject Storage، أعد فحص صلاحية العميل في مصدر الحقيقة؛ فقد تبقى نتيجة Vector Store بعد تغير العضوية.
function tenantScope(principal, requestedOrg) {
const tenantId = entitlements.requireMembership(principal, requestedOrg);
return {
must: [
{ key: 'tenant_id', match: { value: tenantId } },
{ key: 'state', match: { value: 'published' } }
]
};
}
const result = await qdrant.query('knowledge', {
query: queryVector,
using: 'dense_v3',
filter: tenantScope(session.user, request.org),
limit: 20,
with_payload: ['document_id', 'chunk_id', 'version']
});اجعل Builder صغيرًا ومركزيًا، ولا تعرض Qdrant Client عامًا يمكن لRoute أوAgent تجاوزه. يمكن للنموذج اقتراح كلمات البحث، لكنه لا يقرر نطاق التفويض.
أنشئ Tenant Payload Index قبل الإدخال
ليست Payload Indexes مجرد مسرعات Lookup؛ فهي تمنح Query Planner تقدير Cardinality وتساعد Filterable HNSW على المرور داخل الرسم تحت الفلاتر. أنشئ الفهارس للحقول المستخدمة فعليًا، خصوصًا Tenant Key وحالة النشر، قبل Bulk Ingestion متى أمكن. فهرسة كل حقل تستهلك الذاكرة ووقت البناء، لذا ابدأ بالحقول الأكثر تقييدًا للمرشحين.
يدعم Qdrant منذ v1.11 Keyword Payload Index مع `is_tenant=true`. تخبر الإشارة Qdrant أن القيم تمثل مجموعات عملاء وتسمح بتجميع نقاط العميل لقراءات أكثر تسلسلًا. لكنها لا تصادق المتصل ولا تضيف Filter تلقائيًا.
PUT /collections/knowledge/index
{
"field_name": "tenant_id",
"field_schema": {
"type": "keyword",
"is_tenant": true
}
}أنشئ Collection والفهارس المطلوبة عبر Infrastructure Code لها نسخ واضحة، ثم أدخل البيانات. افحص حالة Collection في Staging وشغّل اختبارات Latency وRecall مفلترة بعد كل تغيير. وإذا أضفت Index إلى Collection قائمة فخطط لعمل Optimizer وتحقق من اكتمال Segments. وتذكر أن الطلبات العالمية قد تصبح أبطأ في تهيئة HNSW الموجهة للعملاء؛ اجعل بحث الإدارة العالمي Workflow مصرحًا مستقلًا لا Query عرضيًا بلا `tenant_id`.
افصل Retrieval Scope عن Sparse IDF Scope
تقارن Dense Search المتجهات ولا تعتمد على إحصاءات الكلمات. أما BM25 وminiCOIL فيستخدمان Inverse Document Frequency لرفع وزن المصطلحات النادرة. في التقسيم بالـPayload كان Qdrant يحسب IDF على مستوى Shard، فيمزج مفردات العملاء: قد يبدو Product Code نادر عند العميل A شائعًا لأن عملاء آخرين يستخدمونه كثيرًا.
يضيف Qdrant v1.19 معامل `idf` يقبل `corpus` مفلترًا. يظل Retrieval Filter منفصلًا عن Scoring Corpus. قد يسترجع الطلب مستندات العميل A المنشورة بالعربية فقط، بينما يحسب IDF على جميع مستندات العميل A. جعل Corpus مساويًا لفلتر سنة أوCategory ضيقة قد ينتج إحصاءات ندرة مضطربة، وجعله عالميًا يسمح لبقية العملاء بتغيير توزيع الدرجات.
POST /collections/knowledge/points/query
{
"query": { "text": "invoice NY-4821", "model": "qdrant/bm25" },
"using": "title-bm25",
"filter": {
"must": [
{ "key": "tenant_id", "match": { "value": "tenant-a" } },
{ "key": "state", "match": { "value": "published" } },
{ "key": "language", "match": { "value": "en" } }
]
},
"params": {
"idf": {
"corpus": {
"must": [
{ "key": "tenant_id", "match": { "value": "tenant-a" } }
]
}
}
},
"limit": 10
}في Hybrid Search طبّق نطاق الاسترجاع الموثوق على Dense وSparse معًا، وTenant Corpus على Sparse. خلل تفويض في أحد Prefetches قد يستهلك Candidate Budget بنقاط غير متاحة حتى لو حذفها فلتر متأخر. يشرح دليل Hybrid Search في Qdrant Fusion وCandidate Depth؛ ويجب أن يسبق عقد العزل الدمج.
اختر Shared أوTiered أوDedicated بوعي
تكون Collection مشتركة بداية مناسبة عندما يستخدم العملاء Vector Dimensions وDistance Metric وPayload Schema وRetention Policy نفسها. تقلل الكلفة الإدارية وتجعل التهيئة موحدة. أضف Mandatory Filters وTenant Indexes وResource Quotas.
يرقي Tiered Multitenancy العملاء الكبار أو المنظمين إلى Custom Shard Keys، ويبقي Long Tail مشتركًا. يسمح Custom Sharding للتطبيق باختيار `shard_key_selector` في Upsert وQuery. قد يمثل المفتاح Region أوCapacity Tier، بينما يظل `tenant_id` هوية العميل داخل Shard. بذلك ينفصل Placement عن Authorization. احتفظ بدليل موثوق يربط العميل بـCollection وShard Key وPolicy Version، ولا تستخرج التوجيه من حقل طلب غير موثوق.
استخدم Collection مستقلة عندما يحتاج العميل نموذج Embedding أوDimension مختلفة، أوSchema Migration مستقلة، أوReplication وRetention وBackup وEncryption وOperational Ownership خاصة. واستخدم Cluster أوAccount مستقلة إذا تجاوز العقد ما يناسب الإدارة المشتركة. لا تبدأ Collection لكل مستخدم بصورة تلقائية؛ العدد الكبير يضاعف عمل Optimizer وIndexing وMonitoring.
Tenant directory
tenant-a -> collection=knowledge, shard=shared-eu, policy=v7
tenant-b -> collection=knowledge, shard=dedicated-b, policy=v3
tenant-c -> collection=regulated-c, shard=eu-central, policy=v9الترقية Workflow هجرة: Dual Read أوShadow Read وBackfill وفحص اتساق وتحويل Route ونافذة Rollback. استخدم مبادئ ترحيل Embeddings في Qdrant مع قياس اكتمال البيانات بين Topologies لا الصلة فقط.
اعتبر Custom Sharding موضعًا لا صلاحية
يقلل Shard Selector نطاق Fan-out، وقد يعزل موارد عميل كبير أو يحقق موضعًا إقليميًا. لكنه ليس Authorization Token. إذا اختار التطبيق Shard خاطئة أو حذف فلتر العميل داخل Shard مشتركة، فلن يستنتج Qdrant حدود العمل من الهوية التجارية.
يجب أن تحسم كل عملية القيمتين من Tenant Directory نفسها: يحتوي Retrieval Filter على هوية العميل، ويحمل Shard Selector موضعه. تحقق أن العميل مسموح في Shard المختارة وارفض الحالة المجهولة أوالمهاجرة. سجّل Tenant وShard وCollection وPolicy Version وRequest ID، من دون تسجيل نص السؤال الخاص افتراضيًا.
لا تنفذ Cross-tenant Analytics عبر Product Endpoint بعد حذف الفلتر. أنشئ Batch Pipeline وهوية خدمة وOutput Store مستقلة مع Purpose Limitation واضحة. قد تكون عمليات البحث العالمية أبطأ في HNSW موجه للعملاء، والأهم أن المسار الصريح يمنع إعطاء المتصلين التفاعليين Global Search Primitive.
اختبر العزل كـInvariant لا كعرض
أنشئ عملاء اصطناعيين بمستندات متشابهة عمدًا، وأعط كلًا منهم Canary IDs مختلفة. اختبر كل عملية: Query وScroll وRecommend وCount وUpdate وSet Payload وDelete، وتأكد أن Credential للعميل A لا ترى ولا تغير B. نفذ الاختبارات عبر Routes وBackground Jobs وAgent Tools كلها.
تستطيع Property-based Tests توليد العملاء والمستندات والأدوار والفلاتر. ويجب أن تحذف Mutation Tests شرط العميل وتثبت أن الاختبار يفشل. أضف Sentinel Query إنتاجية لا تحتوي إلا Canaries اصطناعية، ونبّه عند ظهور عميل أجنبي. أي Cross-tenant Hit حادث أمني حتى إذا أخفت مرحلة لاحقة النص عن المستخدم.
يحتاج تقييم الصلة حدود العميل أيضًا. تتبع Recall@k وnDCG وZero-result Rate وLatency بحسب فئة حجم العميل. في Sparse Search قارن Global IDF وTenant IDF بمصطلحات تختلف Frequencies بين العملاء. وفي HNSW المفلتر قارن Approximate Search مع Exact على عينة معلّمة. يوثق Qdrant ACORN لتركيبات الفلاتر الصارمة التي تقطع Traversal؛ فعّلها فقط بعد Benchmark يثبت مشكلة Accuracy تستحق التكلفة.
شغّل الهجرة والحذف والفشل بأمان
حذف العميل Workflow لا API Call واحدة. أوقف الكتابات الجديدة، وألغ العضويات، واحذف Points أوضع Tombstones بشرط العميل، وتحقق أن Count صار صفرًا، ثم احذف المحتوى الثانوي والنسخ بحسب السياسة واحتفظ بإيصال Audit محدود. يجب أن تستأنف الخطوات Idempotently. ولا تقبل Tenant ID من Delete Request قبل إثبات الملكية وتفويض العملية الحساسة.
أثناء Re-embedding أوBackfill، احفظ Tenant وShard Metadata على كل Point جديدة. هجرة تنسخ Vectors وتنسى Payload أوRouting قد تنجح في اختبارات الصلة وتكسر العزل. ويجب أن تستخدم Shadow Queries سياق العميل الموثوق نفسه على المسارين. يشرح مسار RAG الإنتاجي السلسلة الأوسع من Chunking إلى Context Construction.
راقب Filtered Latency ونسبة HNSW إلىExact وOptimizer Backlog وShard Imbalance وStorage لكل عميل وRate-limit Rejections وEmpty Candidate Sets وAuthorization Denials. لا تصنّف كل Zero Result كفشل بحث؛ قد يكون النتيجة الصحيحة بعد إلغاء الصلاحية. افصل Security Signals عن Relevance Metrics.
متى لا تستخدم بحث Qdrant متعدد العملاء
استخدم SQL عندما تكون الإجابة Entitlement أوBalance أوOrder State أوInventory Quantity دقيقة. استخدم Full-text Search تقليديًا إذا كان Corpus صغيرًا وتكفي المطابقة اللفظية ولم تثبت Vectors قيمة إضافية. ولا تضع Workloads عالية الحساسية داخل Collection مشتركة إذا طلب التنظيم أوالعقد إدارة أوKeys أوRetention أوBackups مستقلة.
لا تستخدم Embeddings كـAccess Control List. ولا تعتمد على Prompt يقول «أجب من بيانات هذا العميل فقط». لا تستخدم Post-filter بعد Nearest-neighbor Search غير مقيد. لا تعرض Qdrant Client عامًا لـAI Agent. ولا تفترض أن Shard Key أو`is_tenant` أوPoint ID فريد يثبت صلاحية المتصل.
الخلاصة التنفيذية قصيرة: استخرج سياق العميل من Membership مصادق عليها، واحسم Placement من Directory موثوق، وألزم كل عملية بفلتر العميل، وافهرس الحقل مع `is_tenant`، واحسب Sparse IDF داخل العميل، وأعد فحص الصلاحية عند Hydration، ورقِّ العملاء الكبار عبر هجرة مقاسة، واختبر Cross-tenant Canaries باستمرار. يطبّق المهندس نور الدين ياسر النحال هذا النوع من الفصل بين هوية العميل واسترجاع الدليل في تصميم أنظمة SaaS وRAG؛ ويمكن مراجعة خدمة تكاملات AI وأنظمة الاسترجاع لفهم نطاق التنفيذ.
المراجع الرسمية
تدعم هذه المراجع سلوك الأدوات المذكورة. الأمثلة وقرارات التصميم توضيحية، ويجب تكييفها مع متطلبات المشروع وإصداراته.
إعداد: Noor Yasser
تعمل على تحدٍ تقني مشابه؟
أساعد الفرق على تحويل القرار المعماري إلى نطاق واضح وتنفيذ يمكن تشغيله ومراجعته بثقة.




