توسيع نطاق Prometheus
توسيع نطاق Prometheus
يستطيع خادم Prometheus الواحد استطلاع عشرات الآلاف من الأهداف ومعالجة ملايين السلاسل الزمنية النشطة — حتى حدود معينة. في المؤسسات الكبيرة، يصطدم Prometheus الأحادي بثلاثة جدران في آنٍ واحد: الذاكرة (تُخزَّن جميع السلاسل النشطة في الـ RAM)، والقرص (قاعدة بيانات TSDB المحلية غير مصممة للاستبقاء متعدد السنوات)، ونطاق التأثير (عطل خادم واحد يُعمي كل التنبيهات). تتناول هذه الدرس الأنماط الإنتاجية المستخدمة لتجاوز تلك الحدود: الـ Federation، والكتابة عن بُعد (Remote Write)، وأنظمة التخزين طويل الأمد مثل Thanos وGrafana Mimir.
مشكلة التوسع بالأرقام
تستهلك كل سلسلة زمنية نشطة نحو 2–3 كيلوبايت من الذاكرة في Prometheus 2.x. عند 10 ملايين سلسلة نشطة — وهو أمر شائع في أسطول Kubernetes كبير — يعني ذلك 20–30 غيغابايت من الـ heap قبل احتساب WAL وتعقيد الاستعلامات وعبء التسميات. تتكبّد قاعدة بيانات TSDB المحلية عبر الضغط إدارةً معقولة للقرص طوال 15 يومًا من الاستبقاء، إلا أن متطلبات الامتثال كثيرًا ما تشترط 13 شهرًا. هذان القيدان وحدهما يفرضان بنية موزعة.
الـ Federation
تتيح Federation في Prometheus لخادم عالمي استطلاع مقاييس مجمَّعة مسبقًا من عدة خوادم Prometheus محلية عبر نقطة نهاية HTTP الخاصة بها /federate. يستطلع كل خادم محلي شريحته الخاصة من الأهداف، بينما يسحب الخادم العالمي نتائج قواعد التسجيل ومقاييس التنبيهات الحرجة فحسب — لا السلاسل الخام.
تُعدّ الـ Federation الخيار الصحيح حين تريد لوحة مراقبة موحدة لتنبيهات متعددة مراكز البيانات دون تكرار البيانات الخام. اضبط honor_labels: true كي يحتفظ Prometheus العالمي بتسميات job وinstance من الخادم المصدر بدلًا من استبدالها باسم وظيفة الـ federation.
الكتابة عن بُعد (Remote Write)
تُرسل Remote Write كل عينة من Prometheus المحلي إلى خلفية تخزين خارجية عبر اتصال HTTP/2 دائم باستخدام حمولة protobuf مضغوطة بـ snappy. تجعلها قائمة WAL متينة: تُخزَّن العينات على القرص إن كان الخادم البعيد غير متاح وتُعاد إرسالها عند عودة الاتصال (بحد أقصى يساوي مدة استبقاء WAL المحددة بـ --storage.tsdb.retention.time).
prometheus_remote_storage_shards دائمًا عند max_shards، ارفع الحد الأقصى أو قلّل حجم البيانات باستخدام write_relabel_configs.
Thanos — تحليل عميق للبنية
Thanos هو الحل مفتوح المصدر الأكثر انتشارًا للتخزين طويل الأمد المتاح عالميًا لبيانات Prometheus. يتكون من مكونات صغيرة مستقلة التوزيع بدلًا من ملف ثنائي واحد:
- Sidecar — يعمل جنبًا إلى جنب مع كل pod Prometheus؛ يرفع كتل TSDB المكتملة (كل ساعتين) إلى التخزين الكائني (S3، GCS، Azure Blob) ويكشف Store API عبر gRPC لتمكين Thanos Query من الوصول إلى البيانات المحلية الحديثة.
- Query — محرك استعلام متوافق مع Prometheus يوزع الاستعلامات على جميع نقاط Store API المسجلة (Sidecars، Store Gateways، Rulers) ويزيل التكرار من النسخ المتداخلة.
- Store Gateway — يخدم الاستعلامات على الكتل الموجودة في التخزين الكائني؛ يدعم تخزين الفهرس مؤقتًا (Memcached/Redis) لتجنب إعادة قراءة البيانات الوصفية في كل طلب.
- Compactor — يعمل كنسخة واحدة؛ يدمج الكتل ويُنزّل دقتها في التخزين الكائني (دقتا 5 دقائق وساعة واحدة) لإبقاء الاستعلامات على نطاق زمني واسع سريعةً.
- Ruler — يُقيّم قواعد التسجيل والتنبيه عالميًا عبر جميع الشرائح، مما يُلغي الحاجة إلى federation لكل شريحة.
- Receive — يقبل remote_write من Prometheus (بنية Thanos بدون Sidecars) ويكتب مباشرةً إلى التخزين الكائني؛ يُستخدم في الطوبولوجيا القائمة على الدفع.
Grafana Mimir — حين لا يكفي Thanos
يعتمد Thanos Sidecar على استمرار عمل Prometheus لخدمة البيانات الحديثة. أما Grafana Mimir (مفتوح المصدر، ترخيص Apache 2.0) فهو قاعدة بيانات TSDB مفككة بالكامل وقابلة للتوسع الأفقي مبنية على Cortex، تقبل remote_write وتشغّل كل مكون — Ingester وQuerier وCompactor وStore Gateway وRuler — كخدمات مصغّرة مستقلة التوسع خلف مسار كتابة واستعلام واحد. وهي الخيار الأنسب حين تحتاج إلى استيعاب ملايين السلاسل في الثانية أو إلى عزل متعدد المستأجرين (بيانات كل مستأجر في مساحة أسماء منفصلة).
الاختيار بين Thanos وMimir
- Thanos Sidecar — الأنسب حين لديك Prometheus بالفعل وتحتاج استبقاءً في التخزين الكائني بأدنى تغيير تشغيلي. ممتاز حتى نحو 50 مليون سلسلة نشطة عبر جميع الشرائح.
- Thanos Receive — حين تريد دفع البيانات (بدون Sidecar) وتقبل تعقيد النسخ المتماثلة.
- Mimir — للبيئات الجديدة على نطاق واسع؛ إنتاجية كتابة أفضل، ودعم أصيل لتعدد المستأجرين، وتوسع أفقي أكثر مرونة. تُشغّل Google وMeta مشتقات من Cortex/Mimir بمئات المليارات من السلاسل النشطة.
thanos.shipper.meta.json) وتأكد من أن نشرك لا يولّد وظائف ضغط متداخلة.
التعقيد التصنيفي: جذر مشاكل التوسع
قبل إضافة المزيد من البنية التحتية لمعالجة مشكلة Prometheus، دائمًا افحص التعقيد التصنيفي أولًا. تسمية واحدة عالية التعقيد (مثل request_id أو user_id) يمكنها إنشاء ملايين السلاسل لن يُرخّصها أي قدر من federation أو sharding. استخدم واجهة برمجة TSDB للعثور على المقاييس المسببة للمشكلة:
metric_relabel_configs في وظائف الاستطلاع داخل Prometheus لحذف السلاسل عالية التعقيد قبل استيعابها. الحذف في طبقة remote_write يُهدر الذاكرة ومساحة WAL على الخادم المحلي. الحذف في خلفية التخزين يُهدر الشبكة. احذف في أبكر مرحلة ممكنة.
قائمة التحقق الإنتاجية لتوسيع Prometheus
- اضبط
--storage.tsdb.retention.time=15dعلى Prometheus المحلي واعتمد على التخزين الكائني لما يزيد على ذلك. - فعّل ضغط WAL:
--storage.tsdb.wal-compression(يوفر نحو 30% من مساحة WAL). - حجّم ذاكرة Prometheus بنحو 3 بايت × عدد السلاسل النشطة × 2 (هامش للذروات).
- توزّع فترات الاستطلاع عبر الشرائح لتجنب ارتفاعات الحمل المتزامن على المُصدِّرات.
- راقب المُراقِبين: اكشف مقاييس Thanos Sidecar وStore Gateway لنسخة Prometheus خفيفة مستقلة مخصصة لمنظومة الرصد لديك.
- اختبر اتصال التخزين الكائني بانتظام — خطأ صامت في صلاحيات S3 قد يملأ القرص من WAL قبل أن يُنبَّه أحد.