لو بتبني محرّر مستندات تعاوني وعندك 50 مستخدم بيكتبوا في نفس الفقرة، الـ WebSocket المركزي اللي بيرتّب كل operation هيقع تحت الضغط في أول ساعة. CRDT بيخلّي كل عميل يعدّل محليًا ويزامن مع الباقي بأي ترتيب، والنتيجة النهائية مضمونة رياضيًا إنها تتلاقى عند الكل. الفرق العملي: حذفت الـ central authority، نزّلت P95 latency من 340ms لـ 18ms، وقدرت تشتغل offline بدون أي conflict resolution يدوي.
CRDT للمحترف: ازاي Yjs بيدمج تعديلات 50 مستخدم متزامن في Google Docs بدون تضارب
المشكلة باختصار
الموقف: تطبيق Notion-clone فيه 50 مستخدم بيعدّلوا نفس الـ document في نفس اللحظة. Operational Transformation (OT)، اللي Google Docs بتشتغل بيها، بتحتاج سيرفر مركزي يستقبل كل تعديل، يحوّله transform مقابل التعديلات الأقدم منه، وبعدين يبثّه. لو السيرفر بطئ 200ms، 50 مستخدم بيشوفوا الكتابة بتاعتهم بعد التأخير ده. ولو الشبكة اتقطعت، شغل الـ offline بيتعقّد بسرعة.
CRDT (Conflict-free Replicated Data Type) بيقلب المعادلة: كل عميل يطبّق التعديل عنده فورًا، يبعت عمليّاته للباقي بأي ترتيب، وكل عميل بيوصل لنفس النتيجة النهائية بدون coordinator مركزي. مفيش transform، مفيش locking، مفيش "اللي يوصل الأول يكسب".
تخيّل دفتر ملاحظات الفريق (مثال للمبتدئ)
تخيّل 3 موظفين عندهم نسخة من نفس دفتر ملاحظات. كل واحد بيكتب فيه على راحته، وكل ساعة بيتقابلوا ويدمجوا الدفاتر مع بعض. الطريقة التقليدية: يبعتوا الدفاتر لمدير يقعد يقرّر مين كتب الأول ومين عنده الحق. ده الـ OT.
الطريقة التانية: كل موظف بيكتب، ولكل سطر يكتبه يحط timestamp و IDe بتاعه. لما يدمجوا، أي اتنين سطور بنفس الـ ID نفس السطر، ولأي تضارب فيه قاعدة ثابتة (الأكبر ID يفوز مثلًا). كل واحد فيهم لما يطبّق نفس قواعد الدمج هيوصل لنفس الدفتر النهائي حتى لو دمجوا بترتيب مختلف. ده الـ CRDT.
التعريف العلمي الدقيق
CRDT data structure بيحقّق خاصية الـ Strong Eventual Consistency (SEC): أي replicas استقبلوا نفس مجموعة التحديثات بيوصلوا لنفس الـ state، بغض النظر عن ترتيب الاستقبال. الورقة الأصلية لـ Marc Shapiro ومعهد INRIA سنة 2011 ("Conflict-Free Replicated Data Types") أثبتت إن عمليّات الدمج لازم تكون: Commutative (a∘b = b∘a)، Associative (a∘(b∘c) = (a∘b)∘c)، و Idempotent (a∘a = a). لو الخواص التلاتة دي متحقّقة، الـ convergence مضمونة رياضيًا.
في فيه نوعين رئيسيين:
- State-based (CvRDT): العميل بيبعت كامل الـ state، الدمج بيستخدم join function (مثلًا: union of sets).
- Operation-based (CmRDT): العميل بيبعت العمليات نفسها، الترتيب مش مهم لكن الـ delivery لازم يكون causal.
Yjs بيستخدم تطبيق هجين قريب من CmRDT مع causal broadcast، ومُحسَّن لمحرّرات النصوص بـ data structure اسمها YATA (Yet Another Transformation Approach).
]]>