Database Engineering

إتقان Event Sourcing وCQRS في CockroachDB: دليل إلى الاتساق الموزع

في العصر الحديث لتطبيقات السحابة الأصلية، لم يعد بناء أنظمة تتمتع بتوافر عالٍ واتساق صارم رفاهية، بل أصبح مطلباً أساسياً. مع ابتعاد المطورين عن البنى المعمارية الأحادية، اكتسبت أنماط مثل فصل مسؤولية الأوامر والاستعلامات (CQRS) ومصدر الأحداث (ES) زخماً كبيراً. ومع ذلك، فإن تنفيذ هذه الأنماط في بيئة موزعة يطرح تحديات معقدة تتعلق باتساق البيانات وسلامة المعاملات. يستكشف هذا المنشور كيفية الاستفادة بفعالية من CockroachDB، قاعدة بيانات SQL موزعة، لتنفيذ هذه الأنماط مع الحفاظ على الضمانات القوية التي يتوقعها المطورون من قواعد البيانات العلائقية التقليدية.

لماذا CockroachDB لمصدر الأحداث؟

مصدر الأحداث (Event Sourcing) هو نمط معماري حيث يتم تخزين تغييرات الحالة كسلسلة من الأحداث. وعلى عكس تطبيقات CRUD التقليدية التي تقوم بتحديث الحالة الحالية في مكانها، يقوم ES بإضافة أحداث جديدة إلى سجل غير قابل للتغيير. يوفر هذا النهج مسار تدقيق كاملاً ويمكّن من إجراء استعلامات زمنية معقدة. ومع ذلك، فإنه يتطلب طبقة تخزين قوية قادرة على التعامل مع معدل كتابة عالي وضمان تطبيق الأحداث بالترتيب الدقيق الذي حدثت به.

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

تنفيذ CQRS مع نماذج قراءة وكتابة منفصلة

يفصل CQRS نموذج قراءة البيانات عن نموذج كتابة البيانات. في سياق SQL الموزع، يسمح هذا الفصل بالتوسع المستقل. يمكنك توسيع نطاق طبقة الكتابة للتعامل مع استيعاب الأحداث عالي الحجم، وطبقة القراءة للتعامل مع الاستعلامات التحليلية المعقدة دون تداخل.

في CockroachDB، يمكنك تنفيذ ذلك باستخدام مخططات (schemas) منفصلة أو حتى قواعد بيانات منفصلة لعمليات الكتابة والقراءة. لضمان بقاء نموذج القراءة متزامناً مع أحدث الأحداث، يمكنك استخدام التقاط تغيير البيانات (CDC) أو الاستنساخ القائم على المشغلات (triggers). يضمن ذلك أن الجداول المحسّنة للقراءة (التي قد تكون غير طبيعية لأغراض الأداء) تعكس دائماً مصدر الحقيقة الذي يتم الحفاظ عليه في مخزن الأحداث.

التعامل مع المعاملات الموزعة والاتساق

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

فكر في السيناريو الذي يضع فيه المستخدم طلباً. تحتاج إلى إضافة حدث OrderCreated وتحديث عدد المخزون. في قاعدة بيانات SQL التقليدية، هذه معاملة بسيطة. في CockroachDB، يمكنك تحقيق نفس المستوى من الذرية:


BEGIN;

-- Append the event to the event store
INSERT INTO events (id, aggregate_id, event_type, payload, created_at)
VALUES (gen_random_uuid(), 'order-123', 'ORDER_CREATED', '{"quantity": 1}'::JSONB, NOW());

-- Update the inventory in a separate table
UPDATE inventory SET stock_count = stock_count - 1 WHERE product_id = 'prod-456';

COMMIT;

جمال هذا النهج هو أنه إذا فشل تحديث المخزون (على سبيل المثال، بسبب عدم كفاية المخزون)، يتم التراجع عن المعاملة بأكملها، ولا يتم تثبيت أي حدث. يمنع هذا إنشاء أحداث "شبح" تصف تغييرات في الحالة لم تحدث فعلياً.

التحسين للأداء

بينما تتعامل CockroachDB مع الاتساق تلقائياً، لا يزال ضبط الأداء ضرورياً لأحمال عمل مصدر الأحداث عالية الإنتاجية. استخدم الإدخالات الضخمة لتجميع الأحداث، واستفد من التجزئة على العمود created_at لتحسين استعلامات السلاسل الزمنية. بالإضافة إلى ذلك، فكر في استخدام الجداول العرضية (materialized views) لنماذج القراءة الخاصة بك لتخفيف عمليات الانضمام المعقدة عن جدول الأحداث الرئيسي.

الخاتمة

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

Share: