مقال

شرح Apache Kafka: الموضوعات والأقسام ومجموعات المستهلكين وأول تدفق أحداث

شرح Apache Kafka: الموضوعات والأقسام ومجموعات المستهلكين وأول تدفق أحداث

اتبع حدث طلب من المنتج إلى عدة مستهلكين، ثم جرّب Kafka محلياً وافهم كيف تعمل الأقسام والترتيب وإعادة القراءة.

10 دقيقة قراءةاللغة: AR العربيةمجاني0 تصفيقات0 تعليقات
خيارات القراءة

يمكن استخدام Kafka لنقل عمل إلى الخلفية، لكن النموذج الذهني الأكثر فائدة هو سجل أحداث موزّع تُضاف إليه البيانات بالتتابع. تسجل خدمة الطلبات وقوع عملية شراء، وتقرأها خدمات المخزون والتحليلات والإشعارات بصورة مستقلة. لا تحتاج خدمة الطلبات إلى استدعاء كل خدمة أثناء انتظار العميل.

لكن هذه المرونة تتطلب قرارات واضحة: أي الأحداث تنتمي إلى الموضوع نفسه؟ ما المفتاح الذي يحدد ترتيبها؟ إلى متى تُحتفظ بها؟ وماذا يحدث حين يتوقف مستهلك؟ سنمر على حدث واحد وننفذ تجربة محلية.

المفاهيم الأساسية

المنتِج يكتب سجلاً إلى موضوع topic. ينقسم الموضوع إلى أقسام partitions، وكل قسم سجل مرتب. يحفظ الوسيط broker الأقسام ويخدم طلبات العملاء. يقرأ المستهلك السجلات، وتتقاسم المستهلكات في مجموعة واحدة الأقسام بينها.

يحمل السجل قيمة ومفتاحاً اختيارياً ورؤوساً ووقتاً. يحصل على offset داخل قسمه. يحدد الثلاثي (topic, partition, offset) موضع السجل. الرقم 42 في القسم الأول لا يعني أنه وقع قبل الرقم 41 في القسم الثاني؛ لا يضمن Kafka ترتيباً عاماً بين الأقسام.

في موضوع orders.placed.v1 ذي أربعة أقسام، اجعل orderId مفتاح السجل عندما تحتاج إلى ترتيب أحداث الطلب نفسه. تذهب سجلات المفتاح ذاته إلى القسم ذاته ضمن سياسة توزيع مستقرة، ويُحافظ على ترتيبها داخل ذلك القسم. إذا غيّرت عدد الأقسام مستقبلاً، فقد تتغير وجهة سجلات المفتاح الجديدة؛ خطط لذلك قبل الاعتماد على ترتيب طويل العمر.

عقد حدث واضح

{
  "eventId": "evt_01JQ8X8F",
  "eventType": "OrderPlaced",
  "schemaVersion": 1,
  "occurredAt": "2026-09-29T10:30:00Z",
  "orderId": "ord_782",
  "customerId": "cus_17",
  "totalMinor": 12900,
  "currency": "USD"
}

يعرف eventId هذا الوقوع كي يستطيع المستهلك اكتشاف التكرار. يمثل totalMinor المبلغ بأصغر وحدة للعملة لتجنّب غموض الكسور العشرية. أرسل فقط البيانات التي يحتاجها المستهلكون، لأن الحدث قد يُحتفظ به ويُعاد تشغيله. OrderPlaced حقيقة حدثت بالفعل، وليس أمراً مثل ReserveInventory؛ للأمر مالك وسلوك فشل مختلف.

من الكتابة إلى القراءة

يتصل المنتج بالعنقود، يحصل على معلومات الموضوع، يختار قسماً، ويرسل السجل إلى الوسيط القائد. يمكن لنسخ متماثلة حفظه على وسطاء آخرين. تحدد إعدادات الإقرار متى يعتبر المنتج الإرسال ناجحاً. تجلب المستهلكات السجلات من الأقسام المخصصة لها.

تسجل مجموعة المستهلكين تقدمها عبر offsets ملتزم بها. تأكيد offset لا يحذف الحدث من الموضوع. تستطيع مجموعة التحليلات قراءته حتى لو انتهت مجموعة المخزون منه، ويمكن لمجموعة أن تعيد موضعها وتقرأ أحداثاً لا تزال ضمن فترة الاحتفاظ. مدة الاحتفاظ مستقلة عن قراءات المستهلكين.

إذا شغلت ثلاث نسخ من مستهلك المخزون لأربعة أقسام، تُوزع الأقسام بينها. نسخة خامسة في المجموعة نفسها لن تحصل على قسم نشط من هذا الموضوع وحده. أما sales-analytics فهي مجموعة أخرى لها تقدم مستقل. عند انضمام نسخة أو توقفها، قد تُعاد موازنة التوزيع، لذلك لا تفترض أن عملية واحدة تملك القسم إلى الأبد.

تجربة محلية باستخدام CLI

يوفر الدليل الرسمي السريع صورة Docker رسمية. للتجربة على جهازك:

docker run -d --name kafka-demo -p 9092:9092 apache/kafka:4.3.1

نفذ الأوامر التالية في بيئة تملك ملفات Kafka التنفيذية داخل bin/ وتستطيع الوصول إلى الوسيط على localhost:9092:

bin/kafka-topics.sh --create --topic quickstart-events \
  --bootstrap-server localhost:9092
bin/kafka-topics.sh --describe --topic quickstart-events \
  --bootstrap-server localhost:9092
bin/kafka-console-producer.sh --topic quickstart-events \
  --bootstrap-server localhost:9092

اكتب بضعة أسطر في المنتج، ثم افتح طرفية أخرى:

bin/kafka-console-consumer.sh --topic quickstart-events \
  --from-beginning --bootstrap-server localhost:9092

إن كانت أدوات CLI داخل الحاوية فاستخدم الملفات التنفيذية والعنوان المحلي المناسب من داخلها. هذا وسيط واحد للتعلم، وليس إعداد إنتاج متحمل للأعطال. جرّب بعد ذلك مستهلكين بالمجموعة نفسها، ثم مجموعة ثانية. أنشئ موضوعاً متعدد الأقسام لرؤية التوازي؛ قسم واحد يعني مستهلكاً نشطاً واحداً فقط لكل مجموعة لهذا الموضوع.

اختيار المفتاح وعدد الأقسام

المفتاح قرار متعلق بالعمل. orderId يحفظ ترتيب أحداث الطلب ويُوزع الطلبات غالباً؛ customerId يحفظ ترتيب العميل لكنه قد يجعل عميلاً كبيراً نقطة ضغط. مفتاح ثابت يرسل كل السجلات إلى قسم ساخن، ومفتاح عشوائي يفقد ترتيب الأحداث المرتبطة. اكتب أولاً: ما الكيان الذي يجب أن تبقى أحداثه مرتبة؟

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

الاحتفاظ وإعادة القراءة

لا تُحذف السجلات بعد قراءتها. تحدد إعدادات الزمن أو الحجم مدة بقائها. إذا توقف مستهلك مدة أطول من فترة الاحتفاظ فقد لا يجد offset القديم. راقب هذا الخطر قبل وقوعه.

ضغط السجل log compaction يحتفظ مع الوقت بقيمة حديثة لكل مفتاح، وهو مناسب لسجل حالة مثل تفضيلات عميل، وليس تاريخاً كاملاً غير قابل للمحو. السجل ذو مفتاح وقيمة null يمثل حذفاً في هذا النمط. ميّز بين موضوع لتاريخ الأحداث وموضوع لتغيرات الحالة.

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

مشروع صغير يثبت الفهم

أنشئ orders.placed.v1 في بيئة تجريبية، وأرسل أحداثاً بمفتاح orderId، ثم شغّل مجموعتي مخزون وتحليلات. أوقف مستهلكاً وأعد تشغيله. دوّن في README: لماذا اخترت المفتاح؟ من أين تستأنف كل مجموعة؟ متى تصبح فترة الاحتفاظ مشكلة؟ وماذا يفعل الحدث المكرر بكل أثر جانبي؟

مراجع رسمية

مقالات مختارة

Kafka في الإنتاج: استراتيجية الأقسام وتأخر المستهلكين والاعتمادية وخطة الحوادث
تحريريAR
11 دمجاني

Kafka في الإنتاج: استراتيجية الأقسام وتأخر المستهلكين والاعتمادية وخطة الحوادث

نجاح تجربة إرسال واستقبال حدث لا يكفي للإنتاج. صمّم الأقسام والسعة والاحتفاظ والمراقبة وخطة تعافٍ قابلة للتنفيذ.

مقالات هندسيةأدلة المنصة
0 تصفيقات
قراءة
Laravel وKafka بلا أحداث مفقودة: Outbox والمعالجة الآمنة عند التكرار مع PostgreSQL
تحريريAR
11 دمجاني

Laravel وKafka بلا أحداث مفقودة: Outbox والمعالجة الآمنة عند التكرار مع PostgreSQL

حفظ الطلب في قاعدة البيانات ونشر الحدث إلى Kafka عمليتان منفصلتان. تعلّم كيف يحمي Outbox من فقد الحدث وكيف يمنع المستهلك آثار التكرار.

مقالات هندسيةأدلة المنصة
0 تصفيقات
قراءة
كيف تصمّم واجهات API يثق بها العملاء: دليل عملي يبدأ بالعقد
تحريريAR
10 دمجاني

كيف تصمّم واجهات API يثق بها العملاء: دليل عملي يبدأ بالعقد

واجهة API الجيدة تجعل الخطوة التالية متوقعة. صمّم عملية تسجيل في دورة انطلاقاً من حاجة العميل، مع إعادة محاولة آمنة وأخطاء مفيدة وخطة للتغيير.

مقالات هندسيةأدلة المنصة
0 تصفيقات
قراءة

التعليقات

0 تعليقات

لا توجد تعليقات معتمدة بعد. قد تنتظر الردود الجديدة المراجعة.