الانتقال إلى المحتوى الرئيسي
هذه هي النسخة المخصصة للويب من ورقتنا العلمية في VLDB 2024. كما نشرنا مقالة على المدونة عن خلفيتها والمسار الذي سلكته، ونوصي بمشاهدة عرض VLDB 2024 التقديمي الذي يقدمه كبير مسؤولي التكنولوجيا ومبتكر ClickHouse، Alexey Milovidov:

الملخص

على مدى العقود الماضية، ازداد حجم البيانات المخزنة والمحللة ازديادًا أُسّيًا. وبدأت الشركات في مختلف الصناعات والقطاعات تعتمد على هذه البيانات لتحسين المنتجات، وتقييم الأداء، واتخاذ قرارات أعمال حاسمة. ومع ذلك، ومع تضخم أحجام البيانات حتى أصبحت على نطاق الإنترنت، باتت الشركات بحاجة إلى إدارة البيانات التاريخية والجديدة على نحو فعّال من حيث التكلفة وقابل للتوسع، مع تحليلها عبر عدد كبير من الاستعلامات المتزامنة وتوقع أزمنة استجابة آنية (مثلًا أقل من ثانية واحدة، بحسب حالة الاستخدام). تقدم هذه الورقة نظرة عامة على ClickHouse، وهي قاعدة بيانات OLAP شائعة ومفتوحة المصدر، صُممت لتقديم تحليلات عالية الأداء على مجموعات بيانات بحجم بيتابايت مع معدلات استيعاب عالية. تجمع طبقة التخزين فيها بين تنسيق بيانات يستند إلى أشجار الدمج المهيكلة بالسجل (LSM) التقليدية وتقنيات مبتكرة للتحويل المستمر للبيانات التاريخية في الخلفية (مثلًا التجميع والأرشفة). وتُكتب الاستعلامات باستخدام لهجة SQL مناسبة، وتُعالج بواسطة محرك حديث لتنفيذ الاستعلامات المتجهة مع خيار ترجمة الشيفرة. ويستخدم ClickHouse تقنيات الاستبعاد بكثافة لتجنب معالجة البيانات غير ذات الصلة في الاستعلامات. كما يمكن دمج أنظمة أخرى لإدارة البيانات على مستوى دالة الجدول أو محرك الجدول أو محرك قاعدة البيانات. وتُظهر اختبارات الأداء الواقعية أن ClickHouse من بين أسرع قواعد البيانات التحليلية في السوق.

1 المقدمة

تصف هذه الورقة ClickHouse، وهي قاعدة بيانات OLAP عمودية صُممت لتنفيذ الاستعلامات التحليلية عالية الأداء على جداول تضم تريليونات الصفوف ومئات الأعمدة. بدأ تطوير ClickHouse في عام 2009 بوصفه عامل ترشيح وتجميع لبيانات ملفات السجل على نطاق الويب، ثم أُتيح كمصدر مفتوح في عام 2016. ويوضح الشكل 1 متى أُضيفت إلى ClickHouse الميزات الرئيسية الموصوفة في هذه الورقة. صُمم ClickHouse لمعالجة خمسة تحديات رئيسية في إدارة البيانات التحليلية الحديثة:
  1. مجموعات بيانات ضخمة بمعدلات إدخال مرتفعة. تتسم كثير من التطبيقات المعتمدة على البيانات في مجالات مثل تحليلات الويب والتمويل والتجارة الإلكترونية بكميات هائلة ومتزايدة باستمرار من البيانات. وللتعامل مع مجموعات البيانات الضخمة، يجب على قواعد البيانات التحليلية ألا تقتصر على توفير استراتيجيات فعالة للفهرسة والضغط، بل أن تتيح أيضًا توزيع البيانات عبر عقد متعددة (التوسع الأفقي)، لأن الخوادم المنفردة تقتصر سعتها على عدة عشرات من التيرابايتات من التخزين. علاوة على ذلك، تكون البيانات الحديثة غالبًا أكثر أهمية للرؤى الآنية من البيانات التاريخية. ونتيجة لذلك، يجب أن تكون قواعد البيانات التحليلية قادرة على إدخال البيانات الجديدة بمعدلات مرتفعة باستمرار أو على دفعات، وأن تواصل في الوقت نفسه “خفض أولوية” البيانات التاريخية (مثلًا عبر تجميعها أو أرشفتها) من دون إبطاء استعلامات إعداد التقارير المتوازية.
  2. عدد كبير من الاستعلامات المتزامنة مع توقع أزمنة استجابة منخفضة. يمكن عمومًا تصنيف الاستعلامات إلى استعلامات مخصّصة (مثل التحليل الاستكشافي للبيانات) أو استعلامات متكررة (مثل استعلامات لوحات المعلومات الدورية). وكلما كانت حالة الاستخدام أكثر تفاعلية، زاد توقع انخفاض زمن استجابة الاستعلامات، مما يفرض تحديات على تحسين الاستعلامات وتنفيذها. كما تتيح الاستعلامات المتكررة فرصة إضافية لتكييف البنية الفيزيائية لقاعدة البيانات مع عبء العمل. ونتيجة لذلك، ينبغي أن توفر قواعد البيانات تقنيات استبعاد تقلل البيانات غير اللازمة وتساعد على تحسين الاستعلامات المتكررة. وبحسب أولوية الاستعلام، يجب على قواعد البيانات أيضًا أن تمنح وصولًا متساويًا أو ذا أولوية إلى موارد النظام المشتركة مثل وحدة المعالجة المركزية والذاكرة والقرص وإدخال/إخراج الشبكة، حتى عند تشغيل عدد كبير من الاستعلامات في الوقت نفسه.
  3. بيئات متنوعة من مخازن البيانات ومواقع التخزين والتنسيقات. للتكامل مع معماريات البيانات القائمة، ينبغي أن تتمتع قواعد البيانات التحليلية الحديثة بدرجة عالية من الانفتاح تتيح لها قراءة البيانات الخارجية وكتابتها في أي نظام أو موقع أو تنسيق.
  4. لغة استعلام عملية مع دعم لاستقصاء الأداء. يفرض الاستخدام الواقعي لقواعد بيانات OLAP متطلبات “مرنة” إضافية. فعلى سبيل المثال، بدلًا من لغة برمجة متخصصة، يفضّل المستخدمون غالبًا التعامل مع قواعد البيانات عبر لهجة SQL غنية تدعم أنواع البيانات المتداخلة ومجموعة واسعة من الدوال العادية ودوال التجميع ودوال النافذة. وينبغي أيضًا أن توفر قواعد البيانات التحليلية أدوات متقدمة لاستقصاء أداء النظام أو الاستعلامات الفردية.
  5. متانة على مستوى المؤسسات ونشر مرن. نظرًا إلى أن العتاد الشائع غير موثوق، يجب أن توفر قواعد البيانات نسخًا متماثلًا للبيانات للحماية من أعطال العقد. كما ينبغي أن تعمل قواعد البيانات على أي عتاد، من الحواسيب المحمولة القديمة إلى الخوادم القوية. وأخيرًا، لتجنب الأعباء الإضافية الناتجة عن جمع البيانات المهملة في البرامج المعتمدة على JVM وتمكين أداء مباشر على العتاد (مثل SIMD)، فمن المثالي نشر قواعد البيانات على هيئة ملفات تنفيذية أصلية للمنصة المستهدفة.
الشكل 1: الخط الزمني لـ ClickHouse.

الشكل 1: الخط الزمني لـ ClickHouse.

2 البنية المعمارية

الشكل 2: البنية المعمارية عالية المستوى لمحرك قاعدة بيانات ClickHouse.

الشكل 2: البنية المعمارية عالية المستوى لمحرك قاعدة بيانات ClickHouse.

كما يوضّح الشكل 2، ينقسم محرك ClickHouse إلى ثلاث طبقات رئيسية: طبقة معالجة الاستعلامات (الموصوفة في القسم 4)، وطبقة التخزين (القسم 3)، وطبقة التكامل (القسم 5). وإلى جانب ذلك، تدير طبقة الوصول جلسات المستخدم والتواصل مع التطبيقات عبر بروتوكولات مختلفة. وهناك أيضًا مكوّنات مستقلة خاصة بالخيوط، والتخزين المؤقت، والتحكم في الوصول المستند إلى الأدوار، والنسخ الاحتياطية، والمراقبة المستمرة. وقد بُني ClickHouse بلغة C++ على هيئة ملف تنفيذي ثنائي واحد مرتبط ربطًا ساكنًا ومن دون تبعيات. تتبع معالجة الاستعلامات النهج التقليدي المتمثل في تحليل الاستعلامات الواردة، وبناء خطط الاستعلام المنطقية والمادية وتحسينها، ثم تنفيذها. يستخدم ClickHouse نموذج تنفيذ موجّهًا بالمتجهات مشابهًا لـ MonetDB/X100 [11]، بالاقتران مع تجميع انتهازي للشيفرة [53]. ويمكن كتابة الاستعلامات بلهجة SQL غنية بالميزات، أو PRQL [76]، أو KQL الخاصة بـ Kusto [50]. تتكوّن طبقة التخزين من محركات جداول مختلفة تحتضن تنسيق بيانات الجدول وموقعها. وتنقسم محركات الجداول إلى ثلاث فئات: الفئة الأولى هي عائلة محركات الجداول MergeTree* التي تمثل صيغة التخزين الدائم الأساسية في ClickHouse. واستنادًا إلى فكرة أشجار LSM [60]، تُقسَّم الجداول إلى أجزاء أفقية مرتبة، تُدمَج باستمرار بواسطة عملية تعمل في الخلفية. وتختلف محركات الجداول الفردية ضمن MergeTree* في الطريقة التي تدمج بها الصفوف من الأجزاء المُدخلة إليها. فعلى سبيل المثال، يمكن تجميع الصفوف أو استبدالها إذا أصبحت قديمة. أما الفئة الثانية فهي محركات جداول ذات أغراض خاصة، تُستخدم لتسريع تنفيذ الاستعلامات أو توزيعه. وتشمل هذه الفئة محركات جداول مفتاح-قيمة داخل الذاكرة تُسمى القواميس. ويقوم القاموس بتخزين نتيجة استعلام مؤقتًا يُنفَّذ دوريًا على مصدر بيانات داخلي أو خارجي. ويؤدي ذلك إلى خفض كبير في زمن الوصول في السيناريوهات التي يمكن فيها تحمّل قدر من تقادم البيانات. ومن الأمثلة الأخرى على محركات الجداول ذات الأغراض الخاصة محركٌ يعمل بالكامل داخل الذاكرة ويُستخدم للجداول المؤقتة، ومحرك الجداول Distributed لتجزئة البيانات بشفافية (انظر أدناه). أما الفئة الثالثة من محركات الجداول فهي محركات جداول افتراضية لتبادل البيانات ثنائي الاتجاه مع الأنظمة الخارجية مثل قواعد البيانات العلائقية (مثل PostgreSQL وMySQL)، وأنظمة النشر/الاشتراك (مثل Kafka وRabbitMQ [24])، أو مخازن المفتاح/القيمة (مثل Redis). ويمكن للمحركات الافتراضية أيضًا التفاعل مع بحيرات البيانات (مثل Iceberg وDeltaLake وHudi [36]) أو الملفات الموجودة في التخزين الكائني (مثل AWS S3 وGoogle GCP). يدعم ClickHouse التشطير والنسخ المتماثل للجداول عبر عُقد عنقود متعددة لتحقيق قابلية التوسع والتوافر. ويقسّم التشطير الجدول إلى مجموعة من شظايا الجداول وفقًا لتعبير تشطير. وتكون الشظايا الفردية جداول مستقلة عن بعضها بعضًا، وتقع عادةً على عُقد مختلفة. ويمكن للعملاء قراءة الشظايا والكتابة إليها مباشرةً، أي التعامل معها بوصفها جداول منفصلة، أو استخدام محرك الجداول الخاص Distributed، الذي يوفّر عرضًا موحّدًا لجميع شظايا الجدول. والغرض الرئيسي من التشطير هو معالجة مجموعات البيانات التي تتجاوز سعة العُقد الفردية (عادةً بضع عشرات من التيرابايت من البيانات). ومن استخدامات التشطير أيضًا توزيع حمل القراءة والكتابة لجدول ما على عدة عُقد، أي موازنة الحمل. وبشكل مستقل عن ذلك، يمكن نسخ الشظية متماثلًا عبر عدة عُقد لتحمّل أعطال العُقد. ولهذه الغاية، يقابل كل محرك جداول Merge-Tree* محركٌ من نوع ReplicatedMergeTree* يستخدم مخطط تنسيق متعدد القادة يعتمد على توافق Raft [59] (ويُنفَّذ بواسطة Keeper، وهو بديل يمكن إحلاله مباشرةً محل Apache Zookeeper ومكتوب بلغة C++) لضمان أن يكون لكل شظية، في جميع الأوقات، عدد قابل للضبط من النسخ المتماثلة. ويناقش القسم 3.6 آلية النسخ المتماثل بالتفصيل. وعلى سبيل المثال، يوضّح الشكل 2 جدولًا يحتوي على شظيتين، نُسخت كل منهما متماثلًا إلى عُقدتين. وأخيرًا، يمكن تشغيل محرك قاعدة بيانات ClickHouse في أوضاع on-premise والسحابة والمستقل وداخل العملية. ففي وضع on-premise، يُعِدّ المستخدمون ClickHouse محليًا بوصفه خادمًا واحدًا أو عنقودًا متعدد العُقد مع التشطير و/أو النسخ المتماثل. وتتواصل التطبيقات العميلة مع قاعدة البيانات عبر البروتوكول الثنائي الأصلي، أو بروتوكولَي MySQL وPostgreSQL الثنائيين، أو عبر واجهة HTTP REST API. ويمثّل الوضع السحابي خدمة ClickHouse Cloud، وهي خدمة DBaaS مُدارة بالكامل وتدعم التوسّع التلقائي. ومع أن هذه الورقة تركّز على وضع on-premise، فإننا نخطط لوصف معمارية ClickHouse Cloud في منشور لاحق. ويحوّل الوضع المستقل ClickHouse إلى أداة سطر أوامر لتحليل الملفات وتحويلها، ما يجعله بديلًا قائمًا على SQL لأدوات Unix مثل cat وgrep. ومع أن هذا لا يتطلب أي إعداد مسبق، فإن الوضع المستقل يقتصر على خادم واحد. ومؤخرًا، جرى تطوير وضع داخل العملية يُسمى chDB [15] لحالات استخدام تحليل البيانات التفاعلي مثل Jupyter notebooks [37] مع إطارات بيانات Pandas [61]. واستلهامًا من DuckDB [67]، يضمّن chDB ClickHouse كمحرك OLAP عالي الأداء داخل عملية مضيفة. وبالمقارنة مع الأوضاع الأخرى، يتيح ذلك تمرير بيانات المصدر والنتائج بين محرك قاعدة البيانات والتطبيق بكفاءة ومن دون نسخ، إذ إنهما يعملان ضمن فضاء العناوين نفسه.

3 طبقة التخزين

يناقش هذا القسم محركات الجداول من نوع MergeTree* باعتبارها صيغة التخزين الأصلية في ClickHouse. كما نصف تمثيلها على القرص، ونستعرض ثلاث تقنيات لاستبعاد البيانات في ClickHouse. بعد ذلك، نعرض استراتيجيات الدمج التي تحول البيانات باستمرار من دون التأثير في عمليات الإدراج المتزامنة. وأخيرًا، نشرح كيفية تنفيذ التحديثات وعمليات الحذف، وكذلك إزالة البيانات المكررة، والنسخ المتماثل للبيانات، والامتثال لخصائص ACID.

3.1 التنسيق على القرص

يُنظَّم كل جدول يستخدم محرك الجداول MergeTree* على هيئة مجموعة من أجزاء جدول غير قابلة للتغيير. ويُنشأ جزء جديد كلما أُدرجت مجموعة من الصفوف في الجدول. وتُعد هذه الأجزاء مكتفية ذاتيًا، بمعنى أنها تتضمن جميع البيانات الوصفية اللازمة لتفسير محتواها من دون الحاجة إلى عمليات lookup إضافية في catalog مركزي. وللحفاظ على انخفاض عدد الأجزاء في كل جدول، تعمل مهمة دمج في الخلفية دوريًا على دمج عدة أجزاء صغيرة في جزء أكبر إلى أن يبلغ حجم الجزء قيمة قابلة للتهيئة (150 غيغابايت افتراضيًا). ونظرًا إلى أن الأجزاء تكون sorted وفق أعمدة المفتاح الأساسي الخاصة بالجدول (انظر القسم 3.2))، تُستخدم خوارزمية فرز الدمج متعدد الاتجاهات بكفاءة [40] في عملية الدمج. وتُعلَّم الأجزاء المصدر على أنها غير نشطة، ثم تُحذف لاحقًا بمجرد أن ينخفض عدد مراجعها إلى الصفر، أي عندما لا تعود أي queries تقرأ منها. يمكن إدراج الصفوف في وضعين: في وضع الإدراج المتزامن، تُنشئ كل عبارة INSERT جزءًا جديدًا وتُلحقه بالجدول. ولتقليل overhead الناتج عن عمليات الدمج، يُنصح clients قواعد البيانات بإدراج Tuples على دفعات كبيرة، مثل 20,000 صف دفعة واحدة. لكن التأخيرات الناتجة عن client-side batching تكون غالبًا غير مقبولة إذا كان من المطلوب تحليل البيانات في الوقت الفعلي. فعلى سبيل المثال، تتضمن حالات استخدام observability كثيرًا آلافًا من وكلاء Monitoring الذين يرسلون باستمرار كميات صغيرة من بيانات الأحداث وmetrics. ويمكن لمثل هذه السيناريوهات الاستفادة من وضع الإدراج غير المتزامن، حيث يخزّن ClickHouse الصفوف مؤقتًا من عدة عمليات INSERT واردة إلى الجدول نفسه، ولا يُنشئ جزءًا جديدًا إلا بعد أن يتجاوز حجم buffer حدًا قابلًا للتهيئة أو تنقضي مهلة timeout.
الشكل 3: عمليات الإدراج والدمج لجداول محرك MergeTree*-engine.

الشكل 3: عمليات الإدراج والدمج لجداول محرك MergeTree*.

يوضح الشكل 3 أربع عمليات إدراج متزامنة وعمليتي إدراج غير متزامنتين في جدول يستخدم محرك MergeTree*. وقد خفّضت عمليتا دمج عدد active parts من خمسة في البداية إلى جزأين. وبالمقارنة مع أشجار LSM [58] وتطبيقاتها في قواعد بيانات مختلفة [13, 26, 56]، يتعامل ClickHouse مع جميع الأجزاء على قدم المساواة بدلًا من تنظيمها ضمن بنية هرمية. ونتيجة لذلك، لم تعد عمليات الدمج مقتصرة على الأجزاء الموجودة في المستوى نفسه. وبما أن ذلك يستغني أيضًا عن الترتيب الزمني الضمني للأجزاء، فثمة حاجة إلى آليات بديلة للتحديثات وعمليات الحذف لا تعتمد على tombstones (انظر القسم 3.4)). ويكتب ClickHouse عمليات الإدراج مباشرة إلى disk، بينما تستخدم المخازن الأخرى القائمة على أشجار LSM عادةً write-ahead logging (انظر القسم 3.7)). يقابل الجزء دليلاً على القرص، ويحتوي على ملف واحد لكل عمود. وكإجراء تحسين، تُخزَّن أعمدة الجزء الصغير (الأصغر من 10 ميغابايت افتراضياً) بشكل متتابع في ملف واحد لزيادة التجاور المكاني لعمليات القراءة والكتابة. كما تُقسَّم صفوف الجزء منطقياً إلى مجموعات من 8192 سجلاً، تُسمى حبيبات. وتمثل الحبيبة أصغر وحدة بيانات غير قابلة للتجزئة تعالجها عمليتا المسح والبحث في الفهرس في ClickHouse. ومع ذلك، لا تُجرى قراءات البيانات على القرص وكتابتها على مستوى الحبيبة، بل على مستوى الكتل، التي تجمع عدة حبيبات متجاورة داخل العمود. وتُشكَّل الكتل الجديدة استناداً إلى حجم بايتات قابل للضبط لكل كتلة (1 ميغابايت افتراضياً)، أي إن عدد الحبيبات في الكتلة متغير ويعتمد على نوع بيانات العمود وتوزيعها. وتُضغط الكتل كذلك لتقليل حجمها وتكاليف I/O المرتبطة بها. ويستخدم ClickHouse افتراضياً خوارزمية الضغط LZ4 [75] بوصفها خوارزمية عامة الغرض، لكن يمكن للمستخدمين أيضاً تحديد codecs متخصصة مثل Gorilla [63] أو FPC [12] للبيانات ذات الفاصلة العائمة. ويمكن أيضاً تسلسل خوارزميات الضغط. فعلى سبيل المثال، يمكن أولاً تقليل التكرار المنطقي في القيم الرقمية باستخدام ترميز delta [23]، ثم إجراء ضغط قوي، وأخيراً تشفير البيانات باستخدام codec من نوع AES. وتُفك ضغط الكتل آنيّاً عند تحميلها من القرص إلى الذاكرة. ولتمكين الوصول العشوائي السريع إلى الحبيبات الفردية رغم الضغط، يخزن ClickHouse أيضاً لكل عمود تعييناً يربط كل معرّف حبيبة بإزاحة الكتلة المضغوطة التي تحتويها في ملف العمود، وبإزاحة الحبيبة داخل الكتلة غير المضغوطة. ويمكن كذلك ترميز الأعمدة باستخدام القاموس [2, 77, 81] أو جعلها قابلةً لاحتواء NULL باستخدام نوعي بيانات مغلفين خاصين: يستبدل LowCardinality(T) قيم العمود الأصلية بمعرّفات صحيحة، وبذلك يقلل بشكل كبير من العبء التخزيني الإضافي للبيانات التي تحتوي على عدد قليل من القيم الفريدة. ويضيف Nullable(T) خريطة بتات داخلية إلى العمود T، تمثل ما إذا كانت قيم العمود NULL أم لا. وأخيراً، يمكن تقسيم الجداول بحسب النطاق أو التجزئة أو بأسلوب round-robin باستخدام تعبيرات partitioning اعتباطية. ولتمكين partition pruning، يخزن ClickHouse أيضاً القيمتين الدنيا والعظمى لتعبير partitioning لكل partition. ويمكن للمستخدمين اختيارياً إنشاء column statistics أكثر تقدماً (مثل إحصاءات HyperLogLog [30] أو t-digest [28]) التي توفر أيضاً تقديرات cardinality.

3.2 استبعاد البيانات

في معظم حالات الاستخدام، يكون مسح بيتابايتات من البيانات لمجرد الإجابة عن استعلام واحد بطيئًا ومكلفًا للغاية. يدعم ClickHouse ثلاث تقنيات لاستبعاد البيانات تتيح تخطي غالبية الصفوف أثناء البحث، وبالتالي تُسرّع الاستعلامات بشكل كبير. أولًا، يمكن للمستخدمين تعريف فهرس مفتاح أساسي لجدول. تحدد أعمدة المفتاح الأساسي ترتيب فرز الصفوف داخل كل جزء، أي إن الفهرس يكون مُجمَّعًا محليًا. ويخزن ClickHouse أيضًا، لكل جزء، تعيينًا يربط بين قيم أعمدة المفتاح الأساسي للصف الأول في كل حبيبة ومعرّف تلك الحبيبة، أي إن الفهرس متناثر [31]. ويكون هيكل البيانات الناتج صغيرًا عادةً بما يكفي ليبقى بالكامل في الذاكرة، فعلى سبيل المثال لا يلزم سوى 1000 مُدخل لفهرسة 8.1 مليون صف. والغرض الرئيسي من المفتاح الأساسي هو تقييم شروط المساواة والمدى للأعمدة التي يُجرى عليها التصفية كثيرًا باستخدام البحث الثنائي بدلًا من المسح المتسلسل (القسم 4.4). ويمكن كذلك الاستفادة من الفرز المحلي في دمج الأجزاء وتحسين الاستعلامات، مثل التجميع القائم على الفرز أو إزالة عوامل الفرز من خطة التنفيذ الفيزيائية عندما تشكّل أعمدة المفتاح الأساسي بادئة لأعمدة الفرز. يوضح الشكل 4 فهرس مفتاح أساسي على العمود EventTime لجدول يحتوي على إحصاءات مرات ظهور الصفحات. ويمكن العثور على الحبيبات التي تطابق شرط المدى في الاستعلام عبر البحث الثنائي في فهرس المفتاح الأساسي بدلًا من مسح EventTime تسلسليًا.
الشكل 4: تقييم المرشحات باستخدام فهرس مفتاح أساسي.

الشكل 4: تقييم المرشحات باستخدام فهرس مفتاح أساسي.

ثانيًا، يمكن للمستخدمين إنشاء إسقاطات للجداول، أي نسخ بديلة من الجدول تحتوي على الصفوف نفسها لكنها مرتبة وفق مفتاح أساسي مختلف [71]. تتيح الإسقاطات تسريع الاستعلامات التي تُصفّي بحسب أعمدة تختلف عن المفتاح الأساسي للجدول الرئيسي، وذلك مقابل زيادة العبء على عمليات الإدراج والدمج واستهلاك المساحة. وبشكل افتراضي، لا تُملأ الإسقاطات إلا تدريجيًا من الأجزاء المُدرجة حديثًا في الجدول الرئيسي، وليس من الأجزاء الموجودة مسبقًا، ما لم يقم المستخدم بتطبيق الإسقاط ماديًا بالكامل. ويختار مُحسّن الاستعلامات بين القراءة من الجدول الرئيسي أو من إسقاط بالاستناد إلى تكاليف IO المقدّرة. وإذا لم يوجد إسقاط لجزء ما، فإن تنفيذ الاستعلام يعود إلى جزء الجدول الرئيسي المقابل. ثالثًا، توفّر فهارس التخطي بديلًا خفيفًا للإسقاطات. وتقوم فكرة فهارس التخطي على تخزين كميات صغيرة من البيانات الوصفية على مستوى عدة حبيبات متتالية، بما يتيح تجنب مسح الصفوف غير ذات الصلة. ويمكن إنشاء فهارس التخطي لأي تعبيرات فهرسة، مع استخدام حبيبية قابلة للضبط، أي عدد الحبيبات في كتلة فهرس التخطي. وتشمل أنواع فهارس التخطي المتاحة ما يلي: 1. فهارس الحدين الأدنى والأقصى [51]، التي تخزن القيم الدنيا والعظمى لتعبير الفهرسة لكل كتلة فهرس. ويعمل هذا النوع من الفهارس جيدًا مع البيانات المُجمَّعة محليًا ذات المجالات المطلقة الصغيرة، مثل البيانات المرتبة ترتيبًا تقريبيًا. 2. فهارس Set، التي تخزن عددًا قابلًا للضبط من القيم الفريدة لكتلة الفهرس. وتُستخدم هذه الفهارس على أفضل وجه مع البيانات ذات عدد قليل من القيم المميزة محليًا، أي القيم “المتكتلة معًا”. 3. فهارس bloom filter [9] المخصّصة لقيم الصفوف أو الرموز أو n-gram مع معدل موجب كاذب قابل للضبط. تدعم هذه الفهارس البحث النصي [73]، لكنها، بخلاف فهارس الحدين الأدنى والأقصى وفهارس Set، لا يمكن استخدامها مع شروط المدى أو الشروط السالبة.

3.3 تحويل البيانات أثناء الدمج

غالبًا ما تتطلب حالات استخدام ذكاء الأعمال وObservability التعامل مع بيانات تُولَّد باستمرار بمعدلات مرتفعة أو على شكل دفعات مفاجئة. كما أن البيانات المُولَّدة حديثًا تكون عادةً أكثر أهمية لاستخلاص رؤى آنية مفيدة من البيانات التاريخية. وتتطلب مثل هذه الحالات أن تحافظ قواعد البيانات على معدلات عالية من إدخال البيانات، مع تقليل حجم البيانات التاريخية باستمرار باستخدام تقنيات مثل التجميع أو تقادم البيانات. يتيح ClickHouse تحويلًا تزايديًا مستمرًا للبيانات الموجودة باستخدام استراتيجيات دمج مختلفة. ولا يؤثر تحويل البيانات أثناء الدمج في أداء عبارات INSERT، لكنه لا يضمن خلو الجداول دائمًا من القيم غير المرغوب فيها (مثل القيم القديمة أو غير المجمّعة). وعند الحاجة، يمكن تطبيق جميع التحويلات التي تتم أثناء الدمج عند وقت الاستعلام عبر تحديد الكلمة المفتاحية FINAL في عبارات SELECT. تحتفظ عمليات الدمج الاستبدالية فقط بأحدث إصدار مُدرَج من tuple استنادًا إلى الطابع الزمني لإنشاء الجزء الذي يحتويه، بينما تُحذف الإصدارات الأقدم. وتُعدّ الـ tuples متكافئة إذا كانت لها القيم نفسها في أعمدة المفتاح الأساسي. وللتحكم الصريح في tuple الذي سيُحتفَظ به، يمكن أيضًا تحديد عمود إصدار خاص للمقارنة. وتُستخدم عمليات الدمج الاستبدالية عادةً كآلية تحديث أثناء الدمج (عادةً في حالات الاستخدام التي تكثر فيها التحديثات)، أو كبديل لإزالة تكرار البيانات وقت الإدراج (القسم 3.5)). تدمج عمليات الدمج التجميعية الصفوف التي لها القيم نفسها في أعمدة المفتاح الأساسي في صف مجمّع واحد. ويجب أن تكون الأعمدة غير التابعة للمفتاح الأساسي من نوع حالة تجميع جزئية تحتفظ بالقيم المُلخَّصة. وتُدمج حالتا تجميع جزئيتان، مثل sum وcount من أجل avg()، في حالة تجميع جزئية جديدة. وتُستخدم عمليات الدمج التجميعية عادةً في العروض المادية بدلًا من الجداول العادية. وتُملأ العروض المادية استنادًا إلى استعلام تحويل على الجدول المصدر. وعلى خلاف قواعد البيانات الأخرى، لا يحدّث ClickHouse العروض المادية دوريًا بمحتوى الجدول المصدر بالكامل. بل تُحدَّث العروض المادية تزايديًا بنتيجة استعلام التحويل عند إدراج جزء جديد في الجدول المصدر. يوضح الشكل 5 عرضًا ماديًا مُعرَّفًا على جدول يحتوي على إحصاءات مرات ظهور الصفحات. وبالنسبة إلى الأجزاء الجديدة المُدرَجة في الجدول المصدر، يحسب استعلام التحويل أقصى زمن استجابة ومتوسطه، مع التجميع حسب المنطقة، ثم يُدرج النتيجة في عرض مادي. وتُرجع دوال التجميع avg() وmax() مع اللاحقة -State حالات تجميع جزئية بدلًا من النتائج الفعلية. وتعمل عملية دمج تجميعية مُعرَّفة للعرض المادي على دمج حالات التجميع الجزئية باستمرار عبر الأجزاء المختلفة. وللحصول على النتيجة النهائية، يدمج المستخدمون حالات التجميع الجزئية في العرض المادي باستخدام avg() وmax()) مع اللاحقة -Merge.
الشكل 5: عمليات الدمج التجميعية في العروض المادية.

الشكل 5: عمليات الدمج التجميعية في العروض المادية.

توفر عمليات دمج TTL (time-to-live) آلية تقادم للبيانات التاريخية. وعلى خلاف عمليات الدمج الحاذفة والتجميعية، تعالج عمليات دمج TTL جزءًا واحدًا فقط في كل مرة. وتُعرَّف عمليات دمج TTL على هيئة قواعد تتضمن مُشغِّلات وإجراءات. والمُشغِّل هو تعبير يحسب طابعًا زمنيًا لكل صف، ثم يُقارَن بالوقت الذي تُنفَّذ فيه عملية دمج TTL. وبينما يتيح ذلك للمستخدمين التحكم في الإجراءات على مستوى الصف، وجدنا أن الاكتفاء بالتحقق مما إذا كانت جميع الصفوف تستوفي شرطًا معينًا وتنفيذ الإجراء على الجزء بأكمله أمرٌ كافٍ. وتشمل الإجراءات الممكنة: 1. نقل الجزء إلى وحدة تخزين أخرى (مثل تخزين أرخص وأبطأ)، 2. إعادة ضغط الجزء (مثل استخدام codec أكبر كلفة)، 3. حذف الجزء، و4. التلخيص، أي تجميع الصفوف باستخدام مفتاح تجميع ودوال تجميع. كمثال، انظر إلى تعريف جدول السجلات في القائمة 1. سينقل ClickHouse الأجزاء التي تكون قيم عمود الطابع الزمني فيها أقدم من أسبوع واحد إلى S3 object storage البطيء لكنه منخفض التكلفة.
القائمة 1: نقل الجزء إلى تخزين الكائنات بعد أسبوع واحد.

3.4 التحديثات وعمليات الحذف

يراعي تصميم محركات الجداول من فئة MergeTree* أعباء العمل القائمة على الإلحاق فقط، ومع ذلك تتطلب بعض حالات الاستخدام تعديل البيانات الموجودة أحيانًا، على سبيل المثال لتلبية متطلبات الامتثال التنظيمي. توجد طريقتان لتحديث البيانات أو حذفها، ولا تحظر أيٌّ منهما عمليات الإدراج المتوازية. تُعيد Mutations كتابة جميع الأجزاء في الجدول في موضعها. ولتفادي تضاعف حجم الجدول (عند الحذف) أو العمود (عند التحديث) مؤقتًا، تكون هذه العملية غير ذرّية؛ أي قد تقرأ عبارات SELECT المتوازية أجزاءً خضعت للـ mutation وأجزاءً لم تخضع لها. وتضمن Mutations أن تتغير البيانات فعليًا عند اكتمال العملية. ولا تزال Delete mutations مكلفة لأنها تعيد كتابة جميع الأعمدة في كل الأجزاء. وكبديل لذلك، لا تُحدِّث lightweight deletes سوى عمود bitmap داخلي يحدد ما إذا كان الصف محذوفًا أم لا. ويضيف ClickHouse إلى استعلامات SELECT عامل تصفية إضافيًا على عمود bitmap لاستبعاد الصفوف المحذوفة من النتيجة. ولا تُزال الصفوف المحذوفة فعليًا إلا عبر عمليات الدمج العادية في وقت غير محدد لاحقًا. وبحسب عدد الأعمدة، قد تكون lightweight deletes أسرع بكثير من Mutations، لكن ذلك يكون على حساب بطء استعلامات SELECT. من المتوقع أن تكون عمليات التحديث والحذف على الجدول نفسه نادرة، وأن تُنفَّذ بشكل متسلسل لتجنب التعارضات المنطقية.

3.5 عمليات الإدراج عديمة الأثر عند التكرار

من المشكلات الشائعة عمليًا كيفية تعامل العملاء مع حالات مهلة الاتصال بعد إرسال البيانات إلى الخادم لإدراجها في جدول. في هذه الحالة، يصعب على العملاء التمييز بين ما إذا كانت البيانات قد أُدرجت بنجاح أم لا. ويُحل هذا الإشكال تقليديًا بإعادة إرسال البيانات من العميل إلى الخادم والاعتماد على المفتاح الأساسي أو قيود التفرد لرفض عمليات الإدراج المكررة. وتنفذ قواعد البيانات عمليات البحث النقطية المطلوبة بسرعة باستخدام بُنى فهرسة تعتمد على الأشجار الثنائية [39, 68]، أو أشجار radix [45]، أو جداول hash [29]. وبما أن بُنى البيانات هذه تفهرس كل Tuple، فإن كلفة المساحة والتحديث تصبح باهظة مع مجموعات البيانات الكبيرة ومعدلات الإدخال المرتفعة. يوفر ClickHouse بديلًا أخف وزنًا يستند إلى حقيقة أن كل عملية إدراج تُنشئ في النهاية جزءًا. وبصورة أدق، يحتفظ الخادم بقيم hash لآخر N من الأجزاء المُدرجة (مثلًا N=100)، ويتجاهل إعادة إدراج الأجزاء ذات الـ hash المعروف. وتُخزَّن قيم hash الخاصة بالجداول غير المكررة والجداول المكررة محليًا، وفي Keeper على الترتيب. ونتيجة لذلك، تصبح عمليات الإدراج عديمة الأثر عند التكرار، أي يمكن للعملاء ببساطة إعادة إرسال الدفعة نفسها من الصفوف بعد حدوث timeout وافتراض أن الخادم سيتولى إزالة التكرار. ولمزيد من التحكم في عملية إزالة التكرار، يمكن للعملاء اختياريًا توفير token لعملية الإدراج يعمل بوصفه hash للجزء. ومع أن إزالة التكرار المعتمدة على hash تضيف كلفة مرتبطة بحساب hash للصفوف الجديدة، فإن تكلفة تخزين قيم hash هذه ومقارنتها تُعد مهملة.

3.6 النسخ المتماثل للبيانات

يُعدّ النسخ المتماثل متطلبًا أساسيًا لتحقيق التوافر العالي (القدرة على تحمّل أعطال العُقد)، كما يُستخدم أيضًا لموازنة الحمل وإجراء الترقيات من دون توقّف [14]. في ClickHouse، يقوم النسخ المتماثل على مفهوم حالات الجدول، التي تتكوّن من مجموعة من أجزاء الجدول (القسم 3.1)) والبيانات الوصفية للجدول، مثل أسماء الأعمدة والأنواع. وتتقدّم العُقد بحالة الجدول عبر ثلاث عمليات: 1. تضيف عمليات insert جزءًا جديدًا إلى الحالة، 2. تضيف عمليات الدمج جزءًا جديدًا وتحذف أجزاءً موجودة من الحالة، 3. وتضيف عمليات mutation وعبارات DDL أجزاءً، و/أو تحذف أجزاءً، و/أو تغيّر البيانات الوصفية للجدول، بحسب العملية المحددة. وتُنفَّذ هذه العمليات محليًا على عُقدة واحدة، ثم تُسجَّل كتسلسل من انتقالات الحالة في سجل نسخ متماثل عام. ويُحفَظ سجل النسخ المتماثل بواسطة مجموعة تتكوّن عادةً من ثلاث عمليات ClickHouse Keeper تستخدم خوارزمية توافق Raft [59] لتوفير طبقة coordination موزعة وقادرة على تحمّل الأعطال لعنقود من عُقد ClickHouse. وتشير جميع عُقد العنقود في البداية إلى الموضع نفسه في سجل النسخ المتماثل. وبينما تنفّذ العُقد محليًا عمليات insert والدمج وعمليات mutation وعبارات DDL، يُعاد تطبيق سجل النسخ المتماثل بشكل Asynchronous على جميع العُقد الأخرى. ونتيجةً لذلك، لا تكون الجداول المكررة متسقة إلا بمرور الوقت، أي قد تقرأ العُقد مؤقتًا حالات قديمة للجدول ريثما تتقارب نحو أحدث حالة. ويمكن بدلًا من ذلك تنفيذ معظم العمليات المذكورة آنفًا بشكل متزامن إلى أن تعتمد quorum من العُقد (مثل أغلبية العُقد أو جميع العُقد) الحالة الجديدة. على سبيل المثال، يوضّح الشكل 6 جدولًا مكررًا فارغًا في البداية ضمن عنقود من ثلاث عُقد ClickHouse. تستقبل العُقدة 1 أولًا عبارتي insert وتُسجّلهما ( 1 2 ) في سجل النسخ المتماثل المخزَّن في Keeper ensemble. بعد ذلك، تعيد العُقدة 2 تطبيق مُدخل السجل الأول عبر fetch له ( 3 ) وتنزيل الجزء الجديد من العُقدة 1 ( 4 )، بينما تعيد العُقدة 3 تطبيق مُدخلي السجل كليهما ( 3 4 5 6 ). وأخيرًا، تدمج العُقدة 3 الجزأين في جزء جديد، وتحذف جزأي الإدخال، وتُسجّل مُدخل merge في سجل النسخ المتماثل ( 7 ).
الشكل 6: النسخ المتماثل في عنقود من ثلاث عُقد.

الشكل 6: النسخ المتماثل في عنقود من ثلاث عُقد.

توجد ثلاثة تحسينات لتسريع المزامنة: أولًا، لا تعيد العُقد الجديدة المضافة إلى العنقود تطبيق سجل النسخ المتماثل من الصفر، بل تنسخ ببساطة حالة العُقدة التي كتبت آخر مُدخل في سجل النسخ المتماثل. ثانيًا، يُعاد تطبيق عمليات الدمج إما بتكرارها محليًا أو عبر fetch للجزء الناتج من عُقدة أخرى. ويمكن تهيئة هذا السلوك بدقة بما يتيح الموازنة بين استهلاك CPU وعمليات I/O على الشبكة. فعلى سبيل المثال، يفضّل النسخ المتماثل عبر مراكز البيانات عادةً عمليات الدمج المحلية لتقليل تكاليف التشغيل. ثالثًا، تعيد العُقد تطبيق مُدخلات سجل النسخ المتماثل المستقلة عن بعضها بعضًا بالتوازي. ويشمل ذلك، على سبيل المثال، عمليات fetch للأجزاء الجديدة المُدرجة تباعًا في الجدول نفسه، أو العمليات على جداول مختلفة.

3.7 الامتثال لـ ACID

لزيادة أداء عمليات القراءة والكتابة المتزامنة إلى أقصى حد، يتجنب ClickHouse استخدام الأقفال قدر الإمكان. تُنفَّذ الاستعلامات على لقطة تضم جميع الأجزاء في كل الجداول المعنية، وتُنشأ عند بداية الاستعلام. ويضمن ذلك ألّا تشارك الأجزاء الجديدة التي أُدرجت بواسطة عمليات INSERT المتوازية أو عمليات الدمج (القسم 3.1) في التنفيذ. ولمنع تعديل الأجزاء أو حذفها في الوقت نفسه (القسم 3.4)، تتم زيادة العدّ المرجعي للأجزاء المُعالَجة طوال مدة الاستعلام. ومن الناحية الشكلية، يقابل ذلك snapshot isolation مُنفَّذًا عبر أحد أشكال MVCC [6] القائم على الأجزاء ذات الإصدارات. ونتيجة لذلك، فإن تعليمات SQL لا تكون عمومًا متوافقة مع ACID إلا في الحالة النادرة التي تؤثر فيها عمليات الكتابة المتزامنة وقت أخذ اللقطة على جزء واحد فقط لكل منها. عمليًا، فإن معظم حالات الاستخدام في ClickHouse التي تتطلب كثافة عالية في الكتابة لأغراض اتخاذ القرار تتسامح حتى مع احتمال ضئيل لفقدان البيانات الجديدة في حال انقطاع الكهرباء. وتستفيد قاعدة البيانات من ذلك بعدم فرض تنفيذ commit ‏(fsync) افتراضيًا على الأجزاء المُدرجة حديثًا على القرص، مما يتيح للنواة تجميع عمليات الكتابة على دفعات مقابل التخلي عن الذرّية.

4 طبقة معالجة الاستعلامات

الشكل 7: التوازي عبر وحدات SIMD والأنوية والعُقد.

الشكل 7: التوازي عبر وحدات SIMD والأنوية والعُقد.

كما هو موضح في الشكل 7، يوفّر ClickHouse موازاة للاستعلامات على مستوى عناصر البيانات ودفعات البيانات وأجزاء الجدول. ويمكن معالجة عدة عناصر بيانات داخل المعاملات في الوقت نفسه باستخدام تعليمات SIMD. وعلى عقدة واحدة، ينفّذ محرك الاستعلام المعاملات بالتزامن عبر عدة خيوط تنفيذ. يستخدم ClickHouse نموذج التوجيه المتجهي نفسه الذي يستخدمه MonetDB/X100 [11]، أي إن المعاملات تُنتج وتمرّر وتستهلك عدة rows (دفعات بيانات) بدلًا من row واحدة لتقليل العبء الإضافي الناتج عن استدعاءات الدوال الافتراضية. وإذا كان الجدول المصدر مقسّمًا إلى أجزاء جدول منفصلة، يمكن لعدة عُقد فحص هذه الأجزاء في الوقت نفسه. ونتيجةً لذلك، تُستغل جميع موارد العتاد استغلالًا كاملًا، ويمكن توسيع معالجة الاستعلامات أفقيًا بإضافة عُقد وعموديًا بإضافة أنوية. يشرح ما تبقى من هذا القسم أولًا المعالجة المتوازية بمزيد من التفصيل على مستوى عناصر البيانات ودفعات البيانات والأجزاء. ثم نعرض مجموعة مختارة من التحسينات الأساسية لزيادة أداء الاستعلامات إلى أقصى حد. وأخيرًا، نناقش كيف يدير ClickHouse موارد النظام المشتركة في ظل وجود استعلامات متزامنة.

4.1 موازاة SIMD

إن تمرير عدة صفوف بين المشغّلات يهيئ فرصةً للمعالجة المتجهية. وتعتمد المعالجة المتجهية إما على الدوال الجوهرية المكتوبة يدويًا [64, 80] أو على المتجهة التلقائية من المصرّف [25]. وتُصرَّف الشيفرة التي تستفيد من المعالجة المتجهية إلى نوى معالجة مختلفة. فعلى سبيل المثال، يمكن تنفيذ الحلقة الداخلية الأكثر كثافةً في التنفيذ ضمن أحد مشغّلات الاستعلام باستخدام نواة غير متجهية، ونواة AVX2 متجهية تلقائيًا، ونواة AVX-512 متجهية يدويًا. وتُختار أسرع نواة وقت التشغيل استنادًا إلى تعليمة cpuid. ويتيح هذا النهج لـ ClickHouse العمل على أنظمة يعود عمرها إلى 15 عامًا (مع اشتراط SSE 4.2 كحد أدنى)، مع الاستمرار في توفير زيادات كبيرة في السرعة على العتاد الحديث.

4.2 التوازي متعدد الأنوية

الشكل 8: مخطط تنفيذ فعلي يتضمن ثلاثة مسارات تنفيذ.

الشكل 8: مخطط تنفيذ فعلي يتضمن ثلاثة مسارات تنفيذ.

يتبع ClickHouse النهج التقليدي [31] القائم على تحويل استعلامات SQL إلى رسم بياني موجّه لمعاملات الخطة الفعلية. ويُمثَّل دخل خطة المعاملات بواسطة معاملات source خاصة تقرأ البيانات بالتنسيق native أو بأي من تنسيقات الجهات الخارجية المدعومة (راجع القسم 5)). وبالمثل، يحوّل معامل sink خاص النتيجة إلى output format المطلوب. وتُفكَّك خطة المعاملات الفعلية وقت ترجمة query إلى مسارات تنفيذ مستقلة استنادًا إلى حد أقصى قابل للضبط لعدد worker threads (ويكون افتراضيًا عدد الأنوية) وإلى حجم الجدول المصدر. وتقسّم مسارات التنفيذ البيانات المطلوب معالجتها بواسطة المعاملات المتوازية إلى ranges غير متداخلة. ولتعظيم فرص المعالجة المتوازية، لا تُدمَج هذه المسارات إلا في مرحلة متأخرة قدر الإمكان. على سبيل المثال، يوضح مربع العقدة 1 في الشكل 8 الرسم البياني للمعاملات لاستعلام OLAP نموذجي على table يحتوي على إحصاءات مرات ظهور الصفحات. في المرحلة الأولى، تُرشَّح ثلاثة ranges منفصلة من الجدول المصدر بالتوازي. ويقوم معامل Repartition exchange بتوجيه دفعات البيانات الناتجة ديناميكيًا بين المرحلتين الأولى والثانية للحفاظ على توزيع متوازن لعبء العمل على خيوط المعالجة. وقد تصبح مسارات التنفيذ غير متوازنة بعد المرحلة الأولى إذا كانت ranges الممسوحة تختلف كثيرًا في الانتقائية. في المرحلة الثانية، تُجمَّع الصفوف التي اجتازت filter بحسب RegionID. وتحافظ معاملات Aggregate على مجموعات نتائج محلية، بحيث يكون RegionID عمود التجميع، وتُحتفَظ لكل مجموعة بقيمتي sum وcount بوصفهما aggregation state جزئية للدالة avg(). وفي النهاية، يدمج معامل GroupStateMerge نتائج التجميع المحلية في نتيجة تجميع عامة. ويُعد هذا المعامل أيضًا pipeline breaker، أي إن المرحلة الثالثة لا يمكن أن تبدأ إلا بعد اكتمال حساب نتيجة التجميع بالكامل. في المرحلة الثالثة، تُقسَّم مجموعات النتائج أولًا بواسطة معامل Distribute exchange إلى ثلاثة partitions منفصلة ومتساوية الحجم، ثم تُرتَّب بحسب AvgLatency. ويجري الترتيب على ثلاث خطوات: أولًا، ترتّب معاملات ChunkSort الـ دفعات البيانات الفردية لكل partition. ثانيًا، تحافظ معاملات StreamSort على نتيجة محلية مرتبة تُدمَج مع الـ دفعات البيانات المرتبة الواردة باستخدام فرز دمج ثنائي الاتجاه 2-way merge sorting. وأخيرًا، يدمج معامل MergeSort النتائج المحلية باستخدام فرز k-way للحصول على النتيجة النهائية. المعاملات هي state machines ومتصلة ببعضها عبر input ports وoutput ports. والحالات الثلاث الممكنة للمعامل هي need-chunk وready وdone. وللانتقال من need-chunk إلى ready، توضع دفعة بيانات في input port الخاصة بالمعامل. وللانتقال من ready إلى done، يعالج المعامل input chunk ويولّد output chunk. وللانتقال من done إلى need-chunk، تُزال output chunk من output port الخاصة بالمعامل. ولا يمكن تنفيذ انتقالَي الحالة الأول والثالث في معاملين متصلين إلا كخطوة مشتركة. أما معاملات source (ومعاملات sink) فلا تملك إلا حالتي ready وdone (أو need-chunk وdone). تجتاز worker threads باستمرار خطة المعاملات الفعلية وتنفّذ انتقالات الحالة. وللحفاظ على سخونة مخابئ CPU، تتضمن الخطة تلميحات تشير إلى أنه ينبغي للخيط نفسه معالجة المعاملات المتتالية في مسار التنفيذ نفسه. وتحدث المعالجة المتوازية أفقيًا عبر المُدخلات المنفصلة داخل المرحلة الواحدة (فعلى سبيل المثال، في الشكل 8 تُنفَّذ معاملات Aggregate بالتوازي)، وعموديًا عبر المراحل التي لا تفصل بينها pipeline breakers (فعلى سبيل المثال، في الشكل 8 يمكن أن يعمل معاملا Filter وAggregate في مسار التنفيذ نفسه في الوقت ذاته). ولتجنّب الإفراط في الاشتراك أو نقصه عند بدء queries جديدة أو انتهاء queries متزامنة، يمكن تغيير degree of parallelism أثناء query بين واحد والحد الأقصى لعدد worker threads الخاصة بالـ query والمحدد عند بدء query (راجع القسم 4.5)). ويمكن للمعاملات أيضًا التأثير في تنفيذ query أثناء runtime بطريقتين. أولًا، يمكنها إنشاء معاملات جديدة وربطها ديناميكيًا. ويُستخدم ذلك أساسًا للتحول إلى external aggregation أو sort أو join algorithms بدلًا من إلغاء query عندما يتجاوز استهلاك الذاكرة threshold قابلة للضبط. ثانيًا، يمكن للمعاملات أن تطلب من worker threads الانتقال إلى asynchronous queue. ويتيح ذلك استخدامًا أكثر كفاءة لـ worker threads عند انتظار البيانات البعيدة. يتشابه محرّك تنفيذ الاستعلامات في ClickHouse والتوازي المعتمد على الأجزاء الصغيرة [44] من حيث إن المسارات تُنفَّذ عادةً على أنوية مختلفة / مقابس NUMA مختلفة، وإن خيوط العمل تستطيع انتزاع المهام من مسارات أخرى. كذلك، لا توجد جدولة مركزية؛ بل تختار خيوط العمل مهامها كلٌّ على حدة عبر اجتياز مخطط التنفيذ باستمرار. وعلى خلاف التوازي المعتمد على الأجزاء الصغيرة، يثبّت ClickHouse الحد الأقصى لدرجة التوازي داخل المخطط، ويستخدم نطاقات أكبر بكثير لتقسيم الجدول المصدر مقارنةً بالحجم الافتراضي لهذه الأجزاء، الذي يبلغ نحو 100.000 صف. ومع أن ذلك قد يسبب في بعض الحالات حالات تعثّر (مثلًا عندما يختلف زمن تشغيل عوامل التصفية بين المسارات المختلفة اختلافًا كبيرًا)، فإننا نرى أن الاستخدام المكثّف لعوامل التبادل مثل Repartition يمنع، على الأقل، تراكم مثل هذه الاختلالات عبر المراحل.

4.3 التوازي متعدد العقد

إذا كان جدول المصدر في استعلام ما موزعًا على عدة شظايا، فإن مُحسِّن الاستعلام في العقدة التي استقبلت الاستعلام (العقدة المُبادِرة) يحاول تنفيذ أكبر قدر ممكن من العمل على العقد الأخرى. ويمكن دمج النتائج الواردة من العقد الأخرى في نقاط مختلفة من خطة الاستعلام. وبحسب الاستعلام، قد تقوم العقد البعيدة بأحد الأمور التالية: 1. بث أعمدة جدول المصدر الخام إلى العقدة المُبادِرة، 2. تصفية أعمدة المصدر وإرسال الصفوف المتبقية، 3. تنفيذ خطوتَي التصفية والتجميع وإرسال مجموعات النتائج المحلية مع حالات التجميع الجزئية، أو 4. تنفيذ الاستعلام بالكامل، بما في ذلك التصفية والتجميع والفرز. تُظهر العقد 2 … N في الشكل 8 أجزاءً من الخطة تُنفَّذ على عقد أخرى تحتفظ بشظايا من جدول hits. وتقوم هذه العقد بتصفية البيانات المحلية وتجميعها ثم إرسال النتيجة إلى العقدة المُبادِرة. ويتولى العامل GroupStateMerge على العقدة 1 دمج النتائج المحلية والبعيدة قبل فرز مجموعات النتائج نهائيًا.

4.4 التحسين الشامل للأداء

يستعرض هذا القسم مجموعة مختارة من تحسينات الأداء الرئيسية المطبَّقة على مراحل مختلفة من تنفيذ الاستعلام. تحسين الاستعلام. تُطبَّق المجموعة الأولى من التحسينات على تمثيل دلالي للاستعلام يُستخلص من AST الخاص به. ومن أمثلة هذه التحسينات: طيّ الثوابت (مثلًا، تتحول concat(lower(‘a’),upper(‘b’)) إلى ‘aB’)، واستخراج القيم العددية من بعض دوال التجميع (مثلًا، تتحول sum(a2) إلى 2 * sum(a))، وإزالة التعبيرات الفرعية المشتركة، وتحويل حالات OR بين مرشحات المساواة إلى قوائم IN (مثلًا، يتحول x=c OR x=d إلى x IN (c,d)). بعد ذلك، يُحوَّل التمثيل الدلالي المحسَّن للاستعلام إلى خطة عوامل منطقية. وتشمل التحسينات على مستوى الخطة المنطقية pushdown للمرشحات، وإعادة ترتيب تقييم الدوال وخطوات الفرز، بحسب ما يُقدَّر أنه الأعلى كلفة. وأخيرًا، تُحوَّل الخطة المنطقية للاستعلام إلى خطة عوامل فيزيائية. ويمكن لهذا التحويل الاستفادة من خصائص محركات الجداول المعنية. فعلى سبيل المثال، في حالة محرك جدول من نوع MergeTree، إذا كانت أعمدة ORDER BY تُشكّل بادئة للمفتاح الأساسي، فيمكن قراءة البيانات وفق ترتيبها على القرص، ويمكن إزالة عوامل الفرز من الخطة. كذلك، إذا كانت أعمدة التجميع في عملية aggregation تُشكّل بادئة للمفتاح الأساسي، يمكن لـ ClickHouse استخدام sort aggregation [33]، أي تجميع السلاسل المتتالية ذات القيمة نفسها مباشرة في المدخلات المفرزة مسبقًا. وبالمقارنة مع hash aggregation، يستهلك sort aggregation ذاكرة أقل بكثير، كما يمكن تمرير قيمة aggregate إلى العامل التالي مباشرة بعد معالجة كل سلسلة. ترجمة الاستعلام برمجيًا. يستخدم ClickHouse ترجمة الاستعلام برمجيًا بالاعتماد على LLVM لدمج عوامل الخطة المتجاورة ديناميكيًا [38, 53]. فعلى سبيل المثال، يمكن دمج التعبير a * b + c + 1 في عامل واحد بدلًا من ثلاثة عوامل. وإلى جانب التعبيرات، يستخدم ClickHouse أيضًا الترجمة البرمجية لتقييم عدة دوال تجميع دفعة واحدة (أي في GROUP BY) وللفرز باستخدام أكثر من مفتاح فرز. تؤدي ترجمة الاستعلام برمجيًا إلى تقليل عدد الاستدعاءات الافتراضية، والإبقاء على البيانات في السجلات أو في ذواكر CPU المخبئية، كما تساعد متنبئ التفرعات لأن مقدارًا أقل من الشيفرة يحتاج إلى التنفيذ. بالإضافة إلى ذلك، تتيح الترجمة البرمجية وقت التشغيل الاستفادة من مجموعة غنية من التحسينات، مثل التحسينات المنطقية وتحسينات peephole المطبقة في المصرّفات، وتوفر الوصول إلى أسرع تعليمات CPU المتاحة محليًا. ولا تبدأ الترجمة البرمجية إلا عندما يُنفَّذ التعبير نفسه، سواء كان عاديًا أو تجميعيًا أو متعلقًا بالفرز، من قِبل استعلامات مختلفة أكثر من عدد قابل للضبط من المرات. ويتم تخزين عوامل الاستعلام المترجمة برمجيًا في cache ويمكن إعادة استخدامها في الاستعلامات المستقبلية.[7] تقييم فهرس المفتاح الأساسي. يقيّم ClickHouse شروط WHERE باستخدام فهرس المفتاح الأساسي إذا كانت مجموعة فرعية من بنود التصفية في الصيغة العطفية المعيارية للشرط تُشكّل بادئة لأعمدة المفتاح الأساسي. ويُحلَّل فهرس المفتاح الأساسي من اليسار إلى اليمين على نطاقات مرتبة معجميًا من قيم المفاتيح. وتُقيَّم بنود التصفية المقابلة لعمود من أعمدة المفتاح الأساسي باستخدام منطق ثلاثي: إما أن تكون كلها true، أو كلها false، أو مزيجًا من true وfalse للقيم الموجودة في النطاق. وفي الحالة الأخيرة، يُقسَّم النطاق إلى نطاقات فرعية تُحلَّل تكراريًا. وهناك تحسينات إضافية للدوال في شروط التصفية. أولًا، تمتلك الدوال سمات تصف رتابتها؛ فمثلًا تكون toDayOfMonth(date) رتيبة على نحو قطعي ضمن الشهر الواحد. وتسمح سمات الرتابة بالاستدلال على ما إذا كانت الدالة تنتج نتائج مرتبة عند تطبيقها على نطاقات مرتبة من قيم المفاتيح المُدخلة. ثانيًا، يمكن لبعض الدوال حساب الصورة السابقة لقيمة ناتجة معيّنة من الدالة. ويُستخدم ذلك لاستبدال مقارنات الثوابت التي تتضمن استدعاءات دوال على أعمدة المفاتيح، وذلك بمقارنة قيمة عمود المفتاح مع الصورة السابقة. فعلى سبيل المثال، يمكن استبدال toYear(k) = 2024 بـ k >= 2024-01-01 && k < 2025-01-01. تخطّي البيانات. يحاول ClickHouse تجنّب قراءة البيانات وقت تشغيل الاستعلام باستخدام تراكيب البيانات المعروضة في القسم 3.2. بالإضافة إلى ذلك، تُقيَّم المرشحات على الأعمدة المختلفة تسلسليًا بترتيب تنازلي وفق الانتقائية المقدَّرة استنادًا إلى القواعد الإرشادية وإحصاءات الأعمدة (الاختيارية). ولا تُمرَّر إلى predicate التالية إلا chunks البيانات التي تحتوي على صف واحد مطابق على الأقل. ويؤدي ذلك تدريجيًا إلى تقليل كمية البيانات المقروءة وعدد العمليات الحسابية المطلوب تنفيذها من predicate إلى أخرى. ولا يُطبَّق هذا التحسين إلا عند وجود predicate واحدة عالية الانتقائية على الأقل؛ وإلا فسيتدهور زمن استجابة الاستعلام مقارنةً بتقييم جميع predicates in parallel. جداول التجزئة. تُعد جداول التجزئة من هياكل البيانات الأساسية لعمليات التجميع وعمليات ربط تجزئة. ويُعد اختيار النوع المناسب من جداول التجزئة عاملًا حاسمًا في الأداء. يقوم ClickHouse بإنشاء أنواع متعددة من جداول التجزئة (أكثر من 30 نوعًا حتى مارس 2024) انطلاقًا من قالب عام لجدول التجزئة، مع استخدام دالة التجزئة، والمخصّص، ونوع الخلية، وسياسة تغيير الحجم كنقاط اختلاف. واستنادًا إلى نوع البيانات لأعمدة التجميع، والقيمة التقديرية لـ cardinality لجدول التجزئة، وعوامل أخرى، يُختار أسرع جدول تجزئة لكل عامل query على حدة. وتشمل التحسينات الإضافية المطبقة على جداول التجزئة ما يلي:
  • تخطيط ثنائي المستوى يضم 256 جدولًا فرعيًا (استنادًا إلى البايت الأول من قيمة التجزئة) لدعم مجموعات المفاتيح الكبيرة جدًا،
  • جداول تجزئة للسلاسل النصية [79] تضم أربعة جداول فرعية ودوال تجزئة مختلفة بحسب أطوال السلاسل،
  • جداول lookup تستخدم المفتاح مباشرةً بوصفه فهرس bucket (أي من دون تجزئة) عندما يكون عدد المفاتيح قليلًا،
  • قيم ذات تجزئات مضمّنة لتسريع معالجة التصادمات عندما تكون المقارنة مكلفة (مثل السلاسل النصية وASTs)،
  • إنشاء جداول التجزئة استنادًا إلى الأحجام المتوقعة من إحصاءات وقت التشغيل لتجنب عمليات تغيير الحجم غير الضرورية،
  • تخصيص عدة جداول تجزئة صغيرة لها دورة الإنشاء/الإتلاف نفسها ضمن شريحة ذاكرة واحدة،
  • المسح الفوري لجداول التجزئة لإعادة استخدامها باستخدام عدّادات الإصدارات لكل خريطة تجزئة ولكل خلية،
  • استخدام الجلب المسبق للمعالج (__builtin_prefetch) لتسريع استرجاع القيم بعد تجزئة المفتاح.
عمليات الربط. نظرًا إلى أن ClickHouse كان يدعم عمليات joins في الأصل بشكل محدود فقط، فقد اعتمدت كثير من حالات الاستخدام تاريخيًا على الجداول غير المطبّعة. أما اليوم، فتوفّر قاعدة البيانات جميع أنواع join المتاحة في SQL ‏(inner وleft- /right/full outer وcross وas-of)، بالإضافة إلى خوارزميات join مختلفة مثل ربط تجزئة ‏(naïve وgrace) وsort-merge join وindex join لمحركات الجداول التي تدعم key-value lookup سريعًا (وعادةً ما تكون Dictionaries). وبما أن joins تُعد من أكثر عمليات قاعدة البيانات كلفة، فمن المهم توفير صيغ متوازية من خوارزميات join الكلاسيكية، ويفضّل أن تكون مع مفاضلات قابلة للضبط بين المساحة والزمن. بالنسبة إلى عمليات ربط تجزئة، يطبّق ClickHouse خوارزمية الأقسام المشتركة غير الحاجزة الواردة في [7]. على سبيل المثال، يحسب الاستعلام في Figure 9 كيفية انتقال المستخدمين بين عناوين URL عبر self-join على جدول إحصاءات زيارات الصفحات. تُقسَّم مرحلة بناء الـ join إلى ثلاثة مسارات، يغطي كل منها نطاقًا منفصلًا من جدول مصدر. وبدلًا من جدول تجزئة عام، يُستخدم جدول تجزئة مُقسَّم. وتحدّد خيوط عمل (وعددها عادةً ثلاثة) القسم الهدف لكل صف إدخال من جهة البناء عبر حساب باقي قسمة دالة تجزئة. وتُزامَن إمكانية الوصول إلى أقسام جدول التجزئة باستخدام معاملات Gather exchange. وتعثر مرحلة الفحص على القسم الهدف لـ tuples الإدخال الخاصة بها بالطريقة نفسها. ومع أن هذه الخوارزمية تضيف عمليتي حساب تجزئة إضافيتين لكل tuple، فإنها تقلل بدرجة كبيرة من التنافس على الأقفال في مرحلة البناء، وذلك بحسب عدد أقسام جدول التجزئة.
الشكل 9: ربط تجزئة متوازٍ مع ثلاثة أقسام لجدول التجزئة.

الشكل 9: ربط تجزئة متوازٍ مع ثلاثة أقسام لجدول التجزئة.

4.5 عزل أعباء العمل

يوفّر ClickHouse التحكم في التزامن، وحدود استخدام الذاكرة، وجدولة I/O، مما يتيح للمستخدمين عزل الاستعلامات ضمن فئات أعباء العمل. ومن خلال فرض حدود على الموارد المشتركة (أنوية CPU، وذاكرة DRAM، وI/O للقرص والشبكة) على فئات أعباء عمل محددة، يضمن عدم تأثير هذه الاستعلامات في استعلامات الأعمال الحرجة الأخرى. يمنع التحكم في التزامن الإفراط في تخصيص خيوط التنفيذ في السيناريوهات التي يوجد فيها عدد كبير من الاستعلامات المتزامنة. وبصورة أدق، يُعدَّل عدد خيوط العمل لكل query ديناميكيًا استنادًا إلى نسبة محددة من عدد أنوية CPU المتاحة. يتتبّع ClickHouse أحجام البايت الخاصة بتخصيصات الذاكرة على مستوى الخادم والمستخدم والاستعلام، وبذلك يتيح تعيين حدود مرنة لاستخدام الذاكرة. وتتيح ميزة memory overcommit للاستعلامات استخدام ذاكرة حرة إضافية تتجاوز الذاكرة المضمونة، مع ضمان حدود الذاكرة للاستعلامات الأخرى. علاوة على ذلك، يمكن تقييد استخدام الذاكرة لعبارات aggregation وsort وjoin، مما يؤدي إلى التحوّل إلى خوارزميات خارجية عند تجاوز حد الذاكرة. وأخيرًا، تتيح جدولة I/O للمستخدمين تقييد عمليات الوصول المحلية والبعيدة إلى disk لفئات أعباء العمل استنادًا إلى حد أقصى لعرض النطاق الترددي، والطلبات قيد التنفيذ، والسياسة (مثل FIFO وSFC [32]).

5 طبقة التكامل

تعتمد تطبيقات اتخاذ القرار في الوقت الفعلي غالبًا على وصول فعّال ومنخفض الكمون إلى البيانات عبر مواقع متعددة. وهناك نهجان لإتاحة البيانات الخارجية داخل قاعدة بيانات OLAP. في نهج الوصول القائم على الدفع، يتولى مكوّن تابع لجهة خارجية الربط بين قاعدة البيانات ومخازن البيانات الخارجية. ومن أمثلة ذلك أدوات extract-transform-load (ETL) المتخصصة التي تدفع البيانات البعيدة إلى النظام الوجهة. أما في النموذج القائم على السحب، فتتصل قاعدة البيانات نفسها بمصادر البيانات البعيدة وتسحب البيانات للاستعلام عنها إلى جداول محلية أو تُصدّر البيانات إلى أنظمة بعيدة. ومع أن الأساليب القائمة على الدفع أكثر مرونةً وشيوعًا، فإنها تفرض بصمة معمارية أكبر وتشكّل عنق زجاجة من حيث قابلية التوسع. وفي المقابل، يوفّر الاتصال المباشر بالأنظمة البعيدة من داخل قاعدة البيانات إمكانات مهمة، مثل إجراء عمليات ربط بين البيانات المحلية والبعيدة، مع الحفاظ على بساطة البنية العامة وتقليل الوقت اللازم للوصول إلى الرؤى. يستعرض بقية هذا القسم أساليب تكامل البيانات القائمة على السحب في ClickHouse، والمصممة للوصول إلى البيانات في المواقع البعيدة. ونشير إلى أن فكرة الاتصال بالأنظمة البعيدة في قواعد بيانات SQL ليست جديدة. فعلى سبيل المثال، يقترح معيار SQL/MED [35]، الذي قُدّم في عام 2001 وتدعمه PostgreSQL منذ عام 2011 [65]، foreign data wrappers بوصفها واجهة موحّدة لإدارة البيانات الخارجية. ويُعد تحقيق أعلى قدر من قابلية التشغيل البيني مع مخازن البيانات وتنسيقات التخزين الأخرى أحد أهداف تصميم ClickHouse. واعتبارًا من مارس 2024، يوفّر ClickHouse، بحسب أفضل ما نعلم، أكبر عدد من خيارات تكامل البيانات المضمّنة بين جميع قواعد البيانات التحليلية. الاتصال الخارجي. يوفّر ClickHouse أكثر من 50 من وظائف الجدول ومحركات التكامل للاتصال بالأنظمة الخارجية ومواقع التخزين، بما في ذلك ODBC وMySQL وPostgreSQL وSQLite وKafka وHive وMongoDB وRedis ومخازن الكائنات S3/GCP/Azure ومختلف بحيرات البيانات. ونقسّمها أيضًا إلى الفئات التي يوضّحها الشكل الإضافي التالي (وهو ليس جزءًا من ورقة vldb الأصلية).
شكل إضافي: خيارات التشغيل البيني في ClickBench.

شكل إضافي: خيارات التشغيل البيني في ClickBench.

الوصول المؤقت باستخدام وظائف الجدول الخاصة بالتكامل. يمكن استدعاء وظائف الجدول في عبارة FROM ضمن استعلامات SELECT لقراءة البيانات البعيدة لأغراض الاستكشاف والاستعلامات المخصّصة. وبدلًا من ذلك، يمكن استخدامها لكتابة البيانات إلى المخازن البعيدة باستخدام عبارات INSERT INTO TABLE FUNCTION. الوصول الدائم. توجد ثلاث طرق لإنشاء اتصالات دائمة مع مخازن البيانات البعيدة وأنظمة المعالجة. أولًا، تمثّل محركات الجداول الخاصة بالتكامل مصدر بيانات بعيدًا، مثل جدول MySQL، على هيئة جدول محلي دائم. ويخزّن المستخدمون تعريف الجدول باستخدام صيغة CREATE TABLE AS، مقترنةً باستعلام SELECT ووظيفة الجدول. ويمكن تحديد schema مخصص، على سبيل المثال للإشارة إلى مجموعة فرعية فقط من الأعمدة البعيدة، أو استخدام استنتاج schema لتحديد أسماء الأعمدة وأنواع ClickHouse المكافئة تلقائيًا. ونميّز هنا أيضًا بين السلوك التشغيلي السلبي والنشط: فمحركات الجداول السلبية تمرّر الاستعلامات إلى النظام البعيد وتملأ جدولًا وكيلًا محليًا بالنتيجة. أما محركات الجداول النشطة فتسحب البيانات دوريًا من النظام البعيد أو تشترك في التغييرات البعيدة، مثلًا عبر بروتوكول logical replication الخاص بـ PostgreSQL. ونتيجة لذلك، يحتوي الجدول المحلي على نسخة كاملة من الجدول البعيد. ثانيًا، تقوم محركات قواعد البيانات الخاصة بالتكامل بربط جميع جداول schema الجداول في مخزن بيانات بعيد داخل ClickHouse. وعلى خلاف النوع السابق، فإنها تتطلب عمومًا أن يكون مخزن البيانات البعيد قاعدة بيانات علائقية، كما توفّر دعمًا محدودًا لعبارات DDL. ثالثًا، يمكن تعبئة القواميس باستخدام استعلامات اعتباطية على معظم مصادر البيانات الممكنة عبر وظيفة جدول أو محرك تكامل مطابق. ويكون السلوك التشغيلي هنا نشطًا لأن البيانات تُسحب على فترات منتظمة من التخزين البعيد. تنسيقات البيانات. لكي تتفاعل قواعد البيانات التحليلية الحديثة مع أنظمة الجهات الخارجية، يجب أيضًا أن تكون قادرة على معالجة البيانات بأي تنسيق. وإلى جانب تنسيقه الأصلي، يدعم ClickHouse أكثر من 90 تنسيقًا، بما في ذلك CSV وJSON وParquet وAvro وORC وArrow وProtobuf. ويمكن أن يكون كل تنسيق تنسيق إدخال (يمكن لـ ClickHouse قراءته)، أو تنسيق إخراج (يمكن لـ ClickHouse تصديره)، أو كليهما. كما أن بعض التنسيقات الموجّهة للتحليلات مثل Parquet مدمجة أيضًا في معالجة الاستعلامات، أي إن المُحسِّن يمكنه الاستفادة من الإحصاءات المضمّنة، وتُطبَّق المرشحات مباشرة على البيانات المضغوطة. واجهات التوافق. إلى جانب بروتوكوله الثنائي الأصلي وHTTP، يمكن للعملاء التفاعل مع ClickHouse عبر واجهات متوافقة مع بروتوكول wire الخاص بـ MySQL أو PostgreSQL. وتفيد ميزة التوافق هذه في إتاحة الوصول من التطبيقات الاحتكارية (مثل بعض أدوات ذكاء الأعمال)، حيث لم يطبّق المورّدون بعد دعم الاتصال الأصلي بـ ClickHouse.

6 الأداء كميزة

يستعرض هذا القسم أدوات مدمجة لتحليل الأداء ويقيّمه باستخدام استعلامات واقعية واستعلامات قياس الأداء.

6.1 أدوات تحليل الأداء المضمّنة

تتوفر مجموعة واسعة من الأدوات للتحقيق في اختناقات الأداء في الاستعلامات الفردية أو العمليات التي تُنفَّذ في الخلفية. ويتفاعل المستخدمون مع جميع الأدوات عبر واجهة موحّدة تستند إلى جداول النظام. مقاييس الخادم والاستعلام. تُستكمل الإحصاءات على مستوى الخادم، مثل عدد الأجزاء النشطة، ومعدل نقل الشبكة، ومعدلات الإصابة في ذاكرة التخزين المؤقت، بإحصاءات خاصة بكل استعلام، مثل عدد الكتل المقروءة أو إحصاءات استخدام الفهارس. وتُحتسب المقاييس إما بصورة متزامنة (عند الطلب) أو غير متزامنة على فترات قابلة للتهيئة. محلّل الأداء القائم على أخذ العينات. يمكن جمع مكدسات الاستدعاء لخيوط الخادم باستخدام محلّل أداء قائم على أخذ العينات. ويمكن اختياريًا تصدير النتائج إلى أدوات خارجية مثل أدوات عرض flamegraph. تكامل OpenTelemetry. يُعد OpenTelemetry معيارًا مفتوحًا لتتبّع صفوف البيانات عبر أنظمة متعددة لمعالجة البيانات [8]. ويمكن لـ ClickHouse إنشاء spans لسجلات OpenTelemetry بدرجة تفصيل قابلة للتهيئة لجميع خطوات معالجة الاستعلام، وكذلك جمع spans سجلات OpenTelemetry من الأنظمة الأخرى وتحليلها. شرح الاستعلام. كما هو الحال في قواعد البيانات الأخرى، يمكن أن تسبق EXPLAIN استعلامات SELECT لتوفير رؤى تفصيلية حول AST الخاص بالاستعلام، وخطط العوامل المنطقية والمادية، وسلوك التنفيذ أثناء التشغيل.

6.2 اختبارات الأداء المعيارية

رغم أن اختبارات الأداء المعيارية تعرّضت لانتقادات لكونها لا تعكس الواقع بما يكفي [10, 52, 66, 74]، فإنها تظل مفيدة في تحديد نقاط القوة والضعف في قواعد البيانات. وفيما يلي، نناقش كيفية استخدام اختبارات الأداء المعيارية لتقييم أداء ClickHouse.

6.2.1 الجداول غير المُطبَّعة

مثّلت استعلامات التصفية والتجميع على جداول الوقائع غير المُطبَّعة تاريخيًا حالة الاستخدام الأساسية لـ ClickHouse. نعرض أزمنة تشغيل ClickBench، وهو عبء عمل نموذجي من هذا النوع يحاكي استعلامات التقارير المخصّصة والدورية المستخدمة في تحليل بيانات النقرات وحركة الزيارات. يتكوّن هذا الاختبار المعياري من 43 استعلامًا على جدول يحتوي على 100 مليون زيارة صفحة مجهولة المصدر، مأخوذة من إحدى أكبر منصات التحليلات على الويب. تعرض لوحة معلومات عبر الإنترنت [17] القياسات (أزمنة التشغيل البارد/الساخن، ووقت استيراد البيانات، والحجم على القرص) لأكثر من 45 قاعدة بيانات تجارية وبحثية حتى يونيو 2024. يرسل مساهمون مستقلون النتائج استنادًا إلى مجموعة البيانات والاستعلامات المتاحة علنًا [16]. تختبر هذه الاستعلامات مسارات وصول المسح التسلسلي ومسح الفهرس، وتكشف بشكل متكرر عن معاملات علائقية تكون مقيّدة بالـ CPU أو IO أو الذاكرة. يوضح الشكل 10 إجمالي أزمنة التشغيل النسبية الباردة والساخنة عند تنفيذ جميع استعلامات ClickBench تسلسليًا في قواعد البيانات المستخدمة كثيرًا في التحليلات. أُخذت القياسات على مثيل أحادي العقدة من AWS EC2 c6a.4xlarge مزوّد بـ 16 vCPU و32 GB RAM وقرص بسرعة 5000 IOPS / 1000 MiB/s. واستُخدمت أنظمة مماثلة لكلٍّ من Redshift (ra3.4xlarge، 12 vCPU، و96 GB RAM) وSnowfake (warehouse size S: 2x8 vCPU، و2x16 GB RAM). لم يُضبط التصميم الفيزيائي لقاعدة البيانات إلا بشكل محدود، فعلى سبيل المثال نحدّد المفاتيح الأساسية، لكننا لا نغيّر ضغط الأعمدة الفردية، ولا ننشئ projections أو skipping indexes. كما نفرّغ ذاكرة التخزين المؤقت للصفحات في Linux قبل كل تشغيل بارد للاستعلام، لكننا لا نعدّل إعدادات قاعدة البيانات أو نظام التشغيل. ولكل استعلام، يُستخدم أسرع زمن تشغيل عبر قواعد البيانات كخط أساس. وتُحسب أزمنة تشغيل الاستعلامات النسبية لبقية قواعد البيانات وفق الصيغة ( + 10)/(_ + 10). أما إجمالي زمن التشغيل النسبي لقاعدة البيانات فهو المتوسط الهندسي للنسب الخاصة بكل استعلام. وبينما تحقق قاعدة البيانات البحثية Umbra [54] أفضل زمن تشغيل ساخن إجمالًا، تتفوّق ClickHouse على جميع قواعد البيانات الأخرى الجاهزة لبيئات الإنتاج في أزمنة التشغيل الساخنة والباردة.
الشكل 10: أزمنة التشغيل النسبية الباردة والساخنة لـ ClickBench.

الشكل 10: أزمنة التشغيل النسبية الباردة والساخنة لـ ClickBench.

لتتبّع أداء استعلامات SELECT في أعباء عمل أكثر تنوعًا بمرور الوقت، نستخدم مزيجًا من أربعة اختبارات معيارية يُسمّى VersionsBench [19]. يُنفَّذ هذا الاختبار المعياري مرة واحدة شهريًا عند نشر إصدار جديد لتقييم أدائه [20] وتحديد تغييرات الشيفرة التي ربما تسببت في تراجع الأداء: وتشمل الاختبارات المعيارية الفردية ما يلي: 1. ClickBench (الموصوف أعلاه)، 2. ‏15 استعلامًا من MgBench [21]، 3. ‏13 استعلامًا على جدول وقائع غير مُطبَّع من Star Schema Benchmark [57] يضم 600 مليون صف. 4. ‏4 استعلامات على NYC Taxi Rides تضم 3.4 مليار صف [70]. يوضح الشكل 11 تطور أزمنة تشغيل VersionsBench عبر 77 إصدارًا من ClickHouse بين مارس 2018 ومارس 2024. وللتعويض عن الفروق في زمن التشغيل النسبي للاستعلامات الفردية، نطبّع أزمنة التشغيل باستخدام متوسط هندسي، مع اعتماد نسبة زمن تشغيل الاستعلام إلى الحد الأدنى لزمن تشغيل الاستعلام عبر جميع الإصدارات وزنًا. وقد تحسّن أداء VersionBench بمقدار 1.72 × خلال السنوات الست الماضية. وتظهر تواريخ الإصدارات ذات الدعم طويل الأمد (LTS) على المحور السيني. وعلى الرغم من أن الأداء تراجع مؤقتًا في بعض الفترات، فإن إصدارات LTS تتمتع عمومًا بأداء مماثل أو أفضل من إصدار LTS السابق. وكان التحسن الكبير في أغسطس 2022 ناتجًا عن تقنية تقييم التصفية عمودًا بعمود الموضحة في القسم 4.4.
الشكل 11: أزمنة التشغيل الساخنة النسبية لـ VersionsBench ‏2018-2024.

الشكل 11: أزمنة التشغيل الساخنة النسبية لـ VersionsBench ‏2018-2024.

6.2.2 الجداول المُطبَّعة

في مستودعات البيانات التقليدية، غالبًا ما تُنمذج البيانات باستخدام مخططات النجمة أو snowfake. نعرض أزمنة تنفيذ استعلامات TPC-H (عامل القياس 100)، لكننا نشير إلى أن الجداول المُطبَّعة تمثل حالة استخدام ناشئة في ClickHouse. يوضح الشكل 12 أزمنة التشغيل الساخنة لاستعلامات TPC-H استنادًا إلى خوارزمية parallel ربط التجزئة الموصوفة في القسم 4.4. أُخذت القياسات على مثيل AWS EC2 c6i.16xlarge أحادي العقدة، مزود بـ 64 vCPU و128 GB RAM وقرص بسرعة 5000 IOPS / 1000 MiB/s. وسُجِّل أسرع تشغيل من أصل خمس تشغيلات. وللمقارنة، أجرينا القياسات نفسها على نظام Snowfake بحجم مماثل (warehouse size L، ‏8x8 vCPUs، ‏8x16 GB RAM). واستُبعدت نتائج أحد عشر استعلامًا من الجدول: فالاستعلامات Q2 وQ4 وQ13 وQ17 وQ20-22 تتضمن استعلامات فرعية مترابطة غير مدعومة حتى ClickHouse v24.6. كما تعتمد الاستعلامات Q7-Q9 وQ19 على تحسينات موسعة على مستوى خطة التنفيذ لعمليات joins، مثل إعادة ترتيب join ودفع شروط join predicate (وكلاهما غير متاحين حتى ClickHouse v24.6.) لتحقيق أزمنة تنفيذ عملية. ومن المخطط تنفيذ إزالة الارتباط التلقائية لـ subquery ودعم أفضل من المُحسِّن لعمليات joins خلال عام 2024 [18]. ومن بين الاستعلامات الأحد عشر المتبقية، نُفِّذ 5 (6) استعلامات بسرعة أكبر في ClickHouse (Snowfake). ونظرًا إلى أن التحسينات المذكورة آنفًا معروفة بأهميتها الحاسمة للأداء [27]، فإننا نتوقع أن تُحسِّن أزمنة تنفيذ هذه الاستعلامات أكثر بمجرد تنفيذها.
الشكل 12: أزمنة التشغيل الساخنة (بالثواني) لاستعلامات TPC-H.

الشكل 12: أزمنة التشغيل الساخنة (بالثواني) لاستعلامات TPC-H.

حظيت قواعد البيانات التحليلية باهتمام أكاديمي وتجاري كبير خلال العقود الأخيرة [1]. واتسمت الأنظمة المبكرة مثل Sybase IQ [48]، وTeradata [72]، وVertica [42]، وGreenplum [47]، بمهام ETL دفعية مرتفعة الكلفة ومرونة محدودة بسبب طبيعتها المحلية داخل البنية التحتية الخاصة. وفي أوائل العقد الثاني من الألفية، أدى ظهور مستودعات البيانات السحابية الأصلية وعروض قواعد البيانات كخدمة (DBaaS) مثل Snowfake [22]، وBigQuery [49]، وRedshift [4]، إلى خفض تكلفة التحليلات وتعقيدها على المؤسسات بصورة كبيرة، مع الاستفادة من التوافر العالي والتوسع التلقائي للموارد. وفي الآونة الأخيرة، توفّر نوى التنفيذ التحليلية (مثل Photon [5] وVelox [62]) طبقة مشتركة لمعالجة البيانات لاستخدامها في تطبيقات تحليلية وتدفّقية وتعلّم آلي مختلفة. أكثر قواعد البيانات شبهًا بـ ClickHouse، من حيث الأهداف ومبادئ التصميم، هما Druid [78] وPinot [34]. يستهدف كلا النظامين التحليلات في الوقت الفعلي مع معدلات مرتفعة لإدخال البيانات. ومثل ClickHouse، تُقسَّم الجداول إلى أجزاء أفقية تُسمّى segments. وبينما يدمج ClickHouse الأجزاء الأصغر باستمرار ويقلّص أحجام البيانات اختياريًا باستخدام الأساليب الواردة في القسم 3.3، تظل الأجزاء غير قابلة للتغيير إلى الأبد في Druid وPinot. كذلك، يتطلب Druid وPinot عقدًا متخصصة لإنشاء الجداول وتعديلها والبحث فيها، في حين يستخدم ClickHouse ملفًا تنفيذيًا موحّدًا لهذه المهام. يُعد Snowfake [22] مستودع بيانات سحابيًا احتكاريًا شائعًا قائمًا على معمارية القرص المشترك. ويشبه نهجه في تقسيم الجداول إلى micro-partitions مفهوم الأجزاء في ClickHouse. يستخدم Snowfake صفحات PAX هجينة [3] للتخزين الدائم، بينما يكون تنسيق التخزين في ClickHouse عموديًا بالكامل. كما يركّز Snowfake على التخزين المؤقت المحلي وتقنيات تنحية البيانات باستخدام فهارس خفيفة تُنشأ تلقائيًا [31, 51] بوصفها عاملًا من عوامل الأداء الجيد. وعلى نحو مماثل للمفاتيح الأساسية في ClickHouse، يمكن للمستخدمين إنشاء clustered indexes اختياريًا لوضع البيانات ذات القيم المتطابقة معًا. يُعد Photon [5] وVelox [62] محرّكي تنفيذ للاستعلامات صُمّما للاستخدام كمكوّنات في أنظمة إدارة بيانات معقدة. ويتلقى كلا النظامين خطط الاستعلام كمدخلات، ثم تُنفَّذ على العقدة المحلية فوق ملفات Parquet (Photon) أو Arrow (Velox) [46]. يستطيع ClickHouse استهلاك البيانات وإنتاجها بهذه التنسيقات العامة، لكنه يفضّل تنسيق ملفه الأصلي للتخزين. وبينما لا يحسّن Velox وPhoton خطة الاستعلام (إذ يجري Velox تحسينات أساسية على expression)، فإنهما يستخدمان تقنيات التكيّف وقت التشغيل، مثل التبديل الديناميكي بين نوى compute بحسب خصائص البيانات. وبالمثل، يمكن لعوامل الخطة في ClickHouse إنشاء عوامل أخرى وقت التشغيل، وذلك أساسًا للتبديل إلى aggregation خارجية أو عوامل join، استنادًا إلى استهلاك الذاكرة الخاص بالاستعلام. وتشير ورقة Photon إلى أن التصاميم المعتمدة على توليد الشيفرة [38, 41, 53] أصعب تطويرًا وتصحيحًا من التصاميم المتجهة المفسَّرة [11]. أما الدعم (التجريبي) لتوليد الشيفرة في إصدارات Velox فيبني مكتبة مشتركة ويربطها، وهي مُنتَجة من شيفرة C++ مولَّدة وقت التشغيل، بينما يتفاعل ClickHouse مباشرةً مع واجهة API الخاصة بالتجميع عند الطلب في LLVM. كما أن DuckDB [67] مُصمَّم أيضًا ليكون مضمّنًا داخل عملية مضيفة، لكنه يوفّر بالإضافة إلى ذلك تحسين الاستعلامات والمعاملات. وقد صُمِّم لاستعلامات OLAP الممزوجة بعبارات OLTP عرضية. وبناءً على ذلك، اختار DuckDB تنسيق التخزين DataBlocks [43]، الذي يستخدم أساليب ضغط خفيفة مثل القواميس المحافظة على الترتيب أو frame-of-reference [2] لتحقيق أداء جيد في أعباء العمل الهجينة. وعلى النقيض من ذلك، جرى تحسين ClickHouse لحالات الاستخدام القائمة على الإلحاق فقط، أي من دون تحديثات أو عمليات حذف، أو مع ندرتها. وتُضغط الكتل باستخدام تقنيات كثيفة مثل LZ4، على افتراض أن المستخدمين يعتمدون بدرجة كبيرة على تشذيب البيانات لتسريع الاستعلامات المتكررة، وأن تكاليف I/O تفوق بكثير تكاليف فك الضغط بالنسبة إلى الاستعلامات المتبقية. كما يوفّر DuckDB أيضًا معاملات قابلة للتسلسل استنادًا إلى مخطط MVCC الخاص بـ Hyper [55]، في حين لا يوفّر ClickHouse سوى عزل اللقطة.

8 الخاتمة والنظرة المستقبلية

استعرضنا معمارية ClickHouse، وهي قاعدة بيانات OLAP مفتوحة المصدر وعالية الأداء. ويعتمد ClickHouse في أساسه على طبقة تخزين محسّنة للكتابة ومحرك استعلامات متجهي متقدم، مما يتيح إجراء تحليلات لحظية على مجموعات بيانات بحجم بيتابايت وبمعدلات استيعاب عالية. ومن خلال دمج البيانات وتحويلها بشكل غير متزامن في الخلفية، يفصل ClickHouse بكفاءة بين صيانة البيانات وعمليات الإدراج المتوازية. كما تتيح طبقة التخزين فيه استبعادًا مكثفًا للبيانات غير اللازمة باستخدام الفهارس الأولية المتفرقة، وفهارس التخطي، وجداول الإسقاط. وشرحنا كيفية تنفيذ ClickHouse لعمليات التحديث والحذف، وعمليات الإدراج المتكررة غير المؤثرة، ونسخ البيانات بين العُقد لتحقيق التوافر العالي. وتعمل طبقة معالجة الاستعلامات على تحسين الاستعلامات باستخدام مجموعة واسعة من الأساليب، كما توازي التنفيذ عبر جميع موارد الخادم والعنقود. وتوفر محركات الجداول ووظائف التكامل وسيلة مريحة للتفاعل بسلاسة مع أنظمة إدارة البيانات الأخرى وتنسيقات البيانات المختلفة. ومن خلال اختبارات الأداء، نبيّن أن ClickHouse من بين أسرع قواعد البيانات التحليلية في السوق، كما عرضنا تحسينات كبيرة في أداء الاستعلامات الشائعة في عمليات النشر الفعلية لـ ClickHouse على مر السنين. يمكن العثور على جميع الميزات والتحسينات المخطط لها لعام 2024 في خارطة الطريق العامة [18]. وتشمل التحسينات المخطط لها دعم معاملات المستخدم، وPromQL [69] كلغة استعلام بديلة، ونوع بيانات جديد للبيانات شبه المهيكلة (مثل JSON)، وتحسينات أفضل على مستوى خطط التنفيذ لعمليات الربط، بالإضافة إلى تنفيذ تحديثات خفيفة الوزن لاستكمال عمليات الحذف خفيفة الوزن.

شكر وتقدير

اعتبارًا من الإصدار 24.6، يُرجِع SELECT * FROM system.contributors عددًا يبلغ 1994 شخصًا ساهموا في ClickHouse. ونود أن نتوجه بالشكر إلى فريق الهندسة بالكامل في ClickHouse Inc. وإلى مجتمع ClickHouse مفتوح المصدر الرائع على عملهم الدؤوب وتفانيهم في بناء قاعدة البيانات هذه معًا.

المراجع

  • 1 Daniel Abadi, Peter Boncz, Stavros Harizopoulos, Stratos Idreaos, and Samuel Madden. 2013. تصميم وتنفيذ أنظمة قواعد البيانات الحديثة العمودية التوجّه. https://doi.org/10.1561/9781601987556
  • 2 Daniel Abadi، Samuel Madden، وMiguel Ferreira. 2006. Integrating Compression and Execution in Column-Oriented Database Systems. In Proceedings of the 2006 ACM SIGMOD International Conference on Management of Data (SIGMOD ‘06). 671–682.https://doi.org/10.1145/1142473.1142548
  • 3 Anastassia Ailamaki، وDavid J. DeWitt، وMark D. Hill، وMarios Skounakis. 2001. Weaving Relations for Cache Performance. في وقائع المؤتمر الدولي السابع والعشرين لقواعد البيانات الضخمة جدًا (VLDB ‘01). Morgan Kaufmann Publishers Inc.، San Francisco، CA، USA، 169–180.
  • 4 Nikos Armenatzoglou, Sanuj Basu, Naga Bhanoori, Mengchu Cai, Naresh Chainani, Kiran Chinta, Venkatraman Govindaraju, Todd J. Green, Monish Gupta, Sebastian Hillig, Eric Hotinger, Yan Leshinksy, Jintian Liang, Michael McCreedy, Fabian Nagel, Ippokratis Pandis, Panos Parchas, Rahul Pathak, Orestis Polychroniou, Foyzur Rahman, Gaurav Saxena, Gokul Soundararajan, Sriram Subramanian, and Doug Terry. 2022. Amazon Redshift Re-Invented. في وقائع المؤتمر الدولي لإدارة البيانات لعام 2022 ‏(Philadelphia, PA, USA) ‏(SIGMOD ‘22). Association for Computing Machinery، نيويورك، NY، الولايات المتحدة الأمريكية، 2205–2217. https://doi.org/10.1145/3514221.3526045
  • 5 Alexander Behm, Shoumik Palkar, Utkarsh Agarwal, Timothy Armstrong, David Cashman, Ankur Dave, Todd Greenstein, Shant Hovsepian, Ryan Johnson, Arvind Sai Krishnan, Paul Leventis, Ala Luszczak, Prashanth Menon, Mostafa Mokhtar, Gene Pang, Sameer Paranjpye, Greg Rahn, Bart Samwel, Tom van Bussel, Herman van Hovell, Maryann Xue, Reynold Xin، و Matei Zaharia. 2022. Photon: A Fast Query Engine for Lakehouse Systems (SIGMOD ‘22). Association for Computing Machinery, New York, NY, USA, 2326–2339. https://doi.org/10.1145/3514221. 3526054
  • 6 فيليب أ. برنستاين وناثان غودمان. 1981. التحكم في التزامن في أنظمة قواعد البيانات الموزعة. ACM Computing Survey 13, 2 (1981), 185–221. https://doi.org/10.1145/356842.356846
  • 7 Spyros Blanas، وYinan Li، وJignesh M. Patel. 2011. تصميم وتقييم خوارزميات JOIN بالتجزئة في الذاكرة الرئيسية لوحدات CPU متعددة الأنوية. في Proceedings of the 2011 ACM SIGMOD International Conference on Management of Data ‏(Athens, Greece) ‏(SIGMOD ‘11). Association for Computing Machinery، نيويورك، NY، الولايات المتحدة الأمريكية، 37–48. https://doi.org/10.1145/1989323.1989328
  • 8 Daniel Gomez Blanco. 2023. Practical OpenTelemetry. Springer Nature.
  • 9 Burton H. Bloom. 1970. Space/Time Trade-Ofs in Hash Coding with Allowable Errors. Commun. ACM 13, 7 (1970), 422–426. https://doi.org/10.1145/362686. 362692
  • 10 Peter Boncz، Thomas Neumann، وOrri Erling. 2014. TPC-H Analyzed: Hidden Messages and Lessons Learned from an Infuential Benchmark. في Performance Characterization and Benchmarking. 61–76. https://doi.org/10.1007/978-3-319- 04936-6_5
  • 11 Peter Boncz، Marcin Zukowski، وNiels Nes. 2005. MonetDB/X100: تنفيذ الاستعلامات عبر خطوط أنابيب فائقة. في CIDR.
  • 12 Martin Burtscher وParuj Ratanaworabhan. 2007. ضغط عالي الإنتاجية لبيانات الفاصلة العائمة مزدوجة الدقة. في مؤتمر ضغط البيانات (DCC). 293–302. https://doi.org/10.1109/DCC.2007.44
  • 13 Jef Carpenter و Eben Hewitt. 2016. Cassandra: The Defnitive Guide (ط. 2). O’Reilly Media, Inc.
  • 14 برناديت شارون-بوست، وفرناندو بيدوني، وأندريه شيبر (تحرير). 2010. Replication: Theory and Practice. Springer-Verlag.
  • 15 chDB. 2024. chDB - محرك SQL OLAP مضمّن. تم الاسترجاع بتاريخ 2024-06-20 من https://github.com/chdb-io/chdb
  • 16 ClickHouse. 2024. ClickBench: معيار لأداء قواعد البيانات التحليلية. تاريخ الاسترجاع 2024-06-20 من https://github.com/ClickHouse/ClickBench
  • 17 ClickHouse. 2024. ClickBench: قياسات مقارنة. تم الاسترجاع بتاريخ 2024-06-20 من https://benchmark.clickhouse.com
  • 18 ClickHouse. 2024. خريطة طريق ClickHouse لعام 2024 (GitHub). استُرجع في 2024-06-20 من https://github.com/ClickHouse/ClickHouse/issues/58392
  • 19 ClickHouse. 2024. ClickHouse Versions Benchmark. تم الاسترجاع بتاريخ 2024-06-20 من https://github.com/ClickHouse/ClickBench/tree/main/versions
  • 20 ClickHouse. 2024. نتائج اختبار الأداء لإصدارات ClickHouse. استُرجع في 2024-06-20 من https://benchmark.clickhouse.com/versions/
  • 21 Andrew Crotty. 2022. MgBench. تم الاسترجاع بتاريخ 2024-06-20 من https://github.com/ andrewcrotty/mgbench
  • 22 Benoit Dageville, Thierry Cruanes, Marcin Zukowski, Vadim Antonov, Artin Avanes, Jon Bock, Jonathan Claybaugh, Daniel Engovatov, Martin Hentschel, Jiansheng Huang, Allison W. Lee, Ashish Motivala, Abdul Q. Munir, Steven Pelley, Peter Povinec, Greg Rahn, Spyridon Triantafyllis، و Philipp Unterbrunner. 2016. The Snowfake Elastic Data Warehouse. ضمن وقائع المؤتمر الدولي لإدارة البيانات لعام 2016 (سان فرانسيسكو، كاليفورنيا، الولايات المتحدة الأمريكية) (SIGMOD ‘16). Association for Computing Machinery، نيويورك، نيويورك، الولايات المتحدة الأمريكية، 215–226. https: //doi.org/10.1145/2882903.2903741
  • 23 Patrick Damme, Annett Ungethüm, Juliana Hildebrandt, Dirk Habich, and Wolfgang Lehner. 2019. من دراسة استقصائية تجريبية شاملة إلى استراتيجية اختيار قائمة على التكلفة لخوارزميات ضغط الأعداد الصحيحة خفيفة الوزن. ACM Trans. Database Syst. 44, 3, Article 9 (2019), 46 صفحة. https://doi.org/10.1145/3323991
  • 24 Philippe Dobbelaere وKyumars Sheykh Esmaili. 2017. Kafka مقابل RabbitMQ: دراسة مقارنة بين تطبيقين مرجعيين للنشر/الاشتراك في المجال الصناعي: ورقة صناعية (DEBS ‘17). Association for Computing Machinery، نيويورك، نيويورك، الولايات المتحدة الأمريكية، 227–238. https://doi.org/10.1145/3093742.3093908
  • 25 وثائق LLVM. 2024. المتجهة التلقائية في LLVM. استُرجع في 2024-06-20 من https://llvm.org/docs/Vectorizers.html
  • 26 Siying Dong و Andrew Kryczka و Yanqin Jin و Michael Stumm. 2021. ‏RocksDB: تطور أولويات التطوير في مخزن مفتاح-قيمة يخدم تطبيقات على نطاق واسع. ACM Transactions on Storage 17، 4، المقالة 26 (2021)، 32 صفحة. https://doi.org/10.1145/3483840
  • 27 Markus Dreseler، Martin Boissier، Tilmann Rabl، وMatthias Ufacker. 2020. قياس نقاط الاختناق في TPC-H وتحسيناتها. Proc. VLDB Endow. 13، 8 (2020)، 1206–1220. https://doi.org/10.14778/3389133.3389138
  • 28 Ted Dunning. 2021. t-digest: تقديرات فعّالة للتوزيعات. Software Impacts 7 (2021). https://doi.org/10.1016/j.simpa.2020.100049
  • 29 Martin Faust, Martin Boissier, Marvin Keller, David Schwalb, Holger Bischof, Katrin Eisenreich, Franz Färber, and Hasso Plattner. 2016. تقليل البصمة وفرض التفرد باستخدام فهارس hash في SAP HANA. في Database and Expert Systems Applications. 137–151. https://doi.org/10.1007/978-3-319-44406- 2_11
  • 30 Philippe Flajolet, Eric Fusy, Olivier Gandouet, and Frederic Meunier. 2007. HyperLogLog: تحليل خوارزمية شبه مثالية لتقدير الكاردينالية. ضمن AofA: Analysis of Algorithms، المجلد DMTCS Proceedings vol. AH، مؤتمر 2007 لتحليل الخوارزميات (AofA 07). Discrete Mathematics and Theoretical Computer Science، 137–156. https://doi.org/10.46298/dmtcs.3545
  • 31 هيكتور غارسيا-مولينا، وجيفري د. أولمان، وجنيفر ويدوم. 2009. نظم قواعد البيانات - الكتاب الكامل (الطبعة الثانية).
  • 32 Pawan Goyal, Harrick M. Vin, and Haichen Chen. 1996. الاصطفاف العادل وقت البدء: خوارزمية جدولة لشبكات تبديل الحزم للخدمات المتكاملة. 26, 4 (1996), 157–168. https://doi.org/10.1145/248157.248171
  • 33 غوتس غريفه. 1993. تقنيات تقييم الاستعلامات لقواعد البيانات الكبيرة. ACM Comput. Surv. 25, 2 (1993), 73–169. https://doi.org/10.1145/152610.152611
  • 34 Jean-François Im, Kishore Gopalakrishna, Subbu Subramaniam, Mayank Shrivastava, Adwait Tumbde, Xiaotian Jiang, Jennifer Dai, Seunghyun Lee, Neha Pawar, Jialiang Li, and Ravi Aringunram. 2018. Pinot: OLAP الآني لـ 530 مليون مستخدم. في أعمال المؤتمر الدولي لعام 2018 حول إدارة البيانات (Houston, TX, USA) (SIGMOD ‘18). جمعية الآلات الحاسوبية، New York, NY, USA، 583–594. https://doi.org/10.1145/3183713.3190661
  • 35 ISO/IEC 9075-9:2001 2001. تقنية المعلومات — لغة قواعد البيانات — SQL — الجزء 9: إدارة البيانات الخارجية (SQL/MED). معيار. المنظمة الدولية للتوحيد القياسي.
  • 36 Paras Jain، Peter Kraft، Conor Power، Tathagata Das، Ion Stoica، و Matei Zaharia. 2023. Analyzing and Comparing Lakehouse Storage Systems. CIDR.
  • 37 Project Jupyter. 2024. Jupyter Notebooks. تم الاسترجاع بتاريخ 2024-06-20 من https: //jupyter.org/
  • 38 Timo Kersten, Viktor Leis, Alfons Kemper, Thomas Neumann, Andrew Pavlo، وPeter Boncz. 2018. كل ما أردت دائمًا معرفته عن الاستعلامات المترجمة والموجَّهة ولكنك كنت تخشى السؤال عنه. Proc. VLDB Endow. 11, 13 (سبتمبر 2018)، 2209–2222. https://doi.org/10.14778/3275366.3284966
  • 39 Changkyu Kim, Jatin Chhugani, Nadathur Satish, Eric Sedlar, Anthony D. Nguyen, Tim Kaldewey, Victor W. Lee, Scott A. Brandt, and Pradeep Dubey. 2010. FAST: بحث شجري سريع ومراعٍ لبنية العتاد على وحدات CPU وGPU الحديثة. ضمن أعمال مؤتمر ACM SIGMOD الدولي لعام 2010 حول إدارة البيانات (إنديانابوليس، إنديانا، الولايات المتحدة الأمريكية) (SIGMOD ‘10). جمعية آلات الحوسبة، نيويورك، نيويورك، الولايات المتحدة الأمريكية، 339–350. https://doi.org/10.1145/1807167.1807206
  • 40 Donald E. Knuth. 1973. فن برمجة الحاسوب، المجلد الثالث: الفرز والبحث. Addison-Wesley.
  • 41 André Kohn، وViktor Leis، وThomas Neumann. 2018. Adaptive Execution of Compiled Queries. في وقائع 2018 IEEE 34th International Conference on Data Engineering (ICDE). 197–208. https://doi.org/10.1109/ICDE.2018.00027
  • 42 Andrew Lamb, Matt Fuller, Ramakrishna Varadarajan, Nga Tran, Ben Vandiver, Lyric Doshi، و Chuck Bear. 2012. The Vertica Analytic Database: C-Store 7 Years Later. Proc. VLDB Endow. 5, 12 (أغسطس 2012)، 1790–1801. https://doi.org/10. 14778/2367502.2367518
  • 43 Harald Lang, Tobias Mühlbauer, Florian Funke, Peter A. Boncz, Thomas Neumann, and Alfons Kemper. 2016. Data Blocks: Hybrid OLTP and OLAP on Compressed Storage using both Vectorization and Compilation. ضمن وقائع المؤتمر الدولي لعام 2016 حول إدارة البيانات (سان فرانسيسكو، كاليفورنيا، الولايات المتحدة الأمريكية) (SIGMOD ‘16). رابطة آلات الحوسبة، نيويورك، نيويورك، الولايات المتحدة الأمريكية، 311–326. https://doi.org/10.1145/2882903.2882925
  • 44 Viktor Leis، Peter Boncz، Alfons Kemper، وThomas Neumann. 2014. Morseldriven parallelism: a NUMA-aware query evaluation framework for the manycore age. في وقائع المؤتمر الدولي ACM SIGMOD لعام 2014 حول إدارة البيانات (Snowbird، Utah، الولايات المتحدة الأمريكية) (SIGMOD ‘14). رابطة آلات الحوسبة، New York، NY، الولايات المتحدة الأمريكية، 743–754. https://doi.org/10.1145/2588555. 2610507
  • 45 فيكتور لايس، ألفونس كيمبر، وتوماس نويمان. 2013. شجرة الراديكس التكيفية: فهرسة ARTful لقواعد البيانات الموجودة في الذاكرة الرئيسية. في المؤتمر الدولي التاسع والعشرين لهندسة البيانات (ICDE) لعام 2013 التابع لـ IEEE. 38–49. https://doi.org/10.1109/ICDE. 2013.6544812
  • 46 Chunwei Liu، Anna Pavlenko، Matteo Interlandi، وBrandon Haynes. 2023. نظرة متعمقة على التنسيقات المفتوحة الشائعة لنظم إدارة قواعد البيانات التحليلية. 16، 11 (يوليو 2023)، 3044–3056. https://doi.org/10.14778/3611479.3611507
  • 47 Zhenghua Lyu, Huan Hubert Zhang, Gang Xiong, Gang Guo, Haozhou Wang, Jinbao Chen, Asim Praveen, Yu Yang, Xiaoming Gao, Alexandra Wang, Wen Lin, Ashwin Agrawal, Junfeng Yang, Hao Wu, Xiaoliang Li, Feng Guo, Jiang Wu, Jesse Zhang, and Venkatesh Raghavan. 2021. Greenplum: A Hybrid Database for Transactional and Analytical Workloads (SIGMOD ‘21). Association for Computing Machinery, New York, NY, USA, 2530–2542. https: //doi.org/10.1145/3448016.3457562
  • 48 Roger MacNicol و Blaine French. 2004. Sybase IQ Multiplex - Designed for Analytics. في Proceedings of the Thirtieth International Conference on Very Large Data Bases - Volume 30 ‏(Toronto, Canada) ‏(VLDB ‘04). VLDB Endowment، 1227–1230.
  • 49 Sergey Melnik, Andrey Gubarev, Jing Jing Long, Geofrey Romer, Shiva Shivakumar, Matt Tolton, Theo Vassilakis, Hossein Ahmadi, Dan Delorey, Slava Min, Mosha Pasumansky، وJef Shute. 2020. Dremel: A Decade of Interactive SQL Analysis at Web Scale. Proc. VLDB Endow. 13, 12 (aug 2020), 3461–3472. https://doi.org/10.14778/3415478.3415568
  • 50 Microsoft. 2024. Kusto Query Language. تم الاسترجاع بتاريخ 2024-06-20 من https: //github.com/microsoft/Kusto-Query-Language
  • 51 Guido Moerkotte. 1998. التجميعات المادية الصغيرة: بنية فهرس خفيفة الوزن لمستودعات البيانات. في وقائع المؤتمر الدولي الرابع والعشرين لقواعد البيانات الضخمة جدًا (VLDB ‘98). 476–487.
  • 52 Jalal Mostafa وSara Wehbi وSuren Chilingaryan وAndreas Kopmann. 2022. SciTS: A Benchmark for Time-Series Databases in Scientifc Experiments and Industrial Internet of Things. في وقائع المؤتمر الدولي الرابع والثلاثين لإدارة قواعد البيانات العلمية والإحصائية (SSDBM ‘22). المقالة 12. https: //doi.org/10.1145/3538712.3538723
  • 53 Thomas Neumann. 2011. efficiently Compiling efficient Query Plans for Modern Hardware. Proc. VLDB Endow. 4, 9 (jun 2011), 539–550. https://doi.org/10.14778/ 2002938.2002940
  • 54 Thomas Neumann و Michael J. Freitag. 2020. Umbra: نظام قائم على الأقراص بأداء مماثل لأداء الذاكرة. في المؤتمر العاشر للبحث في أنظمة البيانات المبتكرة، CIDR 2020، أمستردام، هولندا، 12-15 يناير 2020، وقائع المؤتمر المنشورة عبر الإنترنت. www.cidrdb.org. http://cidrdb.org/cidr2020/papers/p29-neumanncidr20.pdf
  • 55 Thomas Neumann، وTobias Mühlbauer، وAlfons Kemper. 2015. Fast Serializable Multi-Version Concurrency Control for Main-Memory Database Systems. ضمن Proceedings of the 2015 ACM SIGMOD International Conference on Management of Data (Melbourne, Victoria, Australia) (SIGMOD ‘15). Association for Computing Machinery، New York, NY, USA، 677–689. https://doi.org/10.1145/2723372. 2749436
  • 56 ‏LevelDB على GitHub. 2024. LevelDB. تم الاسترجاع بتاريخ 2024-06-20 من https://github. com/google/leveldb
  • 57 Patrick O’Neil, Elizabeth O’Neil, Xuedong Chen, and Stephen Revilak. 2009. The Star Schema Benchmark and Augmented Fact Table Indexing. ضمن Performance Evaluation and Benchmarking. Springer Berlin Heidelberg, 237–252. https: //doi.org/10.1007/978-3-642-10424-4_17
  • 58 Patrick E. O’Neil, Edward Y. C. Cheng, Dieter Gawlick, و Elizabeth J. O’Neil. 1996. The log-structured Merge-Tree (LSM-tree). Acta Informatica 33 (1996), 351–385. https://doi.org/10.1007/s002360050048
  • 59 Diego Ongaro وJohn Ousterhout. 2014. ضمن In Search of an Understandable Consensus Algorithm. في Proceedings of the 2014 USENIX Conference on USENIX Annual Technical Conference (USENIX ATC’14). 305–320. https://doi.org/doi/10. 5555/2643634.2643666
  • 60 باتريك أونيل، إدوارد تشينغ، ديتر غافليك، وإليزابيث أونيل. 1996. The Log-Structured Merge-Tree (LSM-Tree). Acta Inf. 33, 4 (1996)، 351–385. https: //doi.org/10.1007/s002360050048
  • 61 Pandas. 2024. Pandas Dataframes. استُرجِع في 2024-06-20 من https://pandas. pydata.org/
  • 62 Pedro Pedreira، Orri Erling، Masha Basmanova، Kevin Wilfong، Laith Sakka، Krishna Pai، Wei He، وBiswapesh Chattopadhyay. 2022. Velox: Meta’s Unified Execution Engine. Proc. VLDB Endow. 15، 12 (أغسطس 2022)، 3372–3384. https: //doi.org/10.14778/3554821.3554829
  • 63 Tuomas Pelkonen, Scott Franklin, Justin Teller, Paul Cavallaro, Qi Huang, Justin Meza، وKaushik Veeraraghavan. 2015. Gorilla: A Fast, Scalable, in-Memory Time Series Database. Proceedings of the VLDB Endowment 8, 12 (2015), 1816–1827. https://doi.org/10.14778/2824032.2824078
  • 64 Orestis Polychroniou، Arun Raghavan، و Kenneth A. Ross. 2015. Rethinking SIMD Vectorization for In-Memory Databases. في وقائع المؤتمر الدولي ACM SIGMOD لعام 2015 حول إدارة البيانات (SIGMOD ‘15). 1493–1508. https://doi.org/10.1145/2723372.2747645
  • 65 PostgreSQL. 2024. PostgreSQL - Foreign Data Wrappers. تم الاسترجاع بتاريخ 2024-06-20 من https://wiki.postgresql.org/wiki/Foreign&#95;data&#95;wrappers
  • 66 Mark Raasveldt، Pedro Holanda، Tim Gubner، و Hannes Mühleisen. 2018. اعتبار المقارنة المعيارية العادلة أمرًا صعبًا: المزالق الشائعة في اختبار أداء قواعد البيانات. في وقائع ورشة عمل اختبار أنظمة قواعد البيانات (هيوستن، تكساس، الولايات المتحدة الأمريكية) (DBTest’18). المقالة 2، 6 صفحات. https://doi.org/10.1145/3209950.3209955
  • 67 Mark Raasveldt و Hannes Mühleisen. 2019. DuckDB: قاعدة بيانات تحليلية مضمنة (SIGMOD ‘19). رابطة آلات الحوسبة، نيويورك، نيويورك، الولايات المتحدة الأمريكية، 1981–1984. https://doi.org/10.1145/3299869.3320212
  • 68 Jun Rao و Kenneth A. Ross. 1999. الفهرسة المراعية للذاكرة المخبئية لدعم اتخاذ القرار في الذاكرة الرئيسية. في وقائع المؤتمر الدولي الخامس والعشرين لقواعد البيانات الضخمة جدًا (VLDB ‘99). San Francisco, CA, USA, 78–89.
  • 69 Navin C. Sabharwal و Piyush Kant Pandey. 2020. Working with Prometheus Query Language (PromQL). ضمن Monitoring Microservices and Containerized Applications. https://doi.org/10.1007/978-1-4842-6216-0&#95;5
  • 70 Todd W. Schneider. 2022. بيانات سيارات الأجرة ومركبات النقل المأجور في مدينة نيويورك. استُرجع في 2024-06-20 من https://github.com/toddwschneider/nyc-taxi-data
  • 71 Mike Stonebraker، Daniel J. Abadi، Adam Batkin، Xuedong Chen، Mitch Cherniack، Miguel Ferreira، Edmond Lau، Amerson Lin، Sam Madden، Elizabeth O’Neil، Pat O’Neil، Alex Rasin، Nga Tran، وStan Zdonik. 2005. C-Store: A Column-Oriented DBMS. في وقائع المؤتمر الدولي الحادي والثلاثين لقواعد البيانات كبيرة الحجم جدًا (VLDB ‘05). 553–564.
  • 72 Teradata. 2024. Teradata Database. تم الوصول إليه في 2024-06-20 من https://www. teradata.com/resources/datasheets/teradata-database
  • 73 Frederik Transier. 2010. Algorithms and Data Structures for In-Memory Text Search Engines. رسالة دكتوراه. https://doi.org/10.5445/IR/1000015824
  • 74 Adrian Vogelsgesang, Michael Haubenschild, Jan Finis, Alfons Kemper, Viktor Leis, Tobias Muehlbauer, Thomas Neumann, and Manuel Then. 2018. Get Real: How Benchmarks Fail to Represent the Real World. في وقائع ورشة عمل اختبار أنظمة قواعد البيانات (Houston, TX, USA) (DBTest’18). المقالة 1، 6 صفحات. https://doi.org/10.1145/3209950.3209952
  • 75 موقع LZ4. 2024. LZ4. تم الاسترجاع في 2024-06-20 من https://lz4.org/
  • 76 الموقع الإلكتروني لـ PRQL. 2024. PRQL. تم الاطلاع عليه في 2024-06-20 من https://prql-lang.org 77 Till Westmann, Donald Kossmann, Sven Helmer, and Guido Moerkotte. 2000. The Implementation and Performance of Compressed Databases. SIGMOD Rec.
  • 29, 3 (سبتمبر 2000)، 55–67. https://doi.org/10.1145/362084.362137 78 Fangjin Yang, Eric Tschetter, Xavier Léauté, Nelson Ray, Gian Merlino, and Deep Ganguli. 2014. Druid: مخزن بيانات تحليلي آني. في وقائع المؤتمر الدولي ACM SIGMOD لعام 2014 حول إدارة البيانات (سنوبيرد، يوتا، الولايات المتحدة الأمريكية) (SIGMOD ‘14). رابطة آلات الحوسبة، نيويورك، نيويورك، الولايات المتحدة الأمريكية، 157–168. https://doi.org/10.1145/2588555.2595631
  • 79 Tianqi Zheng، Zhibin Zhang، وXueqi Cheng. 2020. SAHA: A String Adaptive Hash Table for Analytical Databases. Applied Sciences 10، 6 (2020). https: //doi.org/10.3390/app10061915
  • 80 Jingren Zhou و Kenneth A. Ross. 2002. تنفيذ عمليات قاعدة البيانات باستخدام تعليمات SIMD. في وقائع مؤتمر ACM SIGMOD الدولي لإدارة البيانات لعام 2002 (SIGMOD ‘02). 145–156. https://doi.org/10. 1145/564691.564709
  • 81 Marcin Zukowski وSandor Heman وNiels Nes وPeter Boncz. 2006. Super-Scalar RAM-CPU Cache Compression. في وقائع المؤتمر الدولي الثاني والعشرين لهندسة البيانات (ICDE ‘06). 59. https://doi.org/10.1109/ICDE. 2006.150
آخر تعديل في ٢٩ يونيو ٢٠٢٦