Skip to main content
قد تفشل عمليات الإدراج أحيانًا بسبب أخطاء مثل انتهاء المهلة. وعند فشلها، قد تكون البيانات قد أُدرجت بنجاح أو لا. يوضح هذا الدليل كيفية عمل إزالة التكرار عند إعادة محاولة الإدراج، بحيث لا تُدرج البيانات نفسها أكثر من مرة. عند إعادة محاولة الإدراج، يحاول ClickHouse التحقق مما إذا كانت البيانات قد أُدرجت بنجاح بالفعل. وإذا وُسِمت البيانات المُدرجة على أنها مكررة، فلن يُدرجها ClickHouse في الجدول الوجهة. ومع ذلك، سيظل المستخدم يتلقى حالة نجاح للعملية كما لو كانت البيانات قد أُدرجت بشكل طبيعي. تشمل إزالة التكرار عمليات الإدراج المتزامنة، وعمليات الإدراج غير المتزامنة، واستعلامات INSERT ... SELECT. يتحكم إعداد واحد، وهو deduplicate_insert، في عمليات الإدراج المتزامنة وغير المتزامنة. تتطلب INSERT ... SELECT عناية إضافية ولها إعداد خاص بها. راجع الإعدادات التي تتحكم في إزالة تكرار عمليات الإدراج.

القيود

حالة الإدراج غير المؤكدة

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

حد نافذة إزالة التكرار

إذا جرت أكثر من *_deduplication_window عملية إدراج أخرى أثناء تسلسل إعادة المحاولة، فقد لا تعمل إزالة التكرار كما هو مقصود. في هذه الحالة، قد تُدرَج البيانات نفسها عدة مرات.

الإعدادات التي تتحكم في إزالة التكرار

لا يزيل ClickHouse تكرار عملية إدراج إلا عند استيفاء الشرطين التاليين:
  1. أن يحتفظ الجدول الوجهة بسجل لإزالة التكرار. هذا إعداد على مستوى الجدول.
  2. أن تكون إزالة التكرار مفعّلة للاستعلام. هذا إعداد على مستوى الاستعلام.

إعدادات على مستوى الجدول

لا تدعم إزالة التكرار عند الإدراج سوى محرّكات *MergeTree. بالنسبة إلى محرّكات *ReplicatedMergeTree، يكون سجل إزالة التكرار مفعّلًا افتراضيًا، ويتحكم فيه الإعدادان replicated_deduplication_window وreplicated_deduplication_window_seconds. أما في محرّكات *MergeTree غير المكرّرة، فيتحكم في السجل الإعداد non_replicated_deduplication_window، الذي تكون قيمته 0 افتراضيًا. لذلك، لا يزيل جدول MergeTree العادي أي تكرار حتى تضبط تلك النافذة على قيمة موجبة. تحدّد الإعدادات أعلاه معلمات سجل إزالة التكرار للجدول. ويخزّن سجل إزالة التكرار عددًا محدودًا من block_ids`، وهي التي تحدد آلية عمل إزالة التكرار (انظر أدناه).
يُعدّ كل من replicated_deduplication_window_for_async_inserts وreplicated_deduplication_window_seconds_for_async_inserts إعدادين قديمين. تشترك عمليات الإدراج المتزامنة وغير المتزامنة الآن في سجل إزالة تكرار واحد، لذا يتحكم replicated_deduplication_window في كليهما. كانت الإعدادات القديمة تحدّ فقط دليل ClickHouse Keeper القديم، وهو أمر مهم أثناء ترقية تدريجية.

إعدادات على مستوى الاستعلام

يقبل deduplicate_insert ثلاث قيم:
  • enable — تُفعّل إزالة التكرار لاستعلام INSERT.
  • disable — تُعطّل إزالة التكرار لاستعلام INSERT.
  • backward_compatible_choice — يُفوَّض القرار إلى الإعدادات القديمة insert_deduplicate (عمليات الإدراج المتزامنة) وasync_insert_deduplicate (عمليات الإدراج غير المتزامنة).
لاحظ أن الاستعلام الذي يعمل مع deduplicate_insert = disable لا يكتب أي قيم block_id لكتله. ولا يمكن إزالة تكرار هذه البيانات لاحقًا، حتى إذا أعدت محاولة الإدراج باستخدام deduplicate_insert = enable. وينطبق الأمر نفسه عندما لا يحتفظ جدول الوجهة بسجل إزالة التكرار: فلا يُسجَّل شيء، وبالتالي لا يمكن مطابقة أي شيء عند إعادة المحاولة.

الأسبقية

  1. بالنسبة إلى استعلام INSERT ... SELECT، تكون الأولوية لـ deduplicate_insert_select. راجع إزالة التكرار لـ INSERT … SELECT.
  2. بالنسبة إلى جميع عمليات INSERT الأخرى، تكون الأولوية لـ deduplicate_insert.
  3. لا تُقرأ insert_deduplicate وasync_insert_deduplicate إلا عندما تكون قيمة deduplicate_insert هي backward_compatible_choice.

الإعدادات الموروثة والمتقادمة

اعتبارًا من الإصدار 26.2، تكون القيمة الافتراضية لـ deduplicate_insert هي enable. لذا، لم يعد ضبط insert_deduplicate = 0 يعطّل إزالة التكرار بمفرده. لتعطيل إزالة التكرار، اضبط deduplicate_insert = disable.
غيّر الإصدار 26.2 أيضًا القيم الافتراضية لـ async_insert وdeduplicate_blocks_in_dependent_materialized_views إلى مفعّلة. يتحكم إعداد compatibility في الإعدادات الثلاثة جميعها. إذا ضبطت compatibility على إصدار أقدم من 26.2، فستحتفظ هذه الإعدادات بقيمها الافتراضية القديمة: تصبح قيمة deduplicate_insert هي backward_compatible_choice، ما يُحيل القرار إلى insert_deduplicate وasync_insert_deduplicate. ويُطبَّق دائمًا أي إعداد تعيّنه صراحةً، ولا يتأثر مطلقًا بـ compatibility.

كيف تعمل إزالة التكرار عند الإدراج

عند إدراج البيانات في ClickHouse، تُقسَّم البيانات إلى كتل استنادًا إلى عدد الصفوف والبايتات. بالنسبة إلى الجداول التي تستخدم محركات *MergeTree، يُخصَّص لكل كتلة block_id فريد، وهو hash لبيانات تلك الكتلة. ويُستخدم block_id هذا كمفتاح فريد لعملية الإدراج. وإذا عُثر على block_id نفسه في سجل إزالة التكرار، تُعتبر الكتلة مكررة ولا تُدرج في الجدول. يعمل هذا النهج جيدًا عندما تحتوي عمليات الإدراج على بيانات مختلفة. ولكن إذا أُدرجت البيانات نفسها عدة مرات عن قصد، فستحتاج إلى استخدام الإعداد insert_deduplication_token للتحكم في عملية إزالة التكرار. يتيح لك هذا الإعداد تحديد رمز مميز فريد لكل عملية إدراج، ويستخدم ClickHouse هذا الرمز لتحديد ما إذا كانت البيانات مكررة. يتمتع insert_deduplication_token بأولوية أعلى: لا يستخدم ClickHouse قيمة hash للبيانات عند توفير الرمز. بالنسبة إلى استعلامات INSERT ... VALUES، يكون تقسيم البيانات المُدرجة إلى كتل حتميًا ويتحدد بواسطة الإعدادات. لذلك، ينبغي إعادة محاولة الإدراج باستخدام قيم الإعدادات نفسها التي استُخدمت في العملية الأولى.

إزالة التكرار في INSERT ... SELECT

بالنسبة إلى استعلامات INSERT ... SELECT، يجب أن يُرجع جزء SELECT البيانات نفسها وبالترتيب نفسه في كل محاولة. وإلا فستختلف الكتل وblock_ids، ولن يُتعرّف على إعادة المحاولة باعتبارها مكررة. لا يستطيع ClickHouse التحقق من عدم تغيّر البيانات المصدر، لكنه يستطيع التحقق مما إذا كان الاستعلام نفسه ينتج نتيجة قابلة لإعادة الإنتاج. يُعامل SELECT على أنه مستقر عند استيفاء الشرطين التاليين:
  • أن يتضمن الاستعلام عبارة ORDER BY ALL. لا يُتعرّف إلا على الصيغة الحرفية ORDER BY ALL. أما ORDER BY <expressions> العادي فلا يُتعرّف عليه، ولا يكون UNION من عمليتي SELECT أو أكثر مستقرًا أبدًا.
  • أن ينتهي مسار القراءة بتدفق واحد.
يُعدّ insert_deduplication_token غير الفارغ بديلًا مكافئًا للاستقرار، لأن الرمز، وليس البيانات، هو ما يعرّف عملية الإدراج في هذه الحالة. يحدد الإعداد deduplicate_insert_select الإجراء المتبع: يحترم كل من enable_when_possible وenable_even_for_bad_queries أيضًا deduplicate_insert: إذا كانت قيمته disable، فلن يُزال تكرار الاستعلام. يتجاوز force_enable قيمة deduplicate_insert. ضع في اعتبارك أنه قد يُحدَّث الجدول المحدد بين عمليات إعادة المحاولة. عندها يتصرف المساران بصورة متعاكسة:
  • بدون insert_deduplication_token، تُحسب block_ids من البيانات. تؤدي النتيجة المتغيرة إلى block_ids مختلفة، فلا تحدث إزالة التكرار، وتُدرج إعادة المحاولة البيانات الجديدة فوق أي بيانات كتبتها المحاولة الأولى بالفعل.
  • مع insert_deduplication_token، يعرّف الرمز وحده عملية الإدراج. يُتعرّف على إعادة المحاولة باعتبارها مكررة وتُسقط، حتى لو كانت ستدرج بيانات مختلفة.
اختر المسار الذي يتوافق مع المعنى الذي تريده لإعادة المحاولة. كذلك، عند إدراج كميات كبيرة من البيانات، قد يتجاوز عدد الكتل نافذة سجل إزالة التكرار، وعندها لن يعرف ClickHouse أن عليه إزالة تكرار الكتل.

إزالة التكرار لعمليات الإدراج غير المتزامنة

تُزال تكرارات عمليات الإدراج غير المتزامنة (async_insert، وهي مفعّلة افتراضيًا منذ الإصدار 26.2) عند إعادة المحاولة بالطريقة نفسها المتبعة لعمليات الإدراج المتزامنة. ويتحكم deduplicate_insert في كليهما، لذا لا حاجة إلى مفتاح منفصل. يشترك نوعا الإدراج أيضًا في سجل واحد لإزالة التكرار، ويحسبان block_ids بالطريقة نفسها. لذلك، يمكنك تبديل العميل بين عمليات الإدراج المتزامنة وغير المتزامنة دون التأثير في إزالة التكرار، وتبقى إعادة المحاولة المُرسلة في أحد الوضعين معروفة كتكرار لمحاولة أُرسلت في الوضع الآخر. كما يبقى نقل حمل عمل من عمليات الإدراج المتزامنة إلى غير المتزامنة آمنًا في جدول يعتمد على إزالة التكرار.
قبل الإصدار 26.2، كانت إزالة تكرار عمليات الإدراج غير المتزامنة معطّلة افتراضيًا، وكان يتحكم فيها async_insert_deduplicate. ولا يُقرأ هذا الإعداد الآن إلا عندما تكون قيمة deduplicate_insert هي backward_compatible_choice.

دقة إزالة التكرار

يجمع الخادم عدة عمليات إدراج غير متزامنة في دفعة واحدة ويكتب هذه الدفعة في جزء واحد أو أكثر، بواقع جزء واحد على الأقل لكل قيمة مميزة لمفتاح التقسيم. تعمل إزالة التكرار على مستوى استعلام المستخدم، وليس على مستوى الدفعة:
  • يضيف كل استعلام في قائمة الانتظار رمزاً واحداً لإزالة التكرار إلى الدفعة.
  • يكون الرمز إما قيمة insert_deduplication_token إذا وفّرها الاستعلام، أو hash للصفوف التي أضافها هذا الاستعلام.
  • لا يؤثر التجميع في دفعات في الرموز، كما لا يؤثر insert_deduplication_token في كيفية تجميع الاستعلامات ضمن دفعات.
ينتج عن ذلك نتيجتان:
  • إذا كان أحد الاستعلامات في دفعة مكرراً، فإن ClickHouse يزيل صفوف ذلك الاستعلام فقط. وتُدرج بقية الدفعة بشكل طبيعي. ولا يُتخطى الجزء بالكامل إلا إذا أُزيلت جميع صفوفه.
  • إذا حمل استعلامان في الدفعة نفسها الرمز ذاته، يُسقط الاستعلام الثاني قبل كتابة الجزء. ينطبق ذلك على كل تقسيم على حدة: فإذا كتب الاستعلامان صفوفاً في تقسيمات مختلفة، يُحتفظ بكليهما.
تحصي الأحداث DuplicatedAsyncInserts وSelfDuplicatedAsyncInserts في system.events هاتين الحالتين.

عمليات الإدراج غير المتزامنة والعروض المادية

تعمل إزالة التكرار في عمليات الإدراج غير المتزامنة بالتزامن مع العروض المادية التابعة. القاعدة بسيطة: كتلة واحدة تدخل، وكتلة واحدة تخرج. إذا حوّل الاستعلام الداخلي لعرض كتلة إدخال واحدة إلى كتلة إخراج واحدة، تعمل إزالة التكرار. أما إذا أصدر العرض كتلة ثانية، فيُطلق ClickHouse استثناء NOT_IMPLEMENTED. يصدر العرض كتلة ثانية عندما لا يعود الإخراج ضمن كتلة واحدة. يحدد max_block_size عدد الصفوف التي يمكن أن تتسع لها الكتلة. لا تضيف تحويلات الأعمدة أو التصفية أو التجميع صفوفًا، لذا تبقى دائمًا ضمن كتلة واحدة. يمكن أن يضيف JOIN صفوفًا. ويعمل ما دامت النتيجة لا تتجاوز max_block_size، ويفشل عند تجاوزها. للإدراج عبر عرض يصدر أكثر من كتلة واحدة، عيّن deduplicate_blocks_in_dependent_materialized_views = 0 أو استخدم عمليات الإدراج المتزامنة.

إزالة التكرار عند الإدراج مع العروض المادية

عندما يحتوي جدول على عرض مادي واحد أو أكثر، تُدرَج البيانات أيضًا في وجهة تلك العروض مع التحويلات المحددة. كما يُزال تكرار البيانات المُحوَّلة عند إعادة المحاولة أيضًا. ويُجري ClickHouse إزالة التكرار للعروض المادية بالطريقة نفسها التي يُجري بها إزالة التكرار للبيانات المُدرجة في الجدول الهدف. يمكنك التحكم في هذه العملية باستخدام الإعدادات التالية للجدول المصدر: تخضع إزالة التكرار في الجداول التابعة للعروض المادية أيضًا لإعداد ملف تعريف المستخدم deduplicate_blocks_in_dependent_materialized_views، وهو مُمكّن افتراضيًا منذ الإصدار 26.2. يجب أن يسمح كلا الإعدادين بذلك: يزيل deduplicate_insert تكرار البيانات المُدرجة في الجدول المصدر، ويزيل deduplicate_blocks_in_dependent_materialized_views أيضًا تكرار البيانات في الجداول التابعة. مكّن الإعدادين كليهما إذا كنت تريد إزالة التكرار الكاملة. عند إدراج كتل في الجداول التابعة للعروض المادية، يحسب ClickHouse قيمة block_id عبر إجراء تجزئة لسلسلة تجمع بين قيم block_id من الجدول المصدر ومعرّفات إضافية. ويضمن ذلك إزالة تكرار دقيقة داخل العروض المادية، بحيث يمكن تمييز البيانات استنادًا إلى عملية إدراجها الأصلية، بغض النظر عن أي تحويلات طُبّقت عليها قبل وصولها إلى جدول الوجهة التابع للعرض المادي.

أمثلة

الكتل المتطابقة بعد التحويلات في العرض المادي

الكتل المتطابقة التي جرى إنشاؤها أثناء التحويل داخل العرض المادي لا تُزال تكراراتها، لأنها تستند إلى بيانات مُدرجة مختلفة. إليك مثالًا:
تتيح لنا الإعدادات أعلاه إجراء استعلام على جدول يحتوي على سلسلة من الكتل، لا يحتوي كلٌّ منها إلا على صف واحد. هذه الكتل الصغيرة لا تُدمَج، وتبقى كما هي حتى تُدرَج في جدول. نحدد إزالة التكرار في العرض المادي صراحةً، رغم أنها مفعّلة افتراضيًا:
نرى هنا أنه تم إدراج جزأين في الجدول dst. كتلتان من SELECT — وجزآن عند الإدراج. تحتوي الأجزاء على بيانات مختلفة.
هنا نرى أنه تم إدراج جزأين في جدول mv_dst. يحتوي هذان الجزآن على البيانات نفسها، لكن لم تُزل التكرارات بينهما.
نرى هنا أنه عند إعادة محاولة عمليات الإدراج، تُزال جميع البيانات المكررة. وتعمل آلية إزالة التكرار مع الجدولين dst وmv_dst.

الكتل المتطابقة عند الإدراج

الإدراج:
باستخدام الإعدادات أعلاه، تنتج كتلتان من select– ونتيجةً لذلك، ينبغي أن تكون هناك كتلتان لإدخالهما في الجدول dst. ومع ذلك، نرى أنه لم تُدرج سوى كتلة واحدة في الجدول dst. حدث ذلك لأن الكتلة الثانية أُزيل تكرارها. فهي تحتوي على البيانات نفسها وعلى مفتاح إزالة التكرار block_id، الذي يُحتسب على شكل hash من البيانات المُدرجة. هذا السلوك ليس ما كان متوقعًا. مثل هذه الحالات نادرة الحدوث، لكنها ممكنة نظريًا. وللتعامل مع مثل هذه الحالات على نحو صحيح، يجب على المستخدم توفير insert_deduplication_token. لنُصلِح ذلك بالأمثلة التالية:

الكتل المتطابقة عند الإدراج باستخدام insert_deduplication_token

الإدراج:
أُدرجت كتلتان متطابقتان كما هو متوقع.
تُزال التكرارات من عملية الإدراج المُعادَة كما هو متوقّع.
تُعامَل عملية الإدراج تلك أيضًا على أنها مكررة، رغم أنها تحتوي على بيانات مُدرجة مختلفة. لاحظ أن insert_deduplication_token له أولوية أعلى: لا يستخدم ClickHouse قيمة hash للبيانات عند توفير insert_deduplication_token.

تُنتِج عمليات إدراج مختلفة البيانات نفسها بعد التحويل في الجدول الأساسي للعرض المادي

نُدرِج بيانات مختلفة في كل مرة. ومع ذلك، تُدرَج البيانات نفسها في جدول mv_dst. لا تُزال التكرارات لأن بيانات المصدر كانت مختلفة.

عمليات إدراج مختلفة من عروض مادية إلى جدول أساسي واحد ببيانات متكافئة

تم إدراج كتلتين متساويتين إلى الجدول mv_dst (كما هو متوقع).
تُزال تكرارات عملية إعادة المحاولة تلك في كلا الجدولين dst وmv_dst.
آخر تعديل في ٢٦ أغسطس ٢٠٢٦