Lambda Architecture

لو عندنا سيستم عليه عدد عملاء كبير، وفيه كمية داتا ضخمة جدًا (Big Data)، زي سيستم محفظة إلكترونية مثلًا، وعاوزين نطلع لكل عميل لما يفتخ التطبيق:

رصيده الحالي وآخر العمليات اللي قام بيها

مجموعة تقارير وإحصائيات يقدر يستعرضها بسهولة زي مثلًا:

- جراف يوضح معدلات الإنفاق الشهر الحالي مقارنة بآخر شهر\ربع سنة\نصف سنة\سنة سابقة.

- جراف يوضح الإنفاق على المنصات المشهورة (أمازون، نون، أوبر، ترينديول، نينجا، كيتا، جوجل بلاي… إلخ) بنسبة الانفاق في كل منصة.

- تصنيف الإنفاق: تعليم، ترفيه (Games, Films, etc)، سلع أساسية، فواتير… إلخ.

وكل ده يكون جاهز في نفس اللحظة اللي يفتح فيها الموبايل أبليكيشن

لو دققنا شوية، هنلاحظ إن:

التقارير والجرافس مش لازم تكون محدثة لحد نفس الثانية، ومقبول جدًا إن آخر تحديث ليها يكون من فترة لا تزيد عن 24 ساعة.

لكن رصيد العميل وآخر العمليات لازم يكونوا محدثين لحظيًا، وأي تأخير فيهم غير مقبول.

التفكير البديهي في الحل: بناءً على الفرق ده، الحل المنطقي هيكون:

1️⃣ Job تشتغل على الداتا التاريخية وتطلع:

تقارير، إحصائيات،Aggregates في شكل Views جاهزة، بدل ما نعمل حسابات تقيلة وقت الطلب.

2️⃣ Real-time Processing

نظام يلقط أي عملية بتحصل لحظة بلحظة، ويحدّث:

الرصيد اللحظي، آخر العمليات باستخدام Event Streaming + Storage سريع جدًا (Low-latency Store).

3️⃣ Service بسيطة مسؤولة إنها:

تجمع النتائج الجاهزة من الجانبين، تعمل دمج بسيط جدًا وترجع الداتا للتطبيق بسرعة.

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

وأقرب تشبيه للثلاثة دول هو رمز λ.

وده بالظبط اللي بتقدمه Lambda Architecture اللي صاغه Nathan Marz وده يعتبر واحد من أول الناس اللي دخلت في مشاكل Big Data لما كان في تويتر، وبدأ يفكر في معماريات تعالج المشاكل ده، وهو أحد مؤلفي كتاب "Big Data: Principles and best practices of scalable realtime data systems"، جمع فيه كل فلسفاته لبناء أنظمة بيانات ضخمة بتستحمل الضغط (Scalable) ومقاومة للأعطال (Fault-tolerant).

ولما نقول Lambda Architecture على طول نفتكر الرمز λ وإنه بيشير إن هناك 3 Layers، اتنين بيشتغلوا وواحدة بتستلم منهم:

1️⃣ Batch Layer🕵️

(المهندس الخبرة اللي بيشتغل على مهله، بس شغل معلمين 󠅓💯)

الـ Batch Layer بتشتغل دوريًا (مثلًا كل يوم الساعة 3 الفجر)، وبتعمل الآتي:

تعالج الداتا التاريخية من آخر Snapshot أو Partition (مش شرط من أول التاريخ كل مرة).

تحسب: الإجماليات، الفوايد، الضرائب، المصاريف الإدارية، بدقة عالية جدًا وتعمل ما يسمى بالـ (Reconciliation).

تطلع نتيجة اسمها Closing Balance:

“رصيدك لحد الفجر هو 10,000 جني”.

تجهز كل الإحصائيات المطلوبة للتقارير والجرافس وتخزن النتائج في جداول جاهزة وسريعة اسمها Batch Views

(بحيث ما يكونش فيه أي Aggregations وقت القراءة).

2️⃣ Speed Layer🚀

(الرادار الصاحي)

دلوقتي الساعة 2 الظهر، والعميل كان:

اشترى قهوة بـ 50 جني، سحب 1000 جني من ATM، ركب أوبر 4 مرات بـ 400 جني، دفع فواتير بـ 550 جني

اللي بيحصل:

الـ Batch Layer نايمة ومش هتشوف العمليات دي غير بليل.

الـ Speed Layer شغالة، لقطت الأحداث في نفس ثانية حدوثها عن طريق: Event Stream (Kafka / Event Hub / …) ، وحدثت Views سريعة جدًا مخزنة في: Redis / Cassandra / DynamoDB / …

وقالت: “في عمليات جديدة النهارده بقيمة 2000 جني”.

الداتا دي بتتخزن في Real-time Views.

3️⃣ Serving Layer✨

(المايسترو لحظة فتح الأبليكيشن)

دي الطبقة اللي بتكلم الموبايل أبليكيشن. لما تفتح التطبيق الساعة 2 الظهر، الـ Serving Layer بتعمل دمج ذكي (Smart Merge):

  1. للتقارير: تجيب الـ Batch Views الجاهزة (الجرافس والإحصائيات) وتعرضها فوراً.
  2. للرصيد: تجيب الـ Batch View (رصيد الأمس) وتدمجه مع الـ Real-time View (عمليات اليوم) وتظهر لك: "رصيدك الآن 8,000 جني".
    ـــــــــــــــــــــــــــــــــ

المصدر النهائي للحقيقة (Immutable Data)🔏💯

​السيستم ده بيعتمد على إن الـ Raw Data لا تُعدل. كل قرش دخل أو خرج هو عبارة عن "حدث" (Event) مسجل بـ Metadata دقيقة (الوقت، التاجر، نوع الإنفاق). الداتا دي بتفضل ثابتة وهي المرجع لينا لو احتجنا نعيد حساب أي حاجة من سنين فاتوا.
ـــــــــــــــــــــــــــــــ

*ملاحظة: المثال ده تبسيطي لشرح الفكرة، وفي أنظمة حقيقية ممكن الرصيد يتحسب Incrementally بطرق مختلفة، لكن المبدأ واحد.
ـــــــــــــــــــــــــــــ

ليه بنستخدم Lambda Architecture بالذات؟

​🚀 السرعة القصوى: التقارير المعقدة بيتم معالجتها مسبقاً (Pre-computed) داخل الـ Batch Layer، فبتكون النتائج 'جاهزة للعرض' فوراً. ده بيخلي وقت الاستجابة (Latency) يقترب من الصفر لأننا تخلصنا من عبء الحسابات (Computation Overhead) وقت طلب العميل.

🎯 الدقة المطلقة (Fault Tolerance): لو الـ Speed Layer حصل فيها أي خطأ، الـ Batch Layer هتعيد حساب كل شيء بدقة بناءً على الـ Raw Data (المصدر النهائي للحقيقة).

📈 توفير الموارد: بدل ما السيستم يستهلك بروسيسور عالي عشان يحسب تقاريرك كل ما تفتح التطبيق، بنحسبها مرة واحدة ونخزنها كـ View جاهز.
ــــــــــــــــــــــــــــــ

كلمة أخيرة.. هل ليها بدائل؟

​رغم قوة الـ Lambda، إلا إن عيبها هو تكرار الكود. عشان كده ظهرت Kappa Architecture (الرمز اليوناني كابا K أو ϰ) وكأنه بيرمز إلى إن حاجتين اندمجوا مع بعض وبقوا حاجة واحدة.

 واللي سماه Kappa هو (Jay Kreps) - وهو اللي اخترع Apache Kafka ومؤسس شركة Confluent، واختاره كبديل يعتمد على الـ Streaming فقط ويكون فئة واحدة من الـviews، بدل اتنين، وبيحدثها وقتي مع كل Event.

 لكن Lambda بتفضل هي الخيار المفضل في الأنظمة التي تتطلب تقارير إحصائية تاريخية ضخمة بسبب سهولة التعامل مع أكوام البيانات المتراكمة من سنوات (Batch) وانخفاض تكلفة تخزينها ومراجعتها مقارنة بإعادة تشغيل الـ Streams في Kappa.

الخلاصة:

Lambda Architecture بتوازن بين ذكاء التقارير التاريخية وسرعة العمليات اللحظية. وده اللي بيخلي تطبيق المحفظة في إيدك سريع، دقيق، ومليان إحصائيات مفيدة في نفس الوقت، وفعليا التيم بيقدر ينام مرتاح إن لو في أي خطأ حصل من الSpeed فالـBatch هيصلح كل حاجة توماتيكي، وعشان كده أنا شخصيا أفضل معمارية الLambda.

Comments