الانتقال إلى المحتوى الرئيسي

تجاوز حد الذاكرة للاستعلام

بصفتك مستخدمًا جديدًا، قد يبدو ClickHouse في كثير من الأحيان أشبه بالسحر — فكل استعلام سريع للغاية، حتى عند العمل على أكبر مجموعات البيانات وأكثر الاستعلامات طموحًا. لكن من المؤكد أن الاستخدام الفعلي يختبر حتى حدود ClickHouse. وقد تنتج الاستعلامات التي تتجاوز حد الذاكرة عن عدد من الأسباب. وفي أغلب الأحيان، نرى عمليات join كبيرة أو عمليات تجميع على حقول ذات كاردينالية عالية. وإذا كان الأداء عاملًا حاسمًا وكانت هذه الاستعلامات مطلوبة، فإننا نوصي المستخدمين غالبًا ببساطة بزيادة الموارد — وهو ما تقوم به ClickHouse Cloud تلقائيًا وبسهولة لضمان بقاء استعلاماتك سريعة الاستجابة. ومع ذلك، ندرك أنه في البيئات self-managed، لا يكون هذا الأمر بسيطًا دائمًا، وربما لا يكون الأداء الأمثل مطلوبًا أصلًا. وفي هذه الحالة، تتوفر أمام المستخدمين بضعة خيارات.

التجميعات

بالنسبة إلى سيناريوهات التجميع أو الفرز كثيفة الاستهلاك للذاكرة، يمكن للمستخدمين استخدام الإعدادين max_bytes_before_external_group_by وmax_bytes_before_external_sort على التوالي. وقد نوقش الأول منهما بإسهاب هنا. باختصار، يضمن ذلك إمكانية ترحيل أي عمليات تجميع إلى القرص إذا تم تجاوز حد الذاكرة. سيؤثر هذا حتمًا في أداء الاستعلام، لكنه سيساعد على ضمان ألا تتسبب الاستعلامات في حدوث OOM. كما يساعد إعداد الفرز الثاني في معالجة مشكلات مماثلة تتعلق بعمليات الفرز كثيفة الاستهلاك للذاكرة. وقد يكون هذا مهمًا بشكل خاص في البيئات الموزعة، حيث تتلقى عقدة التنسيق استجابات مرتبة من الشظايا الفرعية. في هذه الحالة، قد يُطلب من الخادم المنسِّق فرز مجموعة بيانات أكبر من الذاكرة المتاحة له. باستخدام max_bytes_before_external_sort، يمكن السماح لعمليات الفرز بالترحيل إلى القرص. ويكون هذا الإعداد مفيدًا أيضًا في الحالات التي يستخدم فيها المستخدم ORDER BY بعد GROUP BY مع LIMIT، وخاصة عندما يكون الاستعلام موزعًا.

عمليات JOIN

بالنسبة إلى عمليات JOIN، يمكن للمستخدمين اختيار خوارزميات JOIN مختلفة، ما قد يساعد في تقليل الذاكرة المطلوبة. افتراضيًا، تستخدم عمليات JOIN خوارزمية hash join، التي توفر أكبر قدر من التكامل من حيث الميزات، وغالبًا ما تقدم أفضل أداء. وتحمّل هذه الخوارزمية الجدول الواقع على الجانب الأيمن من JOIN إلى جدول hash في الذاكرة، ثم تُقيِّم الجدول الواقع على الجانب الأيسر بالاستناد إليه. لذلك، ولتقليل استهلاك الذاكرة إلى الحد الأدنى، ينبغي للمستخدمين وضع الجدول الأصغر على الجانب الأيمن. ومع ذلك، يظل لهذا النهج قيود في الحالات التي تكون فيها الذاكرة عاملًا مقيِّدًا. في هذه الحالات، يمكن تمكين partial_merge join عبر الإعداد join_algorithm. وهذا مشتق من خوارزمية sort-merge، إذ يفرز أولًا الجدول الأيمن إلى blocks وينشئ لها فهرس min-max. ثم يفرز parts من الجدول الأيسر بحسب مفتاح الربط ويُجري join عليها مع الجدول الأيمن. ويُستخدم فهرس min-max لتخطي blocks غير المطلوبة من الجدول الأيمن. ويستهلك هذا النهج ذاكرة أقل، لكن على حساب الأداء. وبالانتقال بهذا المفهوم إلى مستوى أبعد، تتيح خوارزمية full_sorting_merge تنفيذ JOIN عندما يكون الجانب الأيمن كبيرًا جدًا ولا يتسع في الذاكرة، وتكون عمليات lookup غير ممكنة، مثل subquery معقد. في هذه الحالة، يُفرز كل من الجانبين الأيمن والأيسر على القرص إذا لم يتسعا في الذاكرة، ما يتيح ربط الجداول الكبيرة. منذ الإصدار 20.3، يدعم ClickHouse القيمة auto لإعداد join_algorithm. وهذا يوجّه ClickHouse إلى تطبيق نهج JOIN تكيّفي، حيث تُفضَّل خوارزمية hash join إلى أن يتم تجاوز حدود الذاكرة، وعندها تُجرَّب خوارزمية partial_merge. وأخيرًا، فيما يتعلق بعمليات JOIN، نشجّع القراء على فهم سلوك distributed joins وكيفية تقليل استهلاكها للذاكرة. يمكن العثور على مزيد من المعلومات هنا.
آخر تعديل في ٢٩ يونيو ٢٠٢٦