لقد كنت مخطئ. المستقبل هو CRDT

قبل بضعة أسابيع ، شاهدت العرض الذي قدمه مارتن كليبمان عن منهجه في التحرير الفوري عبر CRDT وشعرت باليأس الشديد . منهجه جيد جدًا لدرجة أنه يفوق كل أعمالي على مدار العقد الماضي ، ولن يكون هناك مكان له في المستقبل.



لكن لنبدأ من جديد.



في عام 2010 ، عملت في Google Wave ، حيث حاولنا إنشاء مساحات تعاونية قابلة للتحرير لاستبدال البريد الإلكتروني ومحطات Google Docks والمنتديات والمراسلة الفورية والعديد من التطبيقات الأخرى ذات المهام الفردية. من بين أدواتي ، أحب بشكل خاص بيئة الأغراض العامة ، في أي مكان آخر كما في Wave ، لم تتم صياغة الوظيفة في ذلك الوقت. بخلاف معظم الأدوات الأخرى ، لا تفرض بيئة الأغراض العامة سير العمل الخاص بها ، لذا يمكنك استخدامها للتخطيط للعطلات وإنشاء مواقع wiki ولعب ألعاب الطاولة مع الأصدقاء وجدولة اجتماعات العمل وغير ذلك الكثير.



داخليًا ، يعمل التحرير المشترك لـ Wave فوق التحويل التشغيلي (OT) ، وقد تم استخدامه لعدة أيام في ذلك الوقت: استندت الخوارزمية الخاصة بنا إلى حديث المشتري لعام 1995. لكل وثيقة ، تحتفظ الخوارزمية بقائمة منفصلة من التغييرات مرتبة ترتيبًا زمنيًا ، "اكتب H في الموضع 0" ، "اكتب i في الموضع 1" ، وهكذا. في معظم الحالات ، يقوم المستخدمون بتغيير أحدث إصدار من المستند ، ويبدو السجل كسلسلة من التغييرات ، ومع ذلك ، عند المشاركة في التأليف ، نواجه عمليات تحرير متزامنة.



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



مع إغلاق Google Wave ، قمت بنقل نموذج OT إلى ShareJS . في ذلك الوقت شعرت العقدة بأنها جديدة وغريبة ، وإذا كنت أتذكر بشكل صحيح ، فقد بدأت ShareJS حتى قبل إصدار npm. يتطلب المحرر المشارك البسيط ألف سطر فقط من التعليمات البرمجية ، وخلال العرض التوضيحي قمت بتحرير المستند في المتصفح وفي التطبيق.



في جوهرها ، OT عبارة عن حلقة منمقة لـ ()مع وظائف مساعدة متعددة لتحديث إزاحة الأحرف. من الناحية العملية ، فإن OT بسيطة وسهلة الفهم ويتم تشغيلها بسرعة وتعمل بشكل رائع. (10-100 ألف عملية في الثانية بجافا سكريبت غير محسن ، 1-20 مليون في لغة سي المحسنة ). يمكن أن يستهلك سجل الأحداث ذاكرة أكثر من المعتاد ، ولكن يمكن تقليصها إذا رغبت في ذلك ، على الرغم من أنه لن يعمل على دمج عمليات التحرير القديمة بشكل خاص. سيتطلب تخصيص العمليات عالميًا خادمًا مركزيًا ، ولكن معظم الأنظمة لديها بالفعل مثل هذا الخادم أو قاعدة البيانات ، أليس كذلك؟



خوادم مركزية



تتمثل مشكلة OT الكبيرة في اعتمادها على خادم مركزي. هل تساءلت يومًا لماذا ، عند السماح بالوصول إلى مستند محرّر مستندات Google عبر الشبكات الاجتماعية ، واجهت رسالة غريبة مثل "هذا المستند محمّل بشكل زائد وتم تعطيل تحريره"؟ السبب (في رأيي) هو كما يلي: عندما تفتح مستندًا ، يتم تحديد خادم واحد محدد لمعالجة جميع تعديلاته ، وعندما ينقض حشد من المستخدمين على المستند ، يتعين على النظام أن يحاول جاهدًا عدم زيادة التحميل على الخادم.



هناك عدة طرق للتغلب على هذه المشكلة: بالإضافة إلى تجزئة المستندات الثانوية (كما هو الحال في أحواض Google) ، يمكنك إجراء تعديلات من خلال حلقة إعادة المحاولة لتجاوز معاملات قاعدة البيانات ، بحيث تتولى نفس قاعدة البيانات مشكلة التسلسل (هذه هي الطريقة التي يعمل بها Firepadو ShareDB ).



ومع ذلك ، فإن OT ليست مثالية. أردنا استبدال البريد الإلكتروني بـ Wave ، لكن البريد يدعم الدمج ، ويمكن لسلسلة واحدة من الرسائل أن تمتد عبر العديد من الشركات ، وكلها تعمل بنجاح بطريقة ما. بالإضافة إلى ذلك ، على عكس رسائل Facebook ، يمكن إرسال بريد إلكتروني إلى الشركات المذكورة في عمود "نسخ". إذا أردنا أن يحل Wave محل البريد ، فسيحتاج أيضًا إلى وظيفة إرسال الرسائل دون الوصول إلى الشبكة الخارجية ، على سبيل المثال ، عندما أرسل خطابًا إلى زميلي في الجدول التالي. ولكن كيف يمكنك تنفيذ كل هذا على رأس OT؟ لقد تمكنا بطريقة ما من إعداد مثل هذه العملية ، لكن تبين أنها معقدة للغاية ومليئة بالأخطاء: لقد أنشأنا مخططًا، حيث يقوم كل بروتوكول موجة بإعداد شجرة من خوادم الموجة لنقل العمليات في كلا الاتجاهين ، لكنه لم يعمل بشكل كامل. قبل أقل من عشر سنوات بقليل ، في قمة بروتوكول Wave Protocol ، قدمت عرضًا تقديميًا حول كيفية إنشاء مثل هذه الشبكة وتكوينها ، ولكن على الرغم من كل تحضيراتي وجميع الفحوصات الأولية ، فقد فشل التقيد الصارم بكل خطوة في العرض التقديمي نفسه ، ولم تنجح الشبكة أبدًا. ما زلت لا أعرف سبب حدوث ذلك ، ولكن مهما كانت الأخطاء ، لم يتم إصلاحها على الإطلاق في الإصدار العام ، كان الأمر صعبًا للغاية.



الإقلاع CRTD



كما ذكرت سابقًا ، تم إنشاء خوارزمية Wave الرئيسية منذ وقت طويل جدًا ، في عام 1995 ، ولا أتذكر حتى وجود الإنترنت في المنزل في ذلك الوقت. منذ ذلك الحين ، عمل الباحثون بلا كلل لتحسين أداء OT ، وفي الاتجاه الواعد ، يستخدمون CRTD (أنواع البيانات المكررة الخالية من النزاعات). يختلف هذا الأسلوب إلى حد ما عن المعتاد ويسمح لك بتحرير الملفات في الوقت الفعلي دون الحاجة إلى خادم مركزي. يصف عرض مارتن عملهم بشكل أفضل مما يمكنني وصفه ، لذلك سأتخطى التفاصيل.



كان الناس يسألونني عن رأيي في CRTD لسنوات ، وإجابتي تبدو دائمًا على هذا النحو:



إنهم أنيقون وأنا سعيد لأن الناس يعملون عليها ، ومع ذلك:


  • . . , 100 Delta-CRTD . (: B4.)
  • - CRTD , , 100 automerge master 83 . , , , , . ( automerge 1.1 .)
  • لسنوات ، كانت الوظيفة الموجودة في OT غائبة في CRDT ، على سبيل المثال ، لم يقم أي شخص بعد بعمل CRDT مع دعم / تحريك الكائن / (نقل شيء من جزء من شجرة JSON إلى جزء آخر). هذه الإجراءات مطلوبة لتطبيقات مثل Workflowy ، وتقوم OT بعمل رائع معهم .
  • CRDTs معقدة في حد ذاتها ويصعب التفكير فيها.
  • على الأرجح لديك بالفعل خادم / قاعدة بيانات مركزية.


رغم كل انتقاداتي ، تجاهلت CRDT ، لكنني بذلك تجاهلت الأدبيات ذات الصلة ، ولدهشتي ، فاتني التحسين الهادئ وغير المحسوس لـ CRDT. في عرضه التقديمي (الذي يستحق اهتمامك أكثر) ، يتناول مارتن النقاط الرئيسية:



  • : CRDT (Automerge / RGA Y.js / YATA) [log(n)] . ( .)
  • : - , 54- . automerge , Y.js, Y.js 100 160 3 . .
  • : , .
  • : , CRDT OT. , automerge .


لم يقنعني منطق السرعة ، لذلك لاختبار الفكرة ، قمت بتنفيذ واختبار CRDT بشكل مستقل في Rust من خلال شجرة B باستخدام أفكار من automerge. كانت تفتقر إلى الوظائف (حذف الأحرف ، التعارضات) ، لكنها كانت قادرة على معالجة 6 ملايين تعديل في الثانية . ( أجرى كل تكرار 2000 تعديلًا على مستند فارغ بواسطة مستخدمين متناوبين ، الأمر الذي استغرق 330 ميكروثانية في المجموع ، أو 6.06 مليون تعديل في الثانية.) لذا فقد تحسنت بالفعل CRDTs وفرق السرعة بينها وبين OT أصبح الآن أقل من Rust و جافا سكريبت.



كانت كل هذه الإصلاحات في قسم "قريبًا" من فرع أداء automerge لفترة طويلة ، ولكن بعد كل شيء ، فإن الدمج الآلي ليس هو CRDT الوحيد. تثبت Y.js أنها جديرة وتتجاوز بسهولة الإصدار الحالي من الدمج الآلي في اختباراتها . إنه يفتقر إلى الوظيفة التي أهتم بها ، ولكن بشكل عام من الأسهل بالتأكيد إصلاح التنفيذ الحالي بدلاً من إنشاء خوارزمية جديدة.



ابتكار المستقبل



أنا قلق للغاية بشأن إحراز تقدم. ما هو الغريب عدم استخدامه خلال مائة عام؟ من الواضح أنه سيكون لدينا تحرير في الوقت الفعلي ، لكنني لم أعد متأكدًا من تنفيذه من خلال OT وكل العمل الذي قمت به في هذا الصدد ، والذي لا يسعني إلا أن يحزنني.



JSON و REST موجودان في كل مكان هذه الأيام. لنفترض ، بعد 15 عامًا من الآن ، أن التحرير المشترك في الوقت الفعلي سيكون أيضًا في كل مكان. ماذا سيكون معادلاً لـ JSON من حيث التأليف المشترك لسهولة النقل إلى مشروعك؟ في هذا المستقبل المجيد ، سنحتاج إلى تنفيذ عالي الجودة لـ CRDT ، لأنه بالنسبة لبعض التطبيقات ، لن تعمل OT ببساطة ، أو إنشاء إصدار في الوقت الفعلي من GIt من خلاله ، أو لن يعمل أحد أشكال Google Wave البسيطة. ولكن إذا كان لدينا بالفعل تطبيق CRDT جيد ، فهل نحتاج أيضًا إلى تطبيق OT؟ لا أعتقد ذلك ، لأنه لن يكون من الصعب نقل جميع الوظائف من OT إلى CRDT (بما في ذلك ، بالمناسبة ، عمليات القطع) ، في حين أن العكس ليس صحيحًا. يختلف الأشخاص الأذكياء معي ، ولكن في رأيي ، نظرًا لأن لدينا CRDT جيد وسريع لكل لغة ،ستختفي الحاجة إلى OT تمامًا.



تتمثل إحدى مزايا OT في أنه يمكن تنفيذها بسهولة في أنظمة مركزية - مثل معظم التطبيقات الحديثة - ولكن الخوارزميات الموزعة يتم تنفيذها بشكل جيد. (ألق نظرة على Github على سبيل المثال.) إن CRDT عالي الجودة على wasm أسرع من تطبيق OT في JS في رأيي. وإذا كنت مهتمًا فقط بالأنظمة المركزية ، فتذكر: أدت قيود OT إلى قيام Google بمشاكل التوسع في محرر مستندات Google.



لذلك يبدو لي أن الوقت قد حان للتبديل إلى CRDT صغير وسريع. تم بالفعل إنجاز معظم العمل الأكاديمي ، ويظل الأمر يتعلق بالتطبيقات الناجحة.



ماذا بعد



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



من الناحية الفلسفية ، عندما أقوم بتحرير مستند في محرر مستندات Google ، يطلب جهاز الكمبيوتر الخاص بي من Google الإذن بتعديل الملف (لأنه إذا رفض الخادم لسبب ما ، فأنا أفقد جميع تعديلاتي) للمقارنة ، عندما git pushأكون في جيثب ، أنا فقط أبلغgithub حول التعديلات في التعليمات البرمجية الخاصة بي. لا يزال مستودعي ملكًا لي ، كما هو الحال مع كل جزء من البيانات والأجهزة الموجودة عليه ، وهذه هي الطريقة التي يجب أن تعمل بها تطبيقاتي. بفضل أشخاص مثل مارتن ، نحن نعرف الآن كيف نصنع CRDTs جيدة. ومع ذلك ، قبل قبول الطلبات المحلية أولاً كأساس ، يجب كتابة المزيد من سطور التعليمات البرمجية.



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



أنا حزين على كل العمل الذي أنجزته في OT على مر السنين ، لكن OT لم تعد تتناسب مع رؤيتي للمستقبل. سيسمح لنا CRDT بإعادة بناء Wave بشكل أسهل وأسرع وإنشاء تطبيقات تعامل المستخدمين مثل المواطنين الرقميين بدلاً من الفلاحين الرقميين. وهذا مهم.



حان وقت الإبداع.



All Articles