ما هي عمليات دمج الأجزاء في ClickHouse؟
يتميّز ClickHouse بالسرعة ليس فقط في الاستعلامات، بل أيضًا في عمليات الإدراج، وذلك بفضل طبقة التخزين التي تعمل بأسلوب مشابه لـ LSM trees: ① تؤدي عمليات الإدراج (في الجداول من عائلة MergeTree engine) إلى إنشاء أجزاء بيانات مرتبة وغير قابلة للتغيير. ② تُنقَل كل معالجة البيانات إلى عمليات دمج الأجزاء في الخلفية. وهذا يجعل عمليات كتابة البيانات خفيفة وعالية الكفاءة. وللتحكم في عدد الأجزاء لكل جدول وتنفيذ ② أعلاه، يدمج ClickHouse باستمرار الأجزاء الأصغر في أجزاء أكبر في الخلفية (ضمن كل partition) إلى أن تصل إلى حجم مضغوط يقارب ~150 GB. يوضح المخطط التالي بإيجاز عملية الدمج في الخلفية:
تزداد قيمة
merge level للجزء بمقدار واحد مع كل عملية دمج إضافية. ويعني المستوى 0 أن الجزء جديد ولم يُدمج بعد. أما الأجزاء التي دُمجت في أجزاء أكبر فتُعلَّم على أنها غير نشطة ثم تُحذف نهائيًا بعد مدة قابلة للتهيئة (8 دقائق افتراضيًا). ومع مرور الوقت، يؤدي ذلك إلى تكوين شجرة من الأجزاء المدمجة. ومن هنا جاءت تسمية جدول MergeTree.
مراقبة عمليات الدمج
/merges، ويمكن استخدامها لتصوير جميع عمليات دمج الأجزاء لجدولنا التجريبي:
تُظهر لوحة المعلومات المسجَّلة أعلاه العملية كاملة، بدءًا من عمليات إدراج البيانات الأولية وصولًا إلى الدمج النهائي في جزء واحد: ① عدد الأجزاء النشطة. ② عمليات دمج الأجزاء، ممثَّلة بصريًا بمربعات (يعكس الحجم حجم الجزء). ③ تضخيم الكتابة.
عمليات دمج متزامنة
ينفّذ كل خيط دمج حلقةً على النحو التالي: ① يحدّد الأجزاء التي ستُدمج بعد ذلك، ويحمّلها إلى الذاكرة. ② يدمج الأجزاء الموجودة في الذاكرة في جزء أكبر. ③ يكتب الجزء المدمج إلى القرص. ثم ارجع إلى ① لاحظ أن زيادة عدد أنوية CPU وحجم RAM تتيح زيادة إنتاجية عمليات الدمج في الخلفية.
عمليات الدمج الموفّرة للذاكرة
آليات الدمج
تُنفَّذ عملية دمج الأجزاء على عدة خطوات: ① فك الضغط والتحميل: تُفك ضغط ملفات الأعمدة الثنائية المضغوطة الخاصة بالأجزاء المراد دمجها وتُحمَّل إلى الذاكرة. ② الدمج: تُدمَج البيانات في ملفات أعمدة أكبر. ③ الفهرسة: يُنشأ فهرس أساسي متناثر جديد لملفات الأعمدة المدمجة. ④ الضغط والتخزين: تُضغط ملفات الأعمدة والفهرس الجديدان ويُحفَظان في دليل جديد يمثل جزء البيانات المدمج. كما يُعاد أيضًا إنشاء البيانات الوصفية الإضافية في أجزاء البيانات، مثل فهارس تخطي البيانات الثانوية، وإحصاءات الأعمدة، والمجاميع الاختبارية، وفهارس الحدين الأدنى والأقصى، استنادًا إلى ملفات الأعمدة المدمجة. وقد أغفلنا هذه التفاصيل للتبسيط. تعتمد آلية الخطوة ② على محرك MergeTree المستخدم، إذ تتعامل المحركات المختلفة مع الدمج بطرق مختلفة. فعلى سبيل المثال، قد تُجمَّع الصفوف أو تُستبدل إذا كانت قديمة. وكما ذكرنا سابقًا، فإن هذا النهج يُسنِد جميع عمليات معالجة البيانات إلى عمليات الدمج في الخلفية، مما يتيح عمليات إدراج فائقة السرعة عبر إبقاء عمليات الكتابة خفيفة وفعّالة. بعد ذلك، سنعرض بإيجاز آليات الدمج في محركات محددة ضمن عائلة MergeTree.
عمليات الدمج القياسية
تنشئ عبارة DDL في المخطط أعلاه جدول
MergeTree بمفتاح فرز (town, street)، ما يعني أن البيانات على القرص تُرتَّب وفقًا لهذه الأعمدة، ويُنشأ تبعًا لذلك فهرس أساسي متناثر.
تُدمَج ② أعمدة الجدول ① المفكوكة الضغط والمرتبة مسبقًا مع الحفاظ على الترتيب العام للفرز في الجدول كما يحدده مفتاح الفرز، ويُنشأ ③ فهرس أساسي متناثر جديد، ثم تُضغط ④ ملفات الأعمدة المدمجة والفهرس وتُخزَّن كجزء بيانات جديد على القرص.
عمليات دمج ReplacingMergeTree
تنشئ عبارة DDL في المخطط أعلاه جدول
ReplacingMergeTree بمفتاح فرز (town, street, id)، ما يعني أن البيانات على القرص تُرتَّب بحسب هذه الأعمدة، ويُنشأ تبعًا لذلك فهرس أساسي متناثر.
وتعمل عملية الدمج ② بطريقة مشابهة لما يحدث في جدول MergeTree قياسي، إذ تجمع الأعمدة المفكوك ضغطها والمفروزة مسبقًا مع الحفاظ على ترتيب الفرز العام.
ومع ذلك، يزيل ReplacingMergeTree الصفوف المكررة التي لها مفتاح الفرز نفسه، ولا يُبقي إلا على أحدث صف استنادًا إلى الطابع الزمني لإنشاء الجزء الذي يحتويه.
عمليات الدمج بالتجميع
تُعرِّف عبارة DDL في المخطط أعلاه جدول
SummingMergeTree بحيث يكون town مفتاح الفرز، ما يعني أن البيانات على القرص تُرتَّب وفقًا لهذا العمود، ويُنشأ تبعًا لذلك فهرس أساسي متناثر.
في خطوة الدمج ②، يستبدل ClickHouse جميع الصفوف التي لها مفتاح الفرز نفسه بصف واحد، مع جمع قيم الأعمدة الرقمية.
عمليات الدمج التجميعية
SummingMergeTree الوارد أعلاه صيغة متخصصة من جدول AggregatingMergeTree، ويتيح التحويل التلقائي التزايدي للبيانات من خلال تطبيق أيٍ من دوال التجميع البالغ عددها [90+] أثناء عمليات دمج الأجزاء:
تُنشئ عبارة DDL في المخطط أعلاه جدول
AggregatingMergeTree مع town بوصفه مفتاح الفرز، مما يضمن ترتيب البيانات حسب هذا العمود على القرص وإنشاء فهرس أساسي متناثر مطابق.
أثناء ② الدمج، يستبدل ClickHouse جميع الصفوف التي لها مفتاح الفرز نفسه بصف واحد يخزّن حالات التجميع الجزئية (مثل sum وcount من أجل avg()). وتضمن هذه الحالات نتائج دقيقة من خلال عمليات الدمج التزايدية في الخلفية.