OpenSearch وOpenSearch Dashboards: قارِن، اختَر، هاجِر
يُعيد Karim قراءة شروط استعمال Elastic ويسأل Inès في اجتماع المنتج: «هل يمكننا التّحوّل إلى OpenSearch لتفادي مفاجآت الرّخصة حين يمرّ Veille إلى SaaS؟». يأخذ الفريق نصف يوم لإعادة تنفيذ استعلامات الدّورة على fork من AWS، ويقارن المحرّكَين بأمانة، ويقرّر. ترسم هذه الوحدة الحدود بين ما هو متطابق، وما يتباعد، وما يهمّ فعلًا لمنتج يبيع البحث.
من أين جاء الـfork
نقطة التّحوّل هي يناير 2021. حتّى ذلك الوقت، كان Elasticsearch وKibana يُنشران تحت رخصة Apache 2.0، وهي رخصة متساهلة تُتيح لأيّ أحد، بما في ذلك مضيف سحابيّ، إعادة بيع البرمجيّة. تُعلن Elastic الانتقال إلى SSPL / ELv2 ثنائيًّا (Server Side Public License وElastic License 2.0) ابتداءً من النّسخة 7.11. الرّسالة صريحة: لم تعد AWS قادرة على تقديم خدمتها المُدارة باسم «Elasticsearch» دون التّفاوض على اتّفاق تجاريّ. SSPL، المشتقّة من AGPL، تشترط مشاركة الشّيفرة كاملةً بالرّخصة نفسها المستعملة لتقديم الخدمة كـSaaS؛ وELv2 تمنع التّقديم المُدار كخدمة.
فبراير 2021، تردّ AWS بـfork. نقطة الانطلاق هي آخر نسخة Apache 2.0: Elasticsearch 7.10.2 وKibana 7.10.2. يُعاد تسمية الـfork إلى OpenSearch وOpenSearch Dashboards، ويُطَوَّر علنًا، محكومًا في البداية من AWS. النّسخة 1.0 تصدر في صيف 2021.
منذ ذلك الحين، تطوّران بارزان. في 2024، تُضيف Elastic AGPLv3 خيارًا ثالثًا لـElasticsearch: يمكن للمستخدمين اختيار SSPL أو ELv2 أو AGPLv3. عودة جزئيّة إلى المنظومة مفتوحة المصدر الكلاسيكيّة — لكن مسألة SaaS تبقى. في السّنة نفسها، يخرج OpenSearch من احتضان AWS الحصريّ وينضمّ إلى Linux Foundation ضمن مؤسّسة جديدة، OpenSearch Software Foundation، تحضرها أيضًا Uber وSAP وAiven وBytedance وآخرون. تصبح الحوكمة بحقّ متعدّدة الأطراف.
كلّ مفردات الدّورة (فهرس، shard، mapping، text مقابل keyword، التّجميعات، Query DSL) تبقى صحيحة في الجهتَين. الف وارق تعلو ذلك: الإدارة والأمن والإضافات التّجاريّة ولغات الاستعلام الحديثة.
جدول مقارنة
يتّبع الجدول أدناه النّسخة 9.5.3 من Elasticsearch الّتي تُسلَّم في الحقيبة والنّسخة 3.8.0 من OpenSearch، وقت الكتابة.
| المعيار | Elasticsearch 9.5 | OpenSearch 3.8 |
|---|---|---|
| الرّخصة | SSPL أو ELv2 أو AGPLv3 (خيار) | Apache 2.0 |
| الحوكمة | Elastic N.V. | OpenSearch Software Foundation (Linux Foundation) |
| الأمن (auth وRBAC وTLS) | مُضمَّن في basic المجّانيّة | إضافة security مُضمَّنة، مجّانيّة |
| Console ويب | Kibana | OpenSearch Dashboards |
| SQL / PPL | SQL basic؛ ES|QL منذ 8.11 | إضافة sql: SQL وPPL، مجّانيّتان |
| البحث الشّعاعيّ | dense_vector و kNN أصليّ وELSER وsemantic_text | إضافة k-NN، Neural Search |
| Alerting | Basic ومستويات مدفوعة | إضافة Alerting مُضمَّنة، مجّانيّة |
| دورة حياة الفهارس | ILM | ISM (Index State Management)، إضافة |
| العملاء الرّسميّون | elasticsearch v8 / v9 | opensearch-py، وforks لـJS وJava وGo |
| توافق العملاء بين المحرّكَين | عميل v8+ غير متوافق مع OpenSearch | عميل OpenSearch لا يُوصى به لـElastic |
| المُضيفون المُدارون | Elastic Cloud وBonsai وAiven | AWS OpenSearch Service وAiven وBonsai |
سطران يستحقّان التّعمّق. الأمن المُضمَّن: في Elasticsearch، TLS والمستخدمون والأدوار في رخصة basic المجّانيّة منذ 2020، وهو ما يجهله الكثيرون بعد. تستعمله حقيبة veille-es. من جهة OpenSearch، إضافة security مُدمَجة أصليًّا (لكنّها مُعطَّلة في الملفّ المقارن للحقيبة تبسيطًا لقراءة URL). لغات الأنبوب: ES|QL في جهة Elastic، وPPL في جهة OpenSearch، جوابان متمايزان لحاجة واحدة — استبدال أنابيب JSON الطّويلة في Query DSL ببنية خطّيّة قابلة للقراءة.
Elasticsearch (ES|QL)
FROM news | WHERE category == "POLITICS" | STATS c = COUNT() BY category | SORT c DESC
OpenSearch (PPL)
source=news | where category="POLITICS" | stats count() by category | sort -count()
تشغيل OpenSearch في الحقيبة
تُسلِّم الحقيبة ملفًّا مخصَّصًا يتعايش مع Elasticsearch بتحويل المنافذ (9201 و5602). الأمن مُعطَّل طوعًا في هذا الملفّ لتبقى وحدة المقارنة قابلة للقراءة؛ في الإنتاج، نُفعِّل إضافة security وTLS.
./lab.sh opensearch-up
المتوقَّع في النّهاية:
[OK] OpenSearch prêt sur http://localhost:9201 — Dashboards sur http://localhost:5602
فحص سريع بلا مصادقة:
GET _cluster/health
الاستجابة المتوقَّعة:
{
"cluster_name": "veille-os",
"status": "green",
"number_of_nodes": 1,
"active_primary_shards": "(votre chiffre peut différer)"
}
إعادة تنفيذ ثلاثة استعلامات من الدّورة
تعيش مدوَّنة News في Elasticsearch، لا في OpenSearch — وهذه بالضّبط النّقطة. لمقارنة Query DSL دون إعادة استيراد 200 853 وثيقة، أنشئ فهرسًا صغيرًا بثلاث مقالات في OpenSearch Dashboards → Dev Tools (http://localhost:5602/app/dev_tools#/console).
PUT news
{
"settings": { "number_of_shards": 1, "number_of_replicas": 0 },
"mappings": {
"properties": {
"headline": { "type": "text" },
"category": { "type": "keyword" },
"date": { "type": "date" }
}
}
}
POST news/_bulk
{ "index": {} }
{ "headline": "Change Is Here. Climate Change.", "category": "POLITICS", "date": "2017-06-02" }
{ "index": {} }
{ "headline": "How To Cook A Perfect Steak At Home", "category": "TASTE", "date": "2015-11-14" }
{ "index": {} }
{ "headline": "Reuters: Markets Watch Fed Signals", "category": "BUSINESS", "date": "2018-01-09" }
الاستعلام 1 — بحث نصّيّ:
GET news/_search
{
"query": { "match": { "headline": "climate change" } }
}
النّتيجة المتوقَّعة: hit واحد بـ_score غير صفريّ على مقال POLITICS. على المدوَّنة الحقيقيّة في Elasticsearch (الوحدة 5)، يُعيد الاستعلام نفسه 2 834 نتيجة.
الاستعلام 2 — تجميع terms على category:
GET news/_search
{
"size": 0,
"aggs": {
"par_categorie": { "terms": { "field": "category", "size": 5 } }
}
}
المتوقَّع هنا: 3 buckets بمقال واحد لكلّ منها. على المدوَّنة الحقيقيّة، تُعيد الكتلة نفسها POLITICS 32 739 وWELLNESS 17 827 وENTERTAINMENT 16 058 وTRAVEL 9 887 وSTYLE & BEAUTY 9 649.
الاستعلام 3 — الملاءمة مع bool:
GET news/_search
{
"query": {
"bool": {
"must": [{ "match": { "headline": "steak" } }],
"filter": [{ "term": { "category": "TASTE" } }]
}
}
}
انسخ هذه الاستعلامات الثّلاثة كما هي في Kibana Dev Tools (http://localhost:5601) على فهرس news الخاصّ بالدّورة: البنية النّحويّة متطابقة، وتختلف الأرقام فقط. هذا هو أوضح برهان: Query DSL معيار فعليّ مشترك.
_xpack يختفي في جهة OpenSearch، ويُستبدل بـ_plugins/_security و_plugins/_sql و_plugins/_knn و_plugins/_ism. تُحفظ نقاط النّهاية القياسيّة _cat/* بلا تغيير.
OpenSearch Dashboards مقابل Kibana
الأرغونوميا قريبة لا متطابقة. نجد فيها Discover وVisualize وDashboards وDev Tools وStack Management. تصويرات Lens الّتي في Kibana ليست موجودة بعد؛ يقترح OpenSearch محرّر Visualize القديم إضافةً إلى VisBuilder. ملفّات الكائنات المحفوظة (ndjson) المُصدَّرة من Kibana غير مضمونة التّوافق مع OpenSearch Dashboards والعكس. في الواقع، نُعيد بناء لوحات المعلومات في الأداة المستهدفة.
إضافات الطّرف الأوّل في OpenSearch
كلّها تحت Apache 2.0، وكلّها مُضمَّنة في الصّورة:
security: مستخدمون وأدوار وABAC وTLS ومراجعةsql: SQL وPPL على الفهارسk-NN: بحث شعاعيّ مضبوط ومقارَبneural-search: تكامل مع embeddingsalerting: مراقبون ووجهات (Slack، بريد، webhook)anomaly-detection: كشف بلا إشرافindex-management(ISM): سياسات دورة الحياةnotificationsوml-commonsوobservabilityوflow-framework
معايير القرار لـVeille
خمسة أسئلة عمليّة يحسمها الفريق.
- هل الرّخصة تحجب استعمالًا مُخطَّطًا له؟ يستغلّ Veille سحابيًّا داخليًّا، ولا يُعيد توزيع المحرّك، ولا يبيع خدمة مُدارة «OpenSearch as a Service». basic المجّانيّة لـElastic تُغطّي الحاجة: SSPL لا تعوق شيئًا.
- هل ميزانيّة رخصة تجاريّة ممكنة؟ إن أراد Veille ELSER أو مصادقة OIDC لزبائنه أو تعلّم آلة مُدارًا، فسيلزم اشتراك Elastic Cloud أو Platinum. يُسلِّم OpenSearch المكافئ المجّانيّ في عدّة محاور.
- أيّ مُضيف؟ Elastic Cloud من جهة، AWS OpenSearch Service من جهة أخرى؛ والاثنان موجودان أيضًا عند Aiven وBonsai.
- أيّ منظومة ذكاء اصطناعيّ للبحث؟ ELSER و
semantic_textميزة صافية لـElastic في 2026؛ k-NN الأصليّ وNeural Search في جهة OpenSearch يبقيان صلبَين لكنّهما يتطلّبان مزيدًا من التّركيب. - أيّ عملاء؟ إن كتب Karim واجهته البرمجيّة في Python مقابل
elasticsearchv9، فالهجرة تعني الانتقال إلىopensearch-py(استيرادات، بعض الخيارات المُعاد تسميتها، بعض الاستجابات المختلفة في البيانات الوصفيّة).
البقاء على Elasticsearch 9 اليوم. مراقبة OpenSearch كلّ ستّة أشهر: إن تجاوز فارق كلفة السّحابة عتبةً، أو إن اشترط زبون رخصة Apache 2.0 صارمة، فالباب يبقى مفتوحًا.
هجرة فهرس
طريقتان، الأولى هي الصّائبة تقريبًا دائمًا.
الطّريقة 1 — إعادة الاستيراد من المصدر
هذه هي الطّريقة النّظيفة. يمتلك Veille أصلًا News_Category_Dataset_v2.json في data/؛ ومُستورِد الحقيبة سكربت Python من 200 سطر. توجيهه إلى http://localhost:9201 بدل http://localhost:9200 ، وإزالة المصادقة (أو استبدالها بمصادقة إضافة security) ، وإعادة التّشغيل. تُعاد كتابة الـmapping بالمثل في OpenSearch: لا شيء خاصّ بـElastic في مخطّطنا. لا خطر انحراف، اختبارات قابلة للتّكرار، والرّجوع تافه.
الطّريقة 2 — _reindex بـsource.remote
مفيدة حين يكون المصدر بعيدًا أو غير متاح. مدعومة رسميًّا بين Elasticsearch 7.10.2 وOpenSearch 1.x؛ فوق ذلك، كلّ تركيبة نسختَين يجب التّحقّق منها. يجب أوّلًا التّرخيص للمُضيف المصدر في opensearch.yml:
reindex.remote.whitelist: "elasticsearch:9200"
ثمّ، في OpenSearch Dev Tools:
POST _reindex
{
"source": {
"remote": {
"host": "http://elasticsearch:9200",
"username": "elastic",
"password": "veille2026"
},
"index": "news"
},
"dest": { "index": "news" }
}
يُطلق هذا _reindex عن بعد يستعلم الواجهة البرمجيّة لـElasticsearch ويدفع الوثائق بـ_bulk محلّيًّا. لمدوَّنة من 200 853 وثيقة، احسب دقائق عدّة.
_reindex لا يُهاجر الـmapping تلقائيًّا. أنشئ الفهرس المستهدف بالـmappings الصّحيح قبل الاستدعاء، وإلّا يُخمِّن OpenSearch mapping ديناميكيًّا قد يختلف عن الأصليّ (مثلًا date مُخمَّن كـtext إن كان أوّل تاريخ يُقرأ ملتبسًا).
الإيقاف السّليم
./lab.sh opensearch-down