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

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

حيثما أمكن ، نتبع قاعدة الإلحاق فقط. لا تعديلات وحذف الكائنات ، باستثناء إزالة البيانات القديمة وغير الضرورية.
يمر أكثر من 2 تيرابايت من البيانات الخام عبر الخدمة في اليوم الواحد.
المزايا:
- تحتوي التدفقات على جميع الأحداث والرسائل. يمكننا دائمًا فهم ما حدث ومتى حدث. يمكن اعتبار الدفق بمثابة سجل كبير.
- الكفاءة العالية والحد الأدنى من النفقات العامة. اتضح نظامًا موجهًا بالكامل نحو الحدث ، دون أي خسارة في الاقتراع. لا يوجد حدث - نحن لا نفعل أي شيء إضافي.
- لا يتعامل رمز التطبيق عمليًا مع بدائل مزامنة الخيط والذاكرة المشتركة بين سلاسل المحادثات. هذا يجعل النظام أكثر موثوقية.
- المعالجات معزولة بشكل جيد عن بعضها البعض ، لأن لا تتفاعل بشكل مباشر فقط من خلال الجداول. يمكن توفير تغطية اختبار جيدة.
لكن تدفق معالجة البيانات ليس بهذه البساطة:
- مطلوب فهم جيد للنموذج الحسابي. سيكون عليك إعادة التفكير في خوارزميات معالجة البيانات الحالية. لا تقع جميع الخوارزميات على الفور في نموذج البث وعليك تحطيم رأسك قليلاً.
- من الضروري ضمان الحفاظ على ترتيب استلام ومعالجة الأحداث.
- يجب أن تكون قادرًا على التعامل مع الأحداث المترابطة ، أي الوصول السريع إلى جميع البيانات الضرورية أثناء معالجة رسالة جديدة.
- تحتاج أيضًا إلى أن تكون قادرًا على التعامل مع الأحداث المكررة.
معالجة دفق
أثناء العمل على المشروع ، تمت كتابة مكتبة Stream Processor ، مما ساعدنا على تنفيذ وإطلاق خوارزميات معالجة البيانات المتدفقة في الإنتاج بسرعة.
دفق المعالج هو مكتبة لبناء أنظمة معالجة البيانات المتدفقة. الدفق هو تسلسل محتمل لانهائي من البيانات (الرسائل) التي يمكن فقط إضافة رسائل جديدة إليها ؛ لا يتم تغيير الرسائل المسجلة بالفعل ولا يتم حذفها من الدفق. تتكون محولات دفق إلى آخر (معالجات دفق) وظيفيا من ثلاثة أجزاء: موفر الرسائل الواردة ، الذي عادة ما يقرأ الرسائل من واحد أو أكثر من التدفقات ويضعها في قائمة انتظار المعالجة ، ومعالج الرسائل الذي يحول الرسائل الواردة إلى الرسائل الصادرة ويضعها في قائمة انتظار إلى السجل ، والكاتب ، حيث تقع الرسائل الصادرة المجمعة في إطار الوقت في دفق الإخراج. يمكن استخدام رسائل البيانات التي تم إنشاؤها بواسطة معالج دفق بواسطة الآخرين فيما بعد. وبالتالي ، تشكل التدفقات والمعالجات رسمًا بيانيًا موجهًا تكون فيه الحلقات ممكنة ، على وجه الخصوص ، يمكن لمعالج الدفق إنشاء رسائل في نفس الدفق من حيث يتلقى البيانات.
نضمن معالجة كل رسالة من دفق الإدخال بواسطة كل معالج مرتبط بها مرة واحدة على الأقل (معاني الكلمات مرة واحدة على الأقل). من المضمون أيضًا أن تتم معالجة جميع الرسائل بالترتيب الذي وصلت به في هذا الدفق. للقيام بذلك ، يتم توزيع معالجات الدفق على جميع عقد خدمة العمل ، بحيث لا يعمل أكثر من مثيل واحد لكل معالج مسجل في وقت واحد.
تعد معالجة الأحداث المترابطة واحدة من المشاكل الرئيسية في أنظمة البناء لتدفق معالجة البيانات. كقاعدة عامة ، عند دفق الرسائل ، تنشئ معالجات الدفق تدريجيًا حالة معينة كانت صالحة في وقت معالجة الرسالة الحالية. لا ترتبط كائنات الحالة هذه عادةً مع الدفق بأكمله ككل ، ولكن مع مجموعة فرعية معينة من الرسائل ، والتي يتم تحديدها من خلال القيمة الرئيسية في هذا الدفق. التخزين الفعال للثروة هو مفتاح النجاح. عند معالجة الرسالة التالية ، من المهم أن يتمكن المعالج من الحصول على هذه الحالة بسرعة ، وبناءً عليها والرسالة الحالية ، يقوم بإنشاء الرسائل الصادرة. يمكن الوصول إلى كائنات الحالة هذه للمعالجات في L1 (يرجى عدم الخلط بين ذاكرة التخزين المؤقت لوحدة المعالجة المركزية) وذاكرة التخزين المؤقت LRU الموجودة في الذاكرة. في حالة عدم وجود حالة في ذاكرة التخزين المؤقت L1 ، يتم استعادتها من ذاكرة التخزين المؤقت L2 الموجودة في نفس التخزين حيث يتم تخزين التدفقات وحيث يتم تخزينها بشكل دوري أثناء تشغيل المعالج. إذا لم تكن هناك حالة في ذاكرة التخزين المؤقت L2 ، فسيتم استعادتها من رسائل الدفق الأصلية ، كما لو كان المعالج قد قام بمعالجة جميع الرسائل الأصلية المرتبطة بمفتاح الرسالة الحالي. تتيح لك تقنية التخزين المؤقت أيضًا التعامل مع مشكلة الكمون الكبير للتخزين ، نظرًا لأن المعالجة المتسلسلة غالبًا لا تعتمد على أداء الخادم ، ولكن على تأخير الطلبات والاستجابات عند الاتصال بمستودع البيانات.

لتخزين البيانات بشكل فعال في ذاكرة التخزين المؤقت L1 وبيانات الرسائل في الذاكرة ، بالإضافة إلى الهياكل الموفرة للذاكرة ، نستخدم تجمعات الكائنات التي تتيح لك الحصول على نسخة واحدة فقط من كائن (أو حتى أجزاء منه) في الذاكرة. يتم استخدام هذه التقنية بالفعل في JDK لسلاسل تدريب السلسلة وتمتد بالمثل إلى أنواع أخرى من الكائنات ، والتي يجب أن تكون ثابتة.
للتخزين المضغوط للبيانات في تخزين الدفق ، يتم تسوية بعض البيانات قبل الكتابة إلى الدفق ، أي تتحول إلى أرقام. يمكن بعد ذلك تطبيق خوارزميات الضغط الفعالة على الأرقام (معرفات الكائن). يتم فرز الأرقام ، ويتم حساب الدلتا ، ثم التشفير باستخدام ZigZag Encoding ثم الضغط بواسطة الأرشيف. التطبيع ليس تقنية قياسية جدًا لتدفق أنظمة معالجة البيانات. لكن تقنية الضغط هذه فعالة للغاية ويتم تقليل كمية البيانات في التدفق الأكثر تحميلًا بحوالي 1000 مرة.

لكل دفق ومعالج ، نتتبع دورة حياة معالجة الرسائل: ظهور الرسائل الجديدة في دفق الإدخال ، وحجم قائمة انتظار الرسائل غير المجهزة ، وحجم قائمة الانتظار للكتابة إلى الدفق الناتج ، ووقت معالجة الرسالة ، وتوزيع الوقت حسب مراحل معالجة الرسالة:

مستودع البيانات
يجب أن تكون نتائج معالجة البيانات المتدفقة متاحة للمستخدم في أقرب وقت ممكن. يجب تسجيل البيانات المعالجة من التدفقات بشكل مستمر في قاعدة البيانات ، حيث يمكنك بعد ذلك الذهاب إلى البيانات (على سبيل المثال ، إظهار تقرير بنتائج الاختبار ، إظهار تاريخ الاختبار).
خصائص البيانات والاستعلامات المخزنة.
معظم البيانات عبارة عن اختبارات تشغيل. على مدى شهر ، تم إطلاق أكثر من 1.5 مليار إصدار واختبار. يتم تخزين كمية كبيرة إلى حد ما من المعلومات لكل عملية إطلاق: نتيجة ونوع الخطأ ، ووصف موجز للخطأ (المقتطف) ، والعديد من الروابط إلى السجلات ، ومدة الاختبار ، ومجموعة من القيم الرقمية ، والمقاييس ، في اسم التنسيق = القيمة ، إلخ. من الصعب جدًا ضغط بعض هذه البيانات - على سبيل المثال ، المقاييس والمدة - حيث إنها في الواقع قيم عشوائية. يمكن حفظ الجزء الآخر - على سبيل المثال ، النتيجة ونوع الخطأ والسجلات - بكفاءة أكبر ، نظرًا لأنها لا تتغير تقريبًا في نفس الاختبار من التشغيل إلى التشغيل.
في السابق ، استخدمنا MySQL لتخزين البيانات المعالجة. بدأنا تدريجياً بالراحة مقابل قدرات قاعدة البيانات:
- يتضاعف مقدار البيانات التي تتم معالجتها كل ستة أشهر.
- يمكننا فقط تخزين البيانات للشهرين الماضيين ، لكننا أردنا تخزين البيانات لمدة عام على الأقل.
- مشاكل في سرعة تنفيذ بعض الاستفسارات الثقيلة (القريبة من التحليلية).
- مخطط قاعدة البيانات المعقدة. العديد من الجداول (التطبيع) مما يعقد الكتابة لقاعدة البيانات. يختلف المخطط الأساسي اختلافًا كبيرًا عن مخطط الأشياء المستخدمة في دائرة الوقت الفعلي.
- لا تواجه إيقاف تشغيل الخادم. يمكن أن يؤدي فشل خادم منفصل أو إغلاق مركز البيانات إلى فشل النظام.
- عملية معقدة للغاية.
كمرشحين لمستودع البيانات الجديد ، أخذنا بعين الاعتبار عدة خيارات: PostgreSQL و MongoDB والعديد من الحلول الداخلية ، بما في ذلك ClickHouse .
لا تسمح لنا بعض الحلول بتخزين بياناتنا بشكل أكثر كفاءة من حل MySQL القديم. البعض الآخر لا يسمح بتنفيذ استعلامات سريعة ومعقدة (تحليلية تقريبًا). على سبيل المثال ، لدينا طلب كبير نوعًا ما يوضح الالتزامات التي تؤثر على مشروع معين (مجموعة من الاختبارات). في جميع الحالات التي لا يمكننا فيها تنفيذ استعلامات SQL السريعة ، سيتعين علينا إجبار المستخدم على الانتظار لفترة طويلة أو إجراء بعض العمليات الحسابية مقدمًا مع فقدان المرونة. إذا كنت تحسب شيئًا مقدمًا ، فأنت بحاجة إلى كتابة المزيد من التعليمات البرمجية وفي نفس الوقت تفقد المرونة - لا توجد طريقة لتغيير السلوك بسرعة وإعادة سرد أي شيء. إن كتابة استعلام SQL الذي سيعيد البيانات التي يحتاجها المستخدم ويكون قادرًا على تعديلها بسرعة إذا كنت ترغب في تغيير سلوك النظام هو أكثر ملاءمة وأسرع.
كليك هاوس
اخترنا ClickHouse . ClickHouse هو نظام إدارة قاعدة بيانات عمودي (DBMS) لمعالجة الاستعلام التحليلي عبر الإنترنت (OLAP).
بالانتقال إلى ClickHouse ، تعمد التخلي عن بعض الفرص التي توفرها DBMSs الأخرى ، وتلقي تعويضات أكثر من قيمتها عن ذلك في شكل استفسارات تحليلية سريعة جدًا ومستودع بيانات مضغوط.
في DBMSs العلائقية ، يتم تخزين القيم المتعلقة بصف واحد فعليًا جنبًا إلى جنب. في ClickHouse ، يتم تخزين القيم من الأعمدة المختلفة بشكل منفصل ، ويتم تخزين البيانات من عمود واحد معًا. يسمح لك ترتيب تخزين البيانات هذا بتوفير درجة عالية من ضغط البيانات مع الاختيار الصحيح للمفتاح الأساسي. كما أنه يؤثر في أي سيناريوهات يعمل نظام DBMS بشكل جيد. يعمل ClickHouse بشكل أفضل مع الاستعلامات ، حيث تتم قراءة عدد صغير من الأعمدة ويستخدم الاستعلام جدولًا كبيرًا واحدًا وبقية الجداول صغيرة. ولكن حتى في الاستعلامات غير التحليلية ، يمكن لـ ClickHouse إظهار نتائج جيدة.
يتم فرز البيانات في الجداول حسب المفتاح الأساسي. يتم إجراء الفرز في الخلفية. هذا يسمح لك بإنشاء فهرس متناثر لحجم صغير ، مما يسمح لك بالعثور على البيانات بسرعة. ClickHouse ليس لديه فهارس ثانوية. بالمعنى الدقيق للكلمة ، يوجد فهرس ثانوي واحد - مفتاح القسم (يقوم ClickHouse بقطع بيانات القسم حيث يتم تحديد مفتاح القسم في الطلب). مزيد من التفاصيل .
مخطط البيانات مع التطبيع لا يعمل ، على العكس من ذلك ، من الأفضل إلغاء تطبيع البيانات اعتمادًا على الطلبات المقدمة إليه. يفضل إنشاء جداول "واسعة" بعدد كبير من الأعمدة. يرتبط هذا العنصر أيضًا بالعنصر السابق ، نظرًا لأن عدم وجود فهارس ثانوية يؤدي أحيانًا إلى نسخ الجداول باستخدام مفتاح أساسي مختلف.
لا يحتوي ClickHouse على UPDATE و DELETE بالمعنى الكلاسيكي ، ولكن هناك إمكانية لمضاهاة.
يجب إدراج البيانات في كتل كبيرة وليس كثيرًا (مرة كل بضع ثوان). يعد تحميل البيانات سطرًا تلو الآخر تقريبًا غير قابل للعمل على أحجام البيانات الحقيقية.
لا يدعم ClickHouse المعاملات ؛ يصبح النظام في النهاية متسقًا .
ومع ذلك ، فإن بعض ميزات ClickHouse ، المشابهة ل DBMSs الأخرى ، تجعل من السهل نقل الأنظمة الموجودة إليها.
- يستخدم ClickHouse SQL ، ولكن مع اختلافات طفيفة ، مفيدة للاستعلامات النموذجية لأنظمة OLAP. هناك نظام قوي من الوظائف المجمعة ، ALL / ANY JOIN ، وتعابير لامدا في الوظائف وامتدادات SQL الأخرى التي تسمح لك بكتابة أي استفسار تحليلي تقريبًا.
- ClickHouse يدعم النسخ المتماثل وتسجيل النصاب وقراءة النصاب. كتابة النصاب ضروري لتخزين بيانات موثوق به: ينجح INSERT فقط إذا كان ClickHouse قادرًا على كتابة البيانات إلى عدد معين من النسخ المتماثلة بدون أخطاء.
يمكنك قراءة المزيد عن ميزات ClickHouse في الوثائق .
ميزات العمل مع ClickHouse
اختيار المفتاح الأساسي ومفتاح التقسيم.
كيفية اختيار مفتاح أساسي ومفتاح قسم؟ ربما هذا هو السؤال الأول الذي ينشأ عند إنشاء جدول جديد. عادةً ما يتم تحديد اختيار المفتاح الأساسي ومفتاح القسم بواسطة الاستعلامات التي سيتم إجراؤها على البيانات. في الوقت نفسه ، تبين أن الاستعلامات التي تستخدم الشرطين هي الأكثر فاعلية: من خلال المفتاح الأساسي ومفتاح القسم.
في حالتنا ، الجداول الرئيسية هي مصفوفات لتشغيل الاختبارات. من المنطقي أن نفترض أنه باستخدام بنية البيانات هذه ، يجب تحديد المفاتيح بحيث يتم ترتيب تجاوز أحدهما بترتيب زيادة رقم الصف ، وترتيب تجاوز الآخر - بترتيب زيادة رقم العمود.
من المهم أيضًا أن تضع في اعتبارك أن اختيار المفتاح الأساسي يمكن أن يؤثر بشكل كبير على ضغط تخزين البيانات ، نظرًا لأن القيم المتطابقة في تجاوز المفتاح الأساسي في الأعمدة الأخرى لا تشغل مساحة تقريبًا في الجدول. لذا في حالتنا ، على سبيل المثال ، تتغير حالات الاختبارات قليلاً من الالتزام بالالتزام. حددت هذه الحقيقة مسبقًا بشكل أساسي اختيار المفتاح الأساسي - زوج من معرف الاختبار ورقم الالتزام. علاوة على ذلك ، في هذا الترتيب.

مفتاح التقسيم له غرضان. من ناحية ، يسمح للأقسام بأن تصبح "مؤرشفة" بحيث يمكن حذفها نهائيًا من التخزين ، حيث أن البيانات الموجودة بها قديمة بالفعل. من ناحية أخرى ، يعد مفتاح القسم فهرسًا ثانويًا ، مما يعني أنه يسمح لك بتسريع الاستعلامات في حالة وجود تعبير لها.
بالنسبة لمصفوفاتنا ، فإن اختيار رقم الالتزام كمفتاح التقسيم يبدو أمرًا طبيعيًا تمامًا. ولكن إذا قمت بتعيين قيمة المراجعة في التعبير لمفتاح القسم ، فسيكون هناك العديد من الأقسام بشكل غير معقول في مثل هذا الجدول ، مما سيؤدي إلى تدهور أداء الاستعلامات إليه. لذلك ، في التعبير عن مفتاح القسم ، يمكن تقسيم قيمة المراجعة إلى عدد كبير لتقليل عدد الأقسام ، على سبيل المثال ، PARTITION BY intDiv (مراجعة ، 2000). يجب أن يكون هذا العدد كبيرًا بما يكفي بحيث لا يتجاوز عدد الأقسام القيم الموصى بها ، في حين يجب أن يكون صغيرًا بما يكفي بحيث لا يقع الكثير من البيانات في قسم واحد ولا يتعين على قاعدة البيانات قراءة الكثير من البيانات.
كيفية تنفيذ التحديث والحذف؟
بالمعنى المعتاد ، لا يتم دعم UPDATE و DELETE في ClickHouse. ومع ذلك ، بدلاً من UPDATE و DELETE ، يمكنك إضافة عمود مع الإصدار إلى الجدول واستخدام محرك ReplacingMergeTree الخاص (يزيل السجلات المكررة بنفس قيمة المفتاح الأساسي). في بعض الحالات ، سيكون الإصدار موجودًا بشكل طبيعي في الجدول منذ البداية: على سبيل المثال ، إذا أردنا إنشاء جدول للحالة الحالية للاختبار ، فسيكون الإصدار في هذا الجدول هو رقم الالتزام.
CREATE TABLE current_tests ( test_id UInt64, value Nullable(String), version UInt64 ) ENGINE = ReplacingMergeTree(version) ORDER BY test_id
في حالة تغيير السجل ، نضيف الإصدار بقيمة جديدة ، في حالة الحذف ، بقيمة فارغة (أو قيمة خاصة أخرى لا يمكن العثور عليها في البيانات).
ماذا حققت مع التخزين الجديد؟
كان أحد الأهداف الرئيسية للتبديل إلى ClickHouse هو القدرة على تخزين سجل الاختبار لفترة طويلة من الزمن (عدة سنوات ، أو على الأقل عام في أسوأ الحالات). بالفعل في مرحلة النموذج الأولي ، أصبح من الواضح أنه يمكننا الالتفاف على محركات الأقراص SSD الموجودة في خوادمنا لتخزين تاريخ ثلاث سنوات على الأقل. تسارعت الاستفسارات التحليلية بشكل ملحوظ ، والآن يمكننا استخراج معلومات أكثر فائدة من بياناتنا. ارتفع هامش RPS. علاوة على ذلك ، يتم قياس هذه القيمة بشكل خطي تقريبًا عن طريق إضافة خوادم جديدة إلى مجموعة ClickHouse. يعد إنشاء مستودع بيانات جديد لقاعدة بيانات ClickHouse مجرد خطوة بالكاد يمكن ملاحظتها للمستخدم النهائي نحو هدف أكثر أهمية - إضافة ميزات جديدة ، وتسريع عملية التطوير وتبسيطها ، وذلك بفضل القدرة على تخزين ومعالجة كميات كبيرة من البيانات.
تعال إلينا
قسمنا يتوسع باستمرار. قم بزيارتنا إذا كنت ترغب في العمل على مهام وخوارزميات معقدة ومثيرة للاهتمام. إذا كان لديك أسئلة ، يمكنك أن تسألني مباشرة في PM.
روابط مفيدة
معالجة دفق
العمارة كابا
كليك هاوس: