سجل موزع لمجموعة العجلات: تجربة مع نسيج Hyperledger

مرحبًا، أنا أعمل في فريق مشروع DRD KP (سجل البيانات الموزع لمراقبة دورة حياة مجموعات العجلات). أود هنا أن أشارك تجربة فريقنا في تطوير blockchain للمؤسسة لهذا المشروع في ظل قيود التكنولوجيا. بالنسبة للجزء الأكبر، سأتحدث عن Hyperledger Fabric، ولكن النهج الموصوف هنا يمكن استقراءه على أي blockchain مسموح به. الهدف النهائي لبحثنا هو إعداد حلول blockchain للمؤسسات بطريقة تجعل المنتج النهائي ممتعًا للاستخدام وليس من الصعب صيانته.

لن تكون هناك اكتشافات، أو حلول غير متوقعة، ولن تتم تغطية أي تطورات فريدة هنا (لأنني لا أملكها). أريد فقط أن أشارك تجربتي المتواضعة، وأظهر أنه "كان ذلك ممكنًا"، وربما أقرأ في التعليقات عن تجربة شخص آخر في اتخاذ قرارات جيدة وغير جيدة.

المشكلة: blockchain ليست قابلة للتطوير بعد

اليوم، تهدف جهود العديد من المطورين إلى جعل تقنية blockchain تقنية مريحة حقًا، وليست قنبلة موقوتة في غلاف جميل. قد تصبح قنوات الحالة والتراكم المتفائل والبلازما والتقسيم أمرًا شائعًا. في يوم ما. أو ربما تؤجل TON الإطلاق مرة أخرى لمدة ستة أشهر، وستتوقف مجموعة Plasma Group التالية عن الوجود. يمكننا أن نؤمن بخريطة طريق أخرى ونقرأ التقارير البيضاء الرائعة في الليل، ولكن هنا والآن يتعين علينا أن نفعل شيئًا بما لدينا. أنجز الأمور.

تبدو المهمة الموكلة إلى فريقنا في المشروع الحالي كما يلي بشكل عام: هناك العديد من الأشخاص، الذين يصلون إلى عدة آلاف، الذين لا يريدون بناء علاقات على الثقة؛ من الضروري البناء على حل DLT الذي سيعمل على أجهزة الكمبيوتر العادية دون متطلبات أداء خاصة ويوفر تجربة مستخدم ليست أسوأ من أي أنظمة محاسبة مركزية. يجب أن تقلل التكنولوجيا الكامنة وراء الحل من احتمالية التلاعب بالبيانات الضارة – وهذا هو سبب وجود blockchain.

تعدنا الشعارات الواردة في الأوراق البيضاء ووسائل الإعلام بأن التطوير التالي سيسمح بملايين المعاملات في الثانية. ما هو حقا؟

تعمل الشبكة الرئيسية Ethereum حاليًا بمعدل 30 نقطة في الثانية تقريبًا. ولهذا السبب وحده، من الصعب أن ننظر إليها على أنها blockchain مناسبة بأي شكل من الأشكال لاحتياجات الشركات. من بين الحلول المسموح بها، تُعرف المعايير التي تظهر 2000 نقطة في الثانية (نصاب قانوني) أو 3000 نقطة (النسيج هيبيردلجر، يوجد القليل في المنشور، لكن ضع في اعتبارك أن المعيار تم تنفيذه على محرك الإجماع القديم). كان محاولة لإعادة صياغة النسيج بشكل جذريوالتي لم تعط أسوأ النتائج 20000 نقطة ولكن حتى الآن هذه مجرد دراسات أكاديمية تنتظر تنفيذها المستقر. من غير المرجح أن تتحمل الشركة القادرة على تحمل تكاليف إدارة قسم مطوري blockchain مثل هذه المؤشرات. لكن المشكلة لا تكمن فقط في الإنتاجية، بل هناك أيضًا زمن الوصول.

كمون

إن التأخير من لحظة بدء المعاملة حتى الموافقة النهائية عليها من قبل النظام لا يعتمد فقط على سرعة مرور الرسالة عبر جميع مراحل التحقق والطلب، ولكن أيضًا على معلمات تشكيل الكتلة. حتى لو كانت تقنية blockchain الخاصة بنا تسمح لنا بالالتزام بسرعة 1000000 tps، ولكن الأمر يستغرق 10 دقائق لتكوين كتلة بحجم 488 ميجابايت، فهل سيصبح الأمر أسهل بالنسبة لنا؟

دعونا نلقي نظرة فاحصة على دورة حياة المعاملة في Hyperledger Fabric لفهم ما يستغرق وقتًا ومدى ارتباطه بمعلمات تكوين الكتلة.

سجل موزع لمجموعة العجلات: تجربة مع نسيج Hyperledger
مأخوذ من هنا: Hyperledger-fabric.readthedocs.io/en/release-1.4/arch-deep-dive.html#swimlane

(1) يقوم العميل بتكوين معاملة، ويرسلها إلى أقرانه المعتمدين، ويقوم الأخير بمحاكاة المعاملة (يطبق التغييرات التي أجراها رمز السلسلة على الحالة الحالية، ولكن لا يلتزم بدفتر الأستاذ) ويتلقى RWSet - أسماء المفاتيح والإصدارات و القيم المأخوذة من المجموعة في CouchDB، (2) يرسل المصادقون RWSet موقعة مرة أخرى إلى العميل، (3) يقوم العميل إما بالتحقق من توقيعات جميع الأقران الضروريين (المصدقين)، ثم يرسل المعاملة إلى الطلب الخدمة، أو إرسالها دون التحقق (سيستمر التحقق لاحقًا)، وتشكل خدمة الطلب كتلة و(4) تُرسل مرة أخرى إلى جميع الأقران، وليس فقط المُصادقين؛ يتحقق الأقران من أن إصدارات المفاتيح في مجموعة القراءة تتطابق مع الإصدارات الموجودة في قاعدة البيانات، وتوقيعات جميع المصادقين، وأخيرًا يلتزمون بالكتلة.

ولكن هذا ليس كل شيء. خلف عبارة "الأمر يشكل كتلة" لا يتم إخفاء ترتيب المعاملات فحسب، بل أيضًا 3 طلبات شبكة متتالية من القائد إلى المتابعين والعودة: يضيف القائد رسالة إلى السجل، ويرسلها إلى المتابعين، والأخير يضيف إلى سجلهم، أرسل تأكيدًا لنجاح النسخ المتماثل إلى القائد، يلتزم القائد بالرسالة، ويرسل تأكيد الالتزام إلى المتابعين، ويلتزم المتابعين. كلما كان حجم الكتلة ووقتها أصغر، كلما كان على خدمة الطلب في كثير من الأحيان التوصل إلى توافق في الآراء. يحتوي Hyperledger Fabric على معلمتين لتشكيل الكتلة: BatchTimeout - وقت تكوين الكتلة وBatchSize - حجم الكتلة (عدد المعاملات وحجم الكتلة نفسها بالبايت). بمجرد وصول أحد المعلمات إلى الحد الأقصى، يتم إصدار كتلة جديدة. كلما زاد عدد العقد المطلوبة، كلما استغرق ذلك وقتًا أطول. لذلك، تحتاج إلى زيادة BatchTimeout وBatchSize. ولكن نظرًا لإصدار مجموعات RWS، فكلما زاد حجم الكتلة، زاد احتمال حدوث تعارضات MVCC. بالإضافة إلى ذلك، مع زيادة BatchTimeout، تتدهور تجربة المستخدم بشكل كارثي. يبدو لي معقولًا وواضحًا المخطط التالي لحل هذه المشكلات.

كيفية تجنب انتظار الانتهاء من الكتلة وعدم فقدان حالة المعاملة

كلما زاد وقت التكوين وحجم الكتلة، زاد إنتاجية blockchain. لا يتبع أحدهما مباشرة من الآخر، ولكن يجب أن نتذكر أن إنشاء توافق في الآراء في RAFT يتطلب ثلاثة طلبات شبكة من القائد إلى المتابعين والعكس. كلما زاد عدد عقد الطلب، كلما استغرق الأمر وقتًا أطول. كلما كان حجم ووقت تكوين الكتلة أصغر، كلما زادت هذه التفاعلات. كيفية زيادة وقت التكوين وحجم الكتلة دون زيادة وقت استجابة النظام للمستخدم النهائي؟

أولاً، تحتاج إلى حل تعارضات MVCC بطريقة أو بأخرى الناتجة عن حجم الكتلة الكبير، والتي يمكن أن تتضمن مجموعات RWS مختلفة بنفس الإصدار. من الواضح، من ناحية العميل (فيما يتعلق بشبكة blockchain، قد يكون هذا بمثابة واجهة خلفية، وأنا أعني ذلك) معالج تعارض MVCC، والتي يمكن أن تكون إما خدمة منفصلة أو ديكورًا عاديًا عبر مكالمة بدء المعاملة باستخدام منطق إعادة المحاولة.

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

الخطوة التالية هي جعل تفاعل العميل مع النظام غير متزامن بحيث لا ينتظر 15 أو 30 أو 10000000 ثانية، والتي سنعينها كـ BatchTimeout. ولكن في الوقت نفسه، من الضروري الحفاظ على القدرة على التأكد من تسجيل / عدم تسجيل التغييرات التي بدأتها المعاملة في blockchain.
يمكن استخدام قاعدة البيانات لتخزين حالة المعاملات. الخيار الأسهل هو CouchDB نظرًا لسهولة استخدامه: تحتوي قاعدة البيانات على واجهة مستخدم جاهزة، وREST API، ويمكنك بسهولة إعداد النسخ المتماثل والتقسيم لها. يمكنك فقط إنشاء مجموعة منفصلة في نفس مثيل CouchDB الذي يستخدمه Fabric لتخزين حالته العالمية. نحن بحاجة لتخزين وثائق من هذا النوع.

{
 Status string // Статус транзакции: "pending", "done", "failed"
 TxID: string // ID транзакции
 Error: string // optional, сообщение об ошибке
}

تتم كتابة هذا المستند إلى قاعدة البيانات قبل إرسال المعاملة إلى النظراء، ويتم إرجاع معرف الكيان إلى المستخدم (يتم استخدام نفس المعرف كمفتاح) إذا كانت هذه عملية إنشاء، ثم يتم عرض حقول الحالة وTxID والخطأ يتم تحديثها عند تلقي المعلومات ذات الصلة من أقرانها.

سجل موزع لمجموعة العجلات: تجربة مع نسيج Hyperledger

في هذا المخطط، لا ينتظر المستخدم حتى تتشكل الكتلة أخيرًا، ويشاهد عجلة الغزل على الشاشة لمدة 10 ثوانٍ، بل يتلقى استجابة فورية من النظام ويستمر في العمل.

لقد اخترنا BoltDB لتخزين حالات المعاملات لأننا بحاجة إلى حفظ الذاكرة ولا نريد إضاعة الوقت في تفاعل الشبكة مع خادم قاعدة بيانات مستقل، خاصة عندما يتم هذا التفاعل باستخدام بروتوكول النص العادي. بالمناسبة، سواء كنت تستخدم CouchDB لتنفيذ المخطط الموضح أعلاه أو فقط لتخزين الحالة العالمية، في أي حال، فمن المنطقي تحسين طريقة تخزين البيانات في CouchDB. افتراضيًا، في CouchDB، يبلغ حجم عقد b-tree 1279 بايت، وهو أقل بكثير من حجم القطاع على القرص، مما يعني أن قراءة الشجرة وإعادة توازنها سيتطلب المزيد من الوصول إلى القرص الفعلي. الحجم الأمثل يلبي المعيار تنسيق متقدم و هو 4 كيلو بايت. للتحسين، نحن بحاجة إلى تعيين المعلمة btree_chunk_size يساوي 4096 في ملف التكوين CouchDB. بالنسبة لـ BoltDB مثل هذا التدخل اليدوي غير مطلوب.

الضغط الخلفي: استراتيجية العازلة

ولكن يمكن أن يكون هناك الكثير من الرسائل. أكثر مما يستطيع النظام التعامل معه، مشاركة الموارد مع عشرات الخدمات الأخرى إلى جانب تلك الموضحة في الرسم البياني - وكل هذا يجب أن يعمل بشكل لا تشوبه شائبة حتى على الأجهزة التي سيكون تشغيل Intellij Idea عليها مملاً للغاية.

يتم حل مشكلة الإنتاجية المختلفة لأنظمة الاتصال، المنتج والمستهلك، بطرق مختلفة. دعونا نرى ما يمكننا القيام به.

إسقاط: يمكننا الادعاء بأننا قادرون على معالجة معظم معاملات X في T ثانية. يتم إسقاط كافة الطلبات التي تتجاوز هذا الحد. الأمر بسيط جدًا، ولكن بعد ذلك يمكنك نسيان تجربة المستخدم.

السيطرة: يجب أن يكون لدى المستهلك واجهة يمكن من خلالها، حسب الحمل، التحكم في tps للمنتج. ليس سيئًا، لكنه يفرض التزامًا على مطوري عميل التحميل بتنفيذ هذه الواجهة. بالنسبة لنا، هذا أمر غير مقبول، حيث سيتم دمج blockchain في المستقبل في عدد كبير من الأنظمة الموجودة منذ فترة طويلة.

التخزين المؤقت: بدلاً من محاولة مقاومة تدفق البيانات المدخلة، يمكننا تخزين هذا التدفق ومعالجته بالسرعة المطلوبة. من الواضح أن هذا هو الحل الأفضل إذا أردنا تقديم تجربة مستخدم جيدة. قمنا بتنفيذ المخزن المؤقت باستخدام قائمة الانتظار في RabbitMQ.

سجل موزع لمجموعة العجلات: تجربة مع نسيج Hyperledger

تمت إضافة إجراءين جديدين إلى المخطط: (1) بعد تلقي طلب واجهة برمجة التطبيقات (API)، يتم وضع الرسالة في قائمة الانتظار مع المعلمات اللازمة لاستدعاء المعاملة، ويتلقى العميل رسالة تفيد بقبول النظام للمعاملة، ( 2) تقرأ الواجهة الخلفية البيانات بالسرعة المحددة في التكوين من قائمة الانتظار؛ يبدأ المعاملة ويحدث البيانات في مخزن الحالة.
يمكنك الآن زيادة وقت البناء وحجب السعة بقدر ما تريد، وإخفاء التأخير عن المستخدم.

أدوات أخرى

لم يُقال أي شيء هنا عن رمز السلسلة، لأنه لا يوجد عادةً ما يمكن تحسينه فيه. يجب أن يكون رمز السلسلة بسيطًا وآمنًا قدر الإمكان - وهذا كل ما هو مطلوب منه. يساعدنا إطار العمل كثيرًا في كتابة رمز السلسلة ببساطة وأمان. CSKit من S7 Techlab ومحلل ثابت إحياء ^ CC.

بالإضافة إلى ذلك، يقوم فريقنا بتطوير مجموعة من الأدوات المساعدة لجعل العمل مع Fabric بسيطًا وممتعًا: مستكشف blockchain، فائدة ل إعادة تكوين الشبكة تلقائيًا (إضافة/إزالة المنظمات، عقد RAFT)، الأداة المساعدة لـ إلغاء الشهادة وإزالة الهوية. إذا كنت ترغب في المساهمة، مرحبا بك.

اختتام

يجعل هذا النهج من السهل استبدال Hyperledger Fabric بـ Quorum، وشبكات Ethereum الخاصة الأخرى (PoA أو حتى PoW)، مما يقلل بشكل كبير من الإنتاجية الحقيقية، ولكن في نفس الوقت يحافظ على تجربة المستخدم العادية (سواء للمستخدمين في المتصفح أو من جانب الأنظمة المتكاملة) ). عند استبدال Fabric بـ Ethereum في المخطط، سيلزم فقط تغيير منطق خدمة إعادة المحاولة/مصمم الديكور من معالجة تعارضات MVCC إلى زيادة عددية ذرية وإعادة الإرسال. أتاح التخزين المؤقت وتخزين الحالة إمكانية فصل وقت الاستجابة عن وقت تكوين الكتلة. يمكنك الآن إضافة الآلاف من عقد الطلب وعدم الخوف من تكوين الكتل بشكل متكرر وتحميل خدمة الطلب.

على العموم هذا كل ما أردت مشاركته. سأكون سعيدًا إذا كان ذلك يساعد شخصًا ما في عمله.

المصدر: www.habr.com

إضافة تعليق