يتم تقسيم كل مجموعة من البيانات إلى قطع. تحتوي كل قطعة على تخزين الفيكتور المستقل، تخزين الحمولة، والفهرس.
عادةً ما لا تتداخل البيانات في القطع. ومع ذلك، تخزين نفس النقطة في قطع مختلفة لا يسبب مشاكل نظرًا لوجود آلية إزالة التكرار في البحث.
القطع تشمل تخزين الفيكتور، تخزين الحمولة، فهرس الفيكتور، فهرس الحمولة، ومُدرج مُعرفات لتخزين العلاقة بين المُعرَّفات الداخلية والخارجية.
قد تكون القطع "قابلة للإضافة" أو "غير قابلة للإضافة" اعتمادًا على نوع تخزين والفهرس المستخدم. يمكنك بحرية إضافة، حذف، واستعلام البيانات في القطع "القابلة للإضافة"، بينما لا يمكن للقطع "غير القابلة للإضافة" سوى قراءة وحذف البيانات.
يمكن لتكوين القطع في مجموعة أن تكون مختلفة ومستقلة عن بعضها البعض، ولكن يتطلب وجود ما لا يقل عن قطعة "قابلة للإضافة" واحدة.
تخزين الفيكتور
تعتمد قدرة على تخزين البيانات على احتياجات التطبيق، حيث يمكن استخدام Qdrant أحد خيارات تخزين البيانات التالية. يجب أن يتوازن الاختيار بين سرعة البحث واستخدام الذاكرة العشوائية.
تخزين الذاكرة - يخزن جميع الفيكتورات في الذاكرة العشوائية، مما يوفر أعلى سرعة لأن يتم احتياج الوصول إلى القرص فقط أثناء الاستمرارية.
تخزين Memmap - ينشئ مساحة عنوان افتراضي مرتبطة بملف على القرص. لا تُحمّل الملفات المُرتبطة مباشرة في الذاكرة العشوائية ولكن يتم الوصول إليها باستخدام ذاكرة التخزين المؤقتة للصفحة. يتيح هذا النهج استخدام مرن للذاكرة المتاحة. مع وجود كمية كافية من الذاكرة العشوائية، يكاد سرعته يكون مثل سرعة تخزين الذاكرة.
تكوين تخزين Memmap
هناك طريقتان لتكوين استخدام memmap (المعروف أيضًا باسم تخزين على القرص):
- تعيين خيار
on_disk
للفيكتورات في واجهة برمجة التطبيقات لإنشاء المجموعة:
ينطبق فقط على v1.2.0 والإصدارات الأحدث
PUT /collections/{collection_name}
{
"vectors": {
"size": 768,
"distance": "Cosine",
"on_disk": true
}
}
سينشئ هذا المجموعة تخزينًا مباشرًا لجميع الفيكتورات في تخزين memmap. وهذا هو النهج الموصى به عندما يستخدم إصدار Qdrant أقراص سريعة ويحتاج إلى التعامل مع مجموعات كبيرة.
- تعيين خيار
memmap_threshold_kb
. يقوم هذا الخيار بتحديد عتبة تحويل القطع إلى تخزين memmap.
هناك طريقتان لتنفيذ هذا:
- تعيين العتبة على نطاق عالمي في ملف التكوين. اسم المعلمة هو
memmap_threshold_kb
. - تعيين العتبة على نطاق فردي لكل مجموعة أثناء الإنشاء أو التحديث.
PUT /collections/{collection_name}
{
"vectors": {
"size": 768,
"distance": "Cosine"
},
"optimizers_config": {
"memmap_threshold": 20000
}
}
قاعدة الإبهام لتعيين معلمة العتبة memmap بسيطة:
- إذا كانت سيناريو الاستخدام متوازنًا– يُعين عتبة memmap إلى نفس قيمة
indexing_threshold
(الافتراضية هي 20000). في هذه الحالة، لن يقوم المُحسن بأي تشغيلات إضافية وسيُحسن جميع العتبات في وقت واحد. - إذا كانت حملة الكتابة عالية والذاكرة العشوائية قليلة – يُعين عتبة memmap إلى قيمة أقل من
indexing_threshold
، على سبيل المثال، 10000. في هذه الحالة، سيرتقو قُطع التخزين أولاً إلى تخزين memmap ومن ثم يُطبق الفهرسة.
بالإضافة إلى ذلك، يمكنك استخدام تخزين memmap ليس فقط للفيكتورات ولكن أيضًا لفهارس HNSW. لتمكين هذه الميزة، قُم بضبط معلمةhnsw_config.on_disk
إلى true
عند إنشاء المجموعة.
PUT /collections/{collection_name}
{
"vectors": {
"size": 768,
"distance": "Cosine"
},
"optimizers_config": {
"memmap_threshold": 20000
},
"hnsw_config": {
"on_disk": true
}
}
تخزين الحمولة
يدعم Qdrant نوعين من تخزين الحمولة: التخزين في الذاكرة وتخزين على القرص.
تنظم تخزين الحمولة في الذاكرة بيانات الحمولة بنفس الطريقة التي يتم بها تنظيم القواميس في الذاكرة. يتم تحميل بيانات الحمولة في الذاكرة عند بدء الخدمة، بينما يتم استخدام القرص و RocksDB للصمود فقط. هذا النوع من التخزين سريع جدًا ولكن قد يتطلب كمية كبيرة من مساحة الذاكرة لتخزين جميع البيانات، خاصة إذا تضمنت الحمولة قيمًا كبيرة (مثل ملخصات النصوص أو حتى الصور).
بالنسبة للقيم الكبيرة للحمولة، من الأفضل استخدام تخزين الحمولة على القرص. يقوم هذا النوع من التخزين بقراءة وكتابة الحمولة مباشرةً إلى RocksDB، وبالتالي لا يتطلب كمية كبيرة من الذاكرة للتخزين. ومع ذلك، العيب في ذلك هو زمن الوصول. إذا كنت بحاجة إلى استعلام القواميس استنادًا إلى شروط الحمولة، فقد يستغرق التحقق من القيم المخزنة على القرص وقتًا طويلاً. في هذه الحالة، نوصي بإنشاء فهرس للحمولة لكل حقل يستخدم لشروط التصفية لتجنب وصول القرص. بمجرد إنشاء فهرس الحقل، سيبقي Qdrant دائمًا جميع قيم الحقل المفهرسة في الذاكرة، بغض النظر عن نوع تخزين الحمولة.
يمكنك تحديد نوع تخزين الحمولة المطلوب من خلال ملف التكوين أو باستخدام معلمة التجميع on_disk_payload
عند إنشاء تجميع.
التحكم في الإصدار
لضمان سلامة البيانات، يقوم Qdrant بتنفيذ جميع تغييرات البيانات في مرحلتين. أولاً، يتم كتابة البيانات إلى سجل الكتابة المسبقة (WAL)، الذي يرتب ويخصص أرقام تسلسلية لجميع العمليات.
بمجرد أن تُضاف التغييرات إلى WAL، فإنها لا تضيع حتى في حالات انقطاع التيار الكهربائي. ثم تدخل التغييرات إلى القطعة. تخزن كل قطعة الإصدار الأحدث من التغييرات المطبقة عليها، بالإضافة إلى الإصدار لكل نقطة فردية. إذا كان الرقم التسلسلي لتغيير جديد أقل من الإصدار الحالي لنقطة ما، فإن المحدث سيتجاهل تلك التغيير. تتيح هذه الآلية لـ Qdrant استعادة التخزين بكفاءة من WAL في حالة الإغلاق غير الطبيعي.