بنية التخزين المؤقت والمراسلة

مشروع: دليل تشغيل منصة المراسلة

18 دقيقة الدرس 10 من 30

مشروع: دليل تشغيل منصة المراسلة

دليل التشغيل ليس وثيقة لذاتها — بل هو المعرفة القابلة للتنفيذ التي تمكّن أي مهندس في حالة الاستعداد، في الثالثة صباحاً، من إعادة المنصة إلى وضعها الطبيعي دون الحاجة إلى التصعيد. يجمع هذا الدرس كل ما تناولناه في هذا الدرس التعليمي في دليل تشغيل متكامل على مستوى الإنتاج لمنصة يخدم فيها Redis Cluster طبقة الجلسات والحد من المعدّل، بينما يخدم Apache Kafka طبقة بث الأحداث. تنطبق هذه الأنماط سواء كنت تعمل على معدات مادية أو على AWS MSK مع ElastiCache أو على Kubernetes operators المُدارة ذاتياً.

لقطة معمارية للمنصة

قبل أن تتمكن من تشغيل منصة، يجب أن يتشارك كل فرد في الفريق نموذجاً ذهنياً واحداً لتوپولوجيتها. يبدأ دليل التشغيل بمخطط معماري موثوق به، مُثبَّت في ويكي الفريق الداخلي ويُراجَع عند كل تغيير جوهري.

Messaging Platform HA Topology AZ-A Redis Primary Slot shard 0-5461 Kafka Broker 1 Leader: P0, P3 KRaft Controller 1 Voter (active) Redis Sentinel 1 Quorum monitor AZ-B Redis Replica Slot shard 0-5461 Kafka Broker 2 Leader: P1, P4 KRaft Controller 2 Voter (standby) Redis Sentinel 2 Quorum monitor AZ-C Redis Replica Slot shard 0-5461 Kafka Broker 3 Leader: P2, P5 KRaft Controller 3 Voter (standby) Redis Sentinel 3 Quorum monitor
توپولوجيا ثلاثة مناطق توافر: Redis بنظام Primary-Replica لكل جزء مع نصاب Sentinel، وبروكرات Kafka موزِّعة قادة الأقسام، ومتحكمات KRaft في مجموعة Raft مستقلة.

القسم الأول: قرارات تصميم التوافر العالي

عقد Redis للتوافر العالي: شغّل ثلاثة عقد Sentinel كحد أدنى (ليس اثنتين — فالانقسام بين نودتي Sentinel لا يمكن حلّه بنصاب). لمجموعة Redis Cluster، استخدم 3 أجزاء بنسخة واحدة لكل جزء، موزَّعة على 3 مناطق توافر، مع min-replicas-to-write 1 وmin-replicas-max-lag 10 على كل Primary. اضبط cluster-require-full-coverage no حتى يؤدي فقدان جزء إلى تدهور المجموعة لا إسقاطها كلياً. وقت التعافي عند استخدام Sentinel هو 30-60 ثانية افتراضياً؛ اضبط down-after-milliseconds 5000 وfailover-timeout 10000 للحصول على تعافٍ أقل من 30 ثانية في البيئات الحساسة للكمون، مع قبول أن القيم العدوانية تزيد من احتمال التعافيات الكاذبة عند اضطراب الشبكة.

عقد Kafka للتوافر العالي: استخدم معامل نسخ 3 (RF=3) لجميع المواضيع، مع min.insync.replicas=2. هذا يتحمل فقدان بروكر واحد دون فقدان بيانات أو خطأ في المنتج. لنصاب متحكمات KRaft، يكفي 3 متحكمات مخصصة للإنتاج — إذ تتطلب نصاباً من 2/3 لانتخاب متحكم نشط جديد، فالفقدان المتزامن لمتحكمَين يوقف عمليات البيانات الوصفية. احرص على وضع المتحكمات على مضيفين منفصلين عن البروكرات.

القسم الثاني: مكدس المراقبة والإشارات الذهبية

طبقة المراقبة لهذه المنصة مبنية على Prometheus مع Grafana، وتُغذَّى بمقاييس redis_exporter من oliver006 ومصدر JMX (أو منتج Prometheus الأصلي لـ Kafka). قواعد التنبيه التالية غير قابلة للتفاوض للإنتاج:

# prometheus/alerts/messaging-platform.yml groups: - name: redis rules: - alert: RedisReplicationLagHigh expr: redis_connected_slaves{job="redis"} == 0 for: 1m labels: severity: critical annotations: summary: "Redis primary {{ $labels.instance }} has no connected replicas" - alert: RedisMemoryUsageHigh expr: redis_memory_used_bytes / redis_memory_max_bytes > 0.85 for: 5m labels: severity: warning annotations: summary: "Redis {{ $labels.instance }} memory usage high" - alert: RedisKeyEvictions expr: increase(redis_evicted_keys_total[5m]) > 0 for: 0m labels: severity: warning annotations: summary: "Redis evicting keys — check memory policy" - name: kafka rules: - alert: KafkaUnderReplicatedPartitions expr: kafka_server_replicamanager_underreplicatedpartitions > 0 for: 2m labels: severity: critical annotations: summary: "Kafka broker {{ $labels.instance }} has {{ $value }} under-replicated partitions" - alert: KafkaConsumerGroupLagHigh expr: kafka_consumergroup_lag > 50000 for: 5m labels: severity: warning annotations: summary: "Consumer group {{ $labels.consumergroup }} lag {{ $value }}" - alert: KafkaBrokerOffline expr: kafka_brokers < 3 for: 1m labels: severity: critical annotations: summary: "Kafka cluster has fewer than 3 brokers"
أكثر مقياسَين قابلَين للتنفيذ في Redis على الإطلاق هما used_memory مقابل maxmemory وconnected_slaves. إذا كان لدى Primary صفر نسخ وتعرّض للانهيار، فستفقد البيانات بصرف النظر عن إعدادات الثبات. حالة النسخ هي أول ما تفحصه في أي حادثة Redis.

القسم الثالث: دليل الاستجابة للحوادث

خطوات دليل التشغيل التالية مرتبة حسب السرعة. كل قسم يرتبط بقاعدة تنبيه في PagerDuty. يجب أن يتمكن مهندس الاستعداد من نسخ هذه الأوامر ولصقها مباشرة.

فشل Redis Primary (إدارة Sentinel)

  1. تأكيد التنبيه: redis-cli -h sentinel1 -p 26379 SENTINEL masters — تحقق من حقل flags؛ القيمة s_down أو o_down تؤكد شك Sentinel.
  2. فحص النصاب: redis-cli -h sentinel1 -p 26379 SENTINEL ckquorum mymaster — يجب أن تُرجع OK.
  3. إذا كان Sentinel سليماً ولم يبدأ التعافي بعد، شغّله يدوياً: redis-cli -h sentinel1 -p 26379 SENTINEL failover mymaster.
  4. تأكيد الـ Primary الجديد: redis-cli -h sentinel1 -p 26379 SENTINEL get-master-addr-by-name mymaster.
  5. التحقق من إعادة اتصال التطبيق — معظم مكتبات عملاء Redis (ioredis وjedis وlettuce) تتعامل مع تعافي Sentinel تلقائياً خلال 1-3 ثوانٍ بعد نشر Sentinel لعنوان الـ Master الجديد.
  6. تقديم تذكرة ما بعد الحادثة: السبب الجذري (OOM أو OOM-killer للنواة أو عطل معدّي)، حالة إعادة ربط النسخ، نافذة فقدان البيانات (قارن master_repl_offset من INFO replication قبل وبعد).

فقدان Kafka Broker وإعادة انتخاب الأقسام

# 1. تحديد البروكر المعطّل kafka-broker-api-versions.sh --bootstrap-server broker1:9092 # 2. فحص الأقسام ناقصة النسخ — تتقارب نحو 0 بمجرد اللحاق بالتكرار kafka-topics.sh --bootstrap-server broker1:9092 \ --describe --under-replicated-partitions # 3. إذا فُقد البروكر نهائياً، شغّل انتخاب النسخة المفضّلة kafka-leader-election.sh --bootstrap-server broker1:9092 \ --election-type PREFERRED \ --all-topic-partitions # 4. التحقق من تعافي تأخر مجموعة المستهلكين kafka-consumer-groups.sh --bootstrap-server broker1:9092 \ --describe --group payments-consumer-group # 5. إذا كان التأخر يتزايد بعد إعادة التوازن، زد المستهلكين: # kubectl -n kafka scale deployment payments-consumer --replicas=6

ارتفاع تأخر مجموعة المستهلكين (غير ناجم عن فقدان بروكر)

  1. عزل السبب الجذري: بطء معالجة المستهلك، أو ارتفاع مفاجئ في إنتاجية المنتج، أو رسالة مسمومة تسبب أخطاء تسلسل متكررة.
  2. تحقق من سجلات المستهلك بحثاً عن DeserializationException أو إعادات توازن متكررة. إعادات التوازن المتكررة تعني تجاوز المستهلكين لـ max.poll.interval.ms (5 دقائق افتراضياً) — زده أو قلل حجم الدفعة.
  3. للرسالة المسمومة: حدد الإزاحة بـ kafka-get-offsets.sh، ثم استخدم مستهلكاً مؤقتاً مع auto.offset.reset=none وأمر seek للتخطي. لا تحذف الرسالة أبداً — وجّهها إلى موضوع الرسائل الميتة.
  4. زد المستهلكين أفقياً حتى عدد الأقسام. ما وراء ذلك العدد، يظل كل مستهلك إضافي خاملاً ويهدر الموارد.
لا تقلّص عدد أقسام الموضوع أبداً. لا يدعم Kafka إعادة التقسيم نزولاً — يجب إنشاء موضوع جديد ونقل المستهلكين وتفريغ القديم. خطط لأعداد الأقسام عند الإنشاء بناءً على الإنتاجية المستهدفة: قسم واحد يعالج تقريباً 10-50 ميجابايت في الثانية حسب حجم الرسالة وضغط الكودك.

القسم الرابع: شجرة قرار السعة والتوسع

يتضمن دليل التشغيل شجرة قرار للتوسع يتبعها مهندسو الاستعداد قبل تشغيل بنية تحتية جديدة. يمنع ذلك نقص التوفير (تدهور المنصة) والتوفير الزائد (هدر الميزانية).

مشغّلات توسع Redis:

  • الذاكرة فوق 75% لمدة 30 دقيقة: افحص أولاً TTL للمفاتيح وسياسة الإخلاء. إذا كان النمو مشروعاً، أضف جزءاً: redis-cli --cluster add-node new_host:6379 existing_host:6379 ثم --cluster rebalance.
  • CPU فوق 70% على الـ Primary: Redis أحادي الخيط لمستوى البيانات. وسّع أفقياً (أجزاء أكثر) لا عمودياً. حدد المفاتيح الساخنة أولاً بـ redis-cli --hotkeys أو redis-cli OBJECT FREQ key (يتطلب maxmemory-policy allkeys-lfu).
  • كمون القراءة فوق 5 ms p99: وجّه القراءات إلى النسخ. تأكد من أن العميل مهيأ بـ READONLY على اتصالات النسخ.

مشغّلات توسع Kafka:

  • قرص البروكر فوق 70%: قلل log.retention.hours أو زد عدد البروكرات. أعد توزيع الأقسام بـ kafka-reassign-partitions.sh لنشر البيانات.
  • إنتاجية الشبكة فوق 80% من سعة الشبكة: أضف بروكرات وأعد توازن قادة الأقسام. في AWS MSK، غيّر نوع النسخة للبروكر.
  • كمون المنتج فوق 50 ms: افحص request.required.acks. إذا كانت acks=all، افحص حجم ISR — إذا تقلص إلى 1، فنسخة بطيئة واحدة تحجب كل acks. حدد النسخة المتأخرة بـ kafka-topics.sh --under-min-isr-partitions.
احتفظ بـ وثيقة خط أساس للسعة مُحدَّثة شهرياً. سجّل ذروة الإنتاجية (MB/s) وكمون p99 واستخدام الذاكرة وتأخر المستهلكين لكل مكوّن. بدون خط أساس، لا تستطيع تمييز الشذوذ الحقيقي عن نمو حركة المرور الطبيعي أثناء الحادثة — وهذا الغموض يكلفك دقائق ثمينة من متوسط وقت الحل.

القسم الخامس: صيانة دليل التشغيل وجدول التدريبات

دليل التشغيل الذي لا يُختبر أبداً هو التزام لا أصل، لا عائد منه. ادمج ما يلي في التقويم الهندسي لفريقك:

  • تدريب فوضى شهري: أوقف نسخة Redis واحدة في بيئة التجهيز، تحقق من ترقية Sentinel بشكل صحيح، وتحقق من RTO للتطبيق. أوقف بروكر Kafka واحد وتحقق من تقارب التأخر ضمن SLO. استخدم مبادئ هندسة الفوضى من الدرس التعليمي السابق في هذه الدورة — وثّق فرضية الحالة المستقرة قبل كل تدريب.
  • اختبار تعافٍ ربع سنوي: نفّذ تعافياً كاملاً لـ Redis Primary في الإنتاج خلال نافذة حركة مرور منخفضة. هذا يكشف الانجراف في التهيئة (قواعد الجدار الناري وإصدارات مكتبة العميل وإعدادات TTL لـ DNS) التي لا تظهر إلا في ظروف حقيقية.
  • مراجعة دليل التشغيل بعد كل حادثة: بعد كل تحليل ما بعد الحادثة، حدّث قسم دليل التشغيل المتأثر خلال 48 ساعة. مهندس الاستعداد الذي أدار الحادثة يملك هذه المهمة — إذ هو الخبير الموضوعي حتى الدورة التالية.
  • تدقيق إجهاد التنبيهات: ربع سنوياً، راجع تكرار إطلاق كل تنبيه. أي تنبيه يطلق أكثر من مرتين أسبوعياً دون حادثة P1 إما خاطئ المعايرة أو يشير إلى مشكلة منهجية يجب إصلاحها لا إسكاتها.

مقياس نضج تشغيل منصة المراسلة ليس ألا تحدث حوادث — بل أن كل حادثة تكون أقصر وأفضل احتواءً وأفضل توثيقاً من السابقة. هذا الدليل هو العقد التشغيلي بين منصتك وكل مهندس يعتمد عليها.