الاتساق القوي والنصاب
الاتساق القوي والنصاب
الاتساق التدريجي أداةٌ عملية، لكنَّ بعض العمليات لا تتحمَّل أي قراءة قديمة. فالتحويل البنكي، وحجز المخزون، أو القفل الموزَّع — يجب أن تعكس آخر حالة مُثبَّتة في كل استعلام. الاتساق القوي يضمن ذلك تماماً: كل قراءة تُشاهد آخر كتابة ناجحة، أياً كان العقدة التي تسألها. والسؤال: كيف يتحقَّق ذلك عبر مجموعة من N نسخة دون اشتراط أن تكون كل العقد تعمل؟
مفهوم النصاب (Quorum)
النصاب هو الحد الأدنى من العقد التي يجب أن تشارك في عملية ما قبل اعتبارها ناجحة. رقمان يحكمان النظام المنسوخ:
W— عدد العقد التي يجب أن تُقرَّ الكتابة قبل أن يُعيد المنسِّق الاستجابة للعميل.R— عدد العقد التي يجب أن تستجيب للقراءة قبل إعادة القيمة.
يحتوي الكتلة على N نسخة إجمالاً. والقاعدة الذهبية هي:
الاختيار الشائع في الإنتاج لـN = 5 هو W = 3، R = 3 (W + R = 6 > 5). إذ إن 3 عقد أقرَّت الكتابة و3 عقد تُستعلَم عند القراءة، فلا بد أن عقدة واحدة على الأقل موجودة في كلتا المجموعتين.
لماذا يضمن التقاطع الحداثة؟
افترض أنك كتبت القيمة v2 إلى العقد A وB وC (W = 3). لاحقاً، تستعلم قراءة من العقد A وD وE (R = 3). العقدة A في المجموعتين؛ فترجع v2. يختار المنسِّق القيمة ذات أعلى ختم إصدار، فيحصل العميل دائماً على v2 — وليس القيمة القديمة v1 التي تعرفها D وE فحسب.
إعدادات النصاب الشائعة
تتيح مجموعات مختلفة من W وR التوازن بين زمن الاستجابة والاتساق، طالما يتحقق W + R > N:
- القراءة الكثيفة (W=N، R=1): يجب أن تُقرَّ الكتابة من جميع العقد (كتابة بطيئة)، لكن أي عقدة واحدة تكفي للقراءة (قراءة سريعة). يُستخدم حين تفوق القراءات الكتابات بفارق كبير.
- الكتابة الكثيفة (W=1، R=N): تُعترَف بالكتابة فوراً من عقدة واحدة، لكن القراءة تحتاج جميع العقد. نادر التطبيق عملياً.
- المتوازن (W = R = ⌈(N+1)/2⌉): الإعداد الأكثر شيوعاً. لـN=5، كلاهما يساوي 3. يتحمَّل فشل ما يصل إلى
N−Wعقدة في الكتابات وN−Rفي القراءات.
النصاب المرن والتسليم الموعود
حين تكون بعض العقد غير متاحة مؤقتاً، سيرفض النصاب الصارم الكتابة ويُعيد خطأً للعميل. تُطبِّق بعض الأنظمة (DynamoDB، Cassandra) نصاباً مرناً: إذا كانت النسخة المستهدفة معطَّلة، تقبل عقدة صحيحة مختلفة الكتابة مؤقتاً مع تخزين "تلميح" لإعادة التوجيه حين تعود العقدة الأصلية. يُبقي ذلك الكتابات متاحة على حساب إضعاف ضمان الاتساق مؤقتاً.
متجهات الإصدار وحل التعارضات
في قراءة النصاب، قد تُعيد نسخ متعددة إصدارات مختلفة للمفتاح ذاته. يجب أن يختار المنسِّق الفائز. ثمة استراتيجيتان:
- آخر كتابة تفوز (LWW): تحمل كل قيمة طابعاً زمنياً أو عداداً تصاعدياً. الأعلى يفوز. بسيطة، لكن انحراف الساعات في العقد الموزعة قد يؤدي إلى حذف كتابة جديدة صالحة.
- متجهات الإصدار: تحتفظ كل عقدة بعداد خاص بها لكل نسخة. يدمج المنسِّق المتجهات ويكتشف التعارضات الحقيقية (الكتابات المتزامنة). يحلَّها التطبيق (عبر CRDTs أو المستخدم). تستخدمه أنظمة مثل Riak ووضع متجه الساعة في DynamoDB.
التطبيقات الفعلية
في Apache Cassandra، تحدد عامل النسخ على مستوى الـkeyspace ومستوى الاتساق في كل استعلام. CONSISTENCY QUORUM على الكتابات والقراءات مع RF=3 يعطي W=2، R=2، محققاً W + R = 4 > 3. بينما يتطلب CONSISTENCY ALL جميع النسخ، مما يُزيل القِدَم لكنه يُقلِّل التوافر.
يستخدم etcd، مخزن إعدادات Kubernetes، خوارزمية Raft داخلياً. Raft في جوهرها بروتوكول نصاب: يجب على القائد استلام إقرارات من أغلبية العقد قبل تثبيت أي إدخال. مع خمس عقد etcd، يحتاج القائد إلى ثلاثة (الأغلبية) — مطابق تماماً لنصاب W=3 من أصل N=5.
زمن الاستجابة مقابل الاتساق
التكلفة الجوهرية للنصاب الصارم هي زمن الاستجابة. لا تُعيد الكتابة نتيجة حتى تستجيب W نسخ، والقراءة تنتظر R نسخ. إذا كانت إحدى تلك النسخ في منطقة توافر مختلفة تضيف 20 مللي ثانية، فسيُهيمن P99 للكتابة على أبطأ الإقرارات. ولهذا يُعدُّ ضبط W وR قراراً تجارياً: سلة التسوق تتحمل الاتساق التدريجي (زمن أقل، توافر أعلى)، بينما دفتر الأستاذ المالي يستدعي النصاب الصارم (زمن أعلى، صواب مطلق).
N=3، W=2، R=2. هذه النقطة المثالية لمعظم قواعد البيانات: تتحمل فشل عقدة واحدة في الكتابات والقراءات، وتضيف تكلفة شبكية بسيطة، وتُحقق قاعدة النصاب بمريحة (4 > 3).
النصاب ليس حلاً سحرياً
حتى مع W + R > N، لا يكون الخطي (Linearizability) تلقائياً. في حال تسابق كتابتين متزامنتين، قد يرى المنسِّق قيماً مختلفة من عقد مختلفة في الجولة القرائية ذاتها. الأنظمة التي تحتاج إلى خطية حقيقية — دون أي حالات شاذة — يجب أن تُضيف بروتوكول توافق (Raft أو Paxos) فوق النصاب. النصاب وحده يضمن فقط أن الكتابة المُثبَّتة بالكامل مرئية، لا أن الكتابات المتزامنة مُرتَّبة بشكل صحيح. نتناول Raft وPaxos في الدرس السابع.