لماذا تستضيف Weaviate ذاتيًا على خادم VPS
لا يكتفي Weaviate بتخزين المتجهات. فكل كائن يحمل خصائصه (نصوص وأرقام وتواريخ ومراجع) ومتجهًا واحدًا أو أكثر، بحيث يعيد استعلام واحد المستندات ذات الصلة مع كل بياناتها الوصفية. تحسب وحدات text2vec-* التضمينات (embeddings) عند الاستيراد، وترسل وحدات generative-* النتائج إلى نموذج لغوي كبير، وتعيد وحدات إعادة الترتيب (reranker) ترتيب المرشحين. ويمكن الاستعلام عن كل ذلك عبر REST أو GraphQL أو gRPC. تتيح لك الاستضافة الذاتية على خادم VPS اختيار الوحدات المفعّلة، وربط نماذج التضمين الخاصة بك (مثلًا عبر Ollama على الجهاز نفسه)، والإبقاء على المستندات والمتجهات في خادم تديره بنفسك. وسواء تعلّق الأمر بمساعد توثيق داخلي أو محرك بحث في كتالوج أو ذاكرة لوكيل ذكي، فأنت تتحكم في زمن الاستجابة ومدة الاحتفاظ بالبيانات ومخطط المجموعات ووتيرة النسخ الاحتياطي. كما توسّع موارد الخادم بحسب نمو بياناتك، لا بحسب جدول فوترة قائم على الحجم.
ما يقدّمه Weaviate عمليًا
- تحويل متجهي مدمج — مع وحدة
text2vec-*تُدرج نصًا خامًا ويحسب Weaviate المتجه بنفسه. - بحث هجين أصلي — يجمع استعلام
hybridبين الدرجة المتجهية ودرجة BM25، بوزن يحدده المعاملalpha. - RAG داخل قاعدة البيانات — ترسل وحدات
generative-*الكائنات المسترجعة إلى نموذج لغوي وتعيد الإجابة مع مصادرها. - تعدد المستأجرين (multi-tenancy) — shard معزول لكل عميل داخل المجموعة نفسها، وهو مثالي لخدمة SaaS تفصل بيانات كل حساب.
- المتجهات المسمّاة (named vectors) — عدة متجهات لكل كائن (العنوان والمحتوى والصورة)، لكلٍّ منها vectorizer وفهرس خاص به.
- ضغط الفهرس — تكميم PQ أو BQ أو SQ لتقليص الذاكرة التي تشغلها المتجهات.
- رخصة BSD-3-Clause — شيفرة قابلة للتدقيق ويمكن نشرها دون الاعتماد على خدمة مُدارة.
المتطلبات بالأرقام لخادم VPS يشغّل Weaviate
للتجربة على بضعة آلاف من الكائنات تكفي ذاكرة 2 غيغابايت. أما للاستخدام الفعلي مع تفويض التحويل المتجهي إلى واجهة API أو إلى Ollama، فإن 4 غيغابايت ومعالجين افتراضيين (2 vCPU) نقطة انطلاق مريحة. وإذا شغّلت text2vec-transformers على الجهاز نفسه فخطّط لـ8 غيغابايت أو أكثر، لأن الاستدلال على المعالج المركزي بطيء عند الاستيراد الكثيف. على مستوى القرص، احسب من 30 إلى 60 غيغابايت من SSD بحسب الحجم، واترك هامشًا كافيًا لأن Weaviate ينتقل إلى وضع القراءة فقط عندما يتجاوز إشغال القرص عتبة محددة (DISK_USE_READONLY_PERCENTAGE، وقيمتها الافتراضية 90%). ثلاثة منافذ مهمة: 8080 لـREST وGraphQL، و50051 لـgRPC (يستخدمه عميل Python v4 في الاستعلامات والاستيراد)، و2112 لمقاييس Prometheus إن فعّلتها. لا ينبغي كشف أيٍّ منها مباشرة على الإنترنت، بل يجب أن يواجه الجمهورَ وكيلٌ عكسي (reverse proxy) عبر HTTPS فقط، على نطاق فرعي مثل vectors.example.com. وتحتاج أخيرًا إلى Docker وDocker Compose، وهما مثبّتان مسبقًا على الخوادم المنشأة من Marketplace.
أي vectorizer تختار
مرّر الجدول أفقيًا
| الخيار | أين يعمل النموذج | متى تختاره |
|---|---|---|
| none مع متجهاتك الخاصة | داخل تطبيقك، قبل الاستيراد | عندما تحسب التضمينات بنفسك أو تريد تحكمًا كاملًا في النموذج |
| text2vec-openai | واجهة API خارجية، والمفتاح يُرسل في الترويسة X-OpenAI-Api-Key | بداية سريعة، خادم خفيف، وبيانات يُسمح لها بمغادرة الخادم |
| text2vec-ollama | خادم Ollama على الـVPS أو على الشبكة الخاصة | تضمينات محلية دون معالج رسوميات مخصص، بنموذج مثل nomic-embed-text |
| text2vec-transformers | حاوية استدلال بجانب Weaviate | نموذج مضمّن في الصورة، ويُفضّل مع معالج رسوميات للاستيراد الكبير |
| عدة خيارات عبر named vectors | مزيج من الخيارات السابقة | مقارنة نموذجين أو تحويل العنوان والمحتوى كلٍّ على حدة |
نشر Weaviate خطوة بخطوة
تجهيز الخادم وسجلات DNS
تحقق من Docker بالأمر
docker compose version. أنشئ سجل DNS من النوع A للنطاقvectors.example.comيشير إلى عنوان IP الخادم، ثم مجلدًا/opt/weaviateيحتوي على ملفdocker-compose.yml.كتابة خدمة weaviate
صرّح بالصورة
semitechnologies/weaviate:1.27.2(المنشورة أيضًا علىcr.weaviate.io). انشر المنافذ محليًا فقط:127.0.0.1:8080:8080و127.0.0.1:50051:50051. يتجاوز Docker قواعدufwفي المنافذ المنشورة، لذا يبقى ربط من نوع8080:8080متاحًا من الإنترنت حتى مع تفعيل الجدار الناري. اربط مجلدًا مسمّى (named volume) بالمسار/var/lib/weaviateوأضفrestart: unless-stopped.ضبط المتغيرات الأساسية
PERSISTENCE_DATA_PATH=/var/lib/weaviateلحفظ البيانات، وQUERY_DEFAULTS_LIMIT=25لعدد النتائج الافتراضي، وCLUSTER_HOSTNAME=node1لاسم عقدة ثابت: فإذا تغيّر بين إعادتي تشغيل لم تعد العقدة تجد حالتها. أضفDEFAULT_VECTORIZER_MODULE=noneأو الوحدة التي تختارها، وENABLE_API_BASED_MODULES=trueلتفعيل الوحدات التي تستدعي واجهة API (text2vec-openaiوtext2vec-ollamaوgenerative-openai…).تفعيل المصادقة بمفتاح API
اضبط
AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED=false، ثمAUTHENTICATION_APIKEY_ENABLED=trueوAUTHENTICATION_APIKEY_ALLOWED_KEYS=admin-key,read-keyوAUTHENTICATION_APIKEY_USERS=admin,app-reader، إذ تتطابق المفاتيح والمستخدمون بحسب الترتيب. ولّد المفاتيح بالأمرopenssl rand -hex 32. ولقصر المفتاح الثاني على القراءة، أضفAUTHORIZATION_ADMINLIST_ENABLED=trueوAUTHORIZATION_ADMINLIST_USERS=adminوAUTHORIZATION_ADMINLIST_READONLY_USERS=app-reader.التشغيل والتحقق
شغّل
docker compose up -dثمcurl -s localhost:8080/v1/.well-known/readyالذي يعيد الرمز 200 عندما تصبح العقدة جاهزة. ويعيد الأمرcurl -s -H "Authorization: Bearer $KEY" localhost:8080/v1/metaرقم الإصدار وقائمة الوحدات المحمّلة، وهو أول فحص تجريه حين يبدو أن أحد الـvectorizers غير متاح.وضع Nginx وTLS أمام المنفذ 8080
اضبط كتلة
serverفي Nginx للنطاقvectors.example.comمعproxy_pass http://127.0.0.1:8080;، وأصدر الشهادة بالأمرcertbot --nginx -d vectors.example.com، وارفع قيمةclient_max_body_sizeإن كنت تستورد دفعات عبر REST. تُمرَّر الترويسةAuthorizationإلى Weaviate كما هي.الاتصال بعميل Python v4
ثبّت العميل بالأمر
pip install -U weaviate-client. على الخادم نفسه:client = weaviate.connect_to_local(port=8080, grpc_port=50051, auth_credentials=Auth.api_key(KEY))معfrom weaviate.classes.init import Auth. ومن خادم آخر، استخدمweaviate.connect_to_custom(...)مع تحديد المضيف والمنفذ وTLS لكلٍّ من HTTP وgRPC. تحقق بالأمرclient.is_ready()واختم بـclient.close().إنشاء مجموعة والاستيراد
استخدم
client.collections.create("Article", ...)مع خصائصها والـvectorizer، ثمarticles = client.collections.get("Article"). استورد على دفعات داخل كتلةwith articles.batch.dynamic() as batch:باستدعاءbatch.add_object(properties={...})، وأضفvector=[...]إذا كان الـvectorizer هوnone. ثم افحصarticles.batch.failed_objectsلرصد الكائنات المرفوضة.ربط بقية منظومة الذكاء الاصطناعي
للحصول على تضمينات وتوليد محليّين بالكامل، ثبّت Ollama على الخادم نفسه ووجّه
text2vec-ollamaوgenerative-ollamaإلى واجهته البرمجية. بعد ذلك يستعلم Open WebUI أو تطبيق RAG الخاص بك من Weaviate بوصفه ذاكرة المستندات.
نمذجة البيانات: المجموعات وتعدد المستأجرين والمتجهات المسمّاة
تعيش البيانات في Weaviate داخل مجموعات (collections)، وكانت تُسمّى أصنافًا (classes) في الواجهة البرمجية القديمة. تحدّد المجموعة خصائصها المصنّفة بأنواع (text وint وnumber وdate وboolean ومراجع إلى مجموعات أخرى)، والـvectorizer الخاص بها، وإعدادات فهرسها. صرّح بالخصائص صراحةً بدل ترك المخطط التلقائي يخمّنها عند أول إدراج، لأن حقل تاريخ يُخمَّن على أنه نص لم يعد يُصفّى بشكل صحيح. ولخدمة SaaS، فعّل تعدد المستأجرين عند الإنشاء عبر multi_tenancy_config=Configure.multi_tenancy(enabled=True): يحصل كل مستأجر على shard خاص به، ويُستعلم عنه عبر collection.with_tenant("customer-a")، ويمكن تعطيل المستأجر غير النشط لتحرير الذاكرة. وأخيرًا تتيح المتجهات المسمّاة إرفاق عدة متجهات بالكائن نفسه، مثلًا واحد للعنوان وآخر للمحتوى، لكلٍّ منهما نموذجه وفهرسه. انتبه إلى أن الـvectorizer ونوع الفهرس في مجموعة ما لا يمكن تغييرهما لاحقًا، وأي تغيير يتطلب مجموعة جديدة وإعادة استيراد.
الاستعلام في Weaviate: الاستعلامات المفيدة
- البحث الدلالي — يتطلب
articles.query.near_text(query="فسخ العقد", limit=5)وجود vectorizer، وإلا فاستخدمnear_vectorمع تضمينك الخاص. - البحث الهجين — في
articles.query.hybrid(query="فاتورة مكررة", alpha=0.5)تعطيalpha=1بحثًا متجهيًا خالصًا، وتعطيalpha=0بحثًا بـBM25 خالصًا. - الكلمات المفتاحية فقط — يستخدم
articles.query.bm25(query="GDPR")الفهرس المعكوس، وهو مفيد للمراجع ورموز المنتجات وأسماء العلم. - المرشّحات — يُستورد
filters=Filter.by_property("language").equal("ar")منweaviate.classes.query، ويمكن دمجه مع كل الاستعلامات السابقة. - RAG مدمج — يعيد
articles.generate.near_text(query=..., limit=3, grouped_task="أجب انطلاقًا من هذه المقتطفات")الكائنات وإجابة النموذج اللغوي المضبوط. - GraphQL — تبقى نقطة النهاية
/v1/graphqlمتاحة للأدوات التي تعتمد عليها، مع المعاملاتnearTextوhybridوbm25.
فهرس HNSW أو flat أو dynamic وتقدير الذاكرة
تستخدم كل مجموعة افتراضيًا فهرس HNSW، وهو سريع لكنه محفوظ في الذاكرة. وتقدّم وثائق Weaviate قاعدة تقريبية: خطّط لنحو ضعف الحجم الخام للمتجهات. فمليون متجه بـ768 بُعدًا بصيغة float32 يشغل قرابة 3 غيغابايت، أي نحو 6 غيغابايت من الذاكرة للفهرس. أما فهرس flat فلا يحتفظ بشيء في الذاكرة ويناسب المجموعات الصغيرة، ولا سيما مستأجري خدمة SaaS. ويبدأ فهرس dynamic بصيغة flat ثم ينتقل إلى HNSW بعد تجاوز عتبة من الكائنات، ويتطلب ASYNC_INDEXING=true. ولتقليص الاستهلاك فعّل التكميم (quantization): يضغط PQ (product quantization) بقوة بعد مرحلة تدريب على بياناتك، ويختزل BQ (binary quantization) كل بُعد إلى بت واحد ويناسب خصوصًا المتجهات عالية الأبعاد، ويخزّن SQ (scalar quantization) كل بُعد في بايت واحد. اضبط أيضًا GOMEMLIMIT على نحو 80% من الذاكرة المخصصة للحاوية، حتى يتدخل جامع المهملات في Go قبل أن تُنهي النواةُ العملية.
النسخ الاحتياطي والتحديثات
أضف ENABLE_MODULES=backup-filesystem وBACKUP_FILESYSTEM_PATH=/var/lib/weaviate/backups، ثم أطلق نسخة احتياطية بالأمر curl -X POST -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" -d '{"id":"nightly-20261001"}' localhost:8080/v1/backups/filesystem. تُقرأ الحالة عبر GET /v1/backups/filesystem/nightly-20261001، وتتم الاستعادة عبر POST /v1/backups/filesystem/nightly-20261001/restore. لا تحميك نسخة احتياطية على القرص نفسه من فقدان الخادم، لذا انسخ المجلد إلى مكان آخر أو استخدم backup-s3 مع BACKUP_S3_BUCKET نحو تخزين كائنات متوافق مع S3. وللتحديث، اقرأ ملاحظات الترحيل الخاصة بالإصدار المستهدف، وخذ نسخة احتياطية، وغيّر وسم الصورة، ثم شغّل docker compose pull && docker compose up -d. انتقل بين الإصدارات الفرعية واحدًا تلو الآخر، ولا تعد أبدًا إلى إصدار أقدم على البيانات نفسها دون استعادة نسخة احتياطية.
لا تترك منفذ gRPC رقم 50051 مفتوحًا على الإنترنت: تستخدمه تطبيقات الخادم نفسه محليًا، ويمر الجهاز البعيد عبر نفق ssh -L 50051:localhost:50051 user@vps. ويربط النشر من Marketplace هذا المنفذ بالعنوان 127.0.0.1، ويبدأ مع إتاحة الوصول المجهول لتسهيل التجربة الأولى، لذا فعّل المصادقة بمفتاح API قبل استيراد أي بيانات. امنح تطبيقك مفتاحًا للقراءة فقط، واحتفظ بمفتاح الإدارة لعمليات الاستيراد والنسخ الاحتياطي.
مراقبة Weaviate
فعّل PROMETHEUS_MONITORING_ENABLED=true، فيعرض Weaviate حينها مقاييسه على المنفذ 2112 (/metrics) لتجمعها أداة Prometheus وتعرضها Grafana. راقب أولًا ذاكرة العملية ومدة الاستيراد على دفعات وعدد الكائنات في كل مجموعة. وتصلح نقطتا النهاية /v1/.well-known/live و/v1/.well-known/ready مجسّاتٍ لفحص صحة Docker (healthcheck) أو لأداة مثل Uptime Kuma. وعلى مستوى النظام، يعرض docker stats الاستهلاك اللحظي للحاوية، ويعرض df -h إشغال المجلد، وهو ما يستحق متابعة دقيقة لأن الانتقال إلى القراءة فقط يسببه القرص لا الذاكرة. وأخيرًا تابع السجلات بالأمر docker compose logs -f weaviate، إذ تظهر فيها أخطاء الوحدات وإخفاقات التحويل المتجهي مع اسم الكائن المعني.
حل الأعطال: الأخطاء الأكثر شيوعًا
- استجابة 401 على كل الطلبات — الوصول المجهول معطّل والطلب لا يرسل
Authorization: Bearer <key>، أو أن المفتاح غير مدرج فيAUTHENTICATION_APIKEY_ALLOWED_KEYS. - عميل Python v4 يرفض الاتصال — فهو يتحقق من gRPC أيضًا: يجب أن يكون المنفذ
50051متاحًا من جهة العميل، محليًا أو عبر نفق SSH، وأن تتطابق قيمةgrpc_port. - وحدة غير موجودة عند إنشاء مجموعة — الوحدة غير محمّلة: افحص
ENABLE_MODULESوENABLE_API_BASED_MODULESوالقائمة التي تعيدها/v1/meta. - حاوية تعيد التشغيل برمز الخروج 137 — أنهتها النواة لنفاد الذاكرة: اضبط
GOMEMLIMITأو فعّل التكميم أو زِد ذاكرة الخادم. - استيراد مرفوض بسبب وضع القراءة فقط — تجاوز القرص قيمة
DISK_USE_READONLY_PERCENTAGE: حرّر مساحة أو وسّع المجلد، ثم أعد الـshards إلى وضع الكتابة. - أخطاء تحويل متجهي عند الاستيراد — مفتاح API لدى المزوّد مفقود (
X-OpenAI-Api-Keyيُمرَّر فيheadersالخاصة بالعميل)، أو أن خادم Ollama غير متاح من حاوية Weaviate.
Weaviate أم Qdrant أم pgvector أم Milvus
مرّر الجدول أفقيًا
| المعيار | Weaviate | Qdrant | pgvector | Milvus |
|---|---|---|---|---|
| الطبيعة | قاعدة متجهية مكتوبة بـGo | قاعدة متجهية مكتوبة بـRust | امتداد لـPostgreSQL | قاعدة متجهية موزّعة |
| تحويل متجهي مدمج | نعم، عبر وحدات text2vec-* | لا، يوفّر العميلُ التضمينات | لا، يوفّر التطبيقُ التضمينات | غالبًا من جهة العميل |
| الواجهة البرمجية | REST وGraphQL وgRPC | REST وgRPC | SQL | gRPC وREST وحزم SDK |
| البحث الهجين والمرشّحات | BM25 مع المتجهات أصليًا، ومرشّحات | مرشّحات على الـpayload، ومتجهات متفرقة | WHERE في SQL، والبحث النصي في PostgreSQL يُدمج يدويًا | مرشّحات قياسية، وBM25 في الإصدارات الحديثة |
| الاستهلاك على خادم VPS | متوسط، حاوية واحدة | منخفض، حاوية واحدة | استهلاك PostgreSQL لديك | أثقل، مع etcd وMinIO في الوضع standalone |
| الضغط | PQ وBQ وSQ | قياسي وثنائي وضغط المنتج | halfvec وbit | عدة فهارس مكمّمة (IVF_PQ وIVF_SQ8…) |
| الرخصة | BSD-3-Clause | Apache 2.0 | رخصة PostgreSQL | Apache 2.0 |
| حالة الاستخدام النموذجية | RAG متكامل مع تحويل متجهي مدمج | بحث متجهي مقتصد في الموارد | متجهات بجانب بيانات علائقية | أحجام ضخمة جدًا ونشر في عنقود |
متى يكون Weaviate الخيار المناسب
يكون Weaviate مبرَّرًا حين تريد أن تتولى قاعدة البيانات التحويل المتجهي والبحث الهجين والتوليد، بدل أن تجمعها بنفسك في شيفرة التطبيق. وهو يناسب مساعد التوثيق، والبحث في كتالوج متعدد اللغات، وخدمة SaaS تعزل كل عميل في مستأجر خاص به. أما إذا كنت تحسب التضمينات بنفسك وتبحث عن أدنى استهلاك للموارد، فإن Qdrant أكثر اقتصادًا. وإذا كانت بياناتك أصلًا في PostgreSQL والحجم متواضعًا، فإن pgvector يوفّر عليك مكوّنًا إضافيًا. ويستهدف Milvus الأحجام الموزعة الضخمة جدًا، على حساب بنية تحتية أثقل. على خادم VPS، ابدأ بعقدة واحدة وفهرس HNSW ومفتاح API ونسخ احتياطي يومي، ثم أضف التكميم وتعدد المستأجرين حين تستدعي القياسات ذلك. وللتعمق أكثر، اطّلع على أدلتنا حول Qdrant وOllama وOpen WebUI، التي تكمل Weaviate ضمن منظومة RAG مستضافة ذاتيًا.
انشر Weaviate على خادم VPS
اطلب خادم VPS من ServOrbit وانشر Weaviate في نقرات قليلة من Marketplace — Ubuntu 24.04 وDocker مثبَّت مسبقًا وصورة semitechnologies/weaviate:1.27.2 جاهزة للتشغيل.