- نشر تدفقات البيانات أو الاشتراك فيها.
- تنظيم تخزين متحمّل للأعطال.
- معالجة التدفقات فور توفّرها.
إنشاء جدول
kafka_broker_list— قائمة من الوسطاء مفصولة بفواصل (على سبيل المثال،localhost:9092).kafka_topic_list— قائمة بموضوعات Kafka.kafka_group_name— مجموعة من مستهلكي Kafka. تُتتبَّع إزاحات القراءة لكل مجموعة بشكل منفصل. إذا كنت لا تريد تكرار الرسائل في العنقود، فاستخدم اسم المجموعة نفسه في كل مكان.kafka_format— تنسيق الرسائل. يستخدم نفس الصياغة المستخدمة في دالة SQL FORMAT، مثلJSONEachRow. لمزيد من المعلومات، راجع قسم التنسيقات.
kafka_security_protocol- البروتوكول المستخدم للتواصل مع الوسطاء. القيم الممكنة:plaintext,ssl,sasl_plaintext,sasl_ssl.kafka_sasl_mechanism- آلية SASL المستخدمة للمصادقة. القيم الممكنة:GSSAPI,PLAIN,SCRAM-SHA-256,SCRAM-SHA-512,OAUTHBEARER.kafka_sasl_username- اسم مستخدم SASL للاستخدام مع الآليتينPLAINوSASL-SCRAM-...kafka_sasl_password- كلمة مرور SASL للاستخدام مع الآليتينPLAINوSASL-SCRAM-...kafka_schema— معلمة يجب استخدامها إذا كانت الصيغة تتطلب تعريف مخطط. على سبيل المثال، يتطلب Cap’n Proto مسار ملف المخطط واسم الكائن الجذرschema.capnp:Message.kafka_schema_registry_skip_bytes— عدد البايتات التي يجب تخطيها من بداية كل رسالة عند استخدام schema registry مع رؤوس envelope (مثل AWS Glue Schema Registry الذي يتضمن envelope بحجم 19 بايتًا). النطاق:[0, 255]. القيمة الافتراضية:0.kafka_num_consumers— عدد المستهلكين لكل جدول. حدِّد عددًا أكبر من المستهلكين إذا كان معدل النقل لمستهلك واحد غير كافٍ. يجب ألا يتجاوز العدد الإجمالي للمستهلكين عدد partitions في الـ topic، إذ لا يمكن إسناد أكثر من مستهلك واحد لكل partition، كما يجب ألا يزيد على عدد الأنوية الفعلية على الخادم الذي نُشر عليه ClickHouse. القيمة الافتراضية:1.kafka_max_block_size— الحد الأقصى لحجم الدفعة (بالرسائل) لكل poll. القيمة الافتراضية: max_insert_block_size.kafka_skip_broken_messages— مقدار سماحية محلل رسائل Kafka تجاه الرسائل غير المتوافقة مع المخطط في كل block. إذا كانتkafka_skip_broken_messages = Nفإن engine يتخطى N من رسائل Kafka التي يتعذر parse لها (الرسالة تعادل row واحدة من البيانات). القيمة الافتراضية:0.kafka_commit_every_batch— نفِّذ commit لكل batch تم استهلاكها ومعالجتها بدلًا من commit واحد بعد كتابة block كامل. القيمة الافتراضية:0.kafka_client_id— معرّف Client. يكون فارغًا افتراضيًا.kafka_poll_timeout_ms— المهلة الزمنية لعملية poll واحدة من Kafka. القيمة الافتراضية: stream_poll_timeout_ms.kafka_poll_max_batch_size— الحد الأقصى لعدد الرسائل التي يمكن جلبها في Kafka poll واحدة. القيمة الافتراضية: max_block_size.kafka_flush_interval_ms— المهلة الزمنية لتفريغ البيانات من Kafka. القيمة الافتراضية: stream_flush_interval_ms.kafka_consumer_reschedule_ms— فترة إعادة الجدولة عند توقف stream processing في Kafka (على سبيل المثال، عندما لا تتوفر رسائل للاستهلاك). يتحكم هذا الإعداد في التأخير قبل أن يعيد consumer محاولة polling. يجب ألا تتجاوز هذه القيمةkafka_consumers_pool_ttl_ms. القيمة الافتراضية:500ميلي ثانية.kafka_thread_per_consumer— يوفّر thread مستقلًا لكل consumer. عند التمكين، يقوم كل consumer بتفريغ البيانات بشكل مستقل، in parallel (وإلا فستُدمج rows من عدة consumers لتشكيل block واحد). القيمة الافتراضية:0.kafka_handle_error_mode— كيفية التعامل مع errors في Kafka engine. القيم الممكنة: default (سيتم طرح الاستثناء إذا فشلنا في parse رسالة)، stream (سيتم حفظ رسالة الاستثناء والرسالة الخام في virtual columns_errorو_raw_message)، dead_letter_queue (سيتم حفظ البيانات المرتبطة بالخطأ في system.dead_letter_queue).kafka_commit_on_select— نفِّذ commit للرسائل عند تنفيذ استعلام select. القيمة الافتراضية:false.kafka_consumer_acquire_timeout_ms— المهلة الزمنية بالميلي ثانية للحصول على Kafka consumer أثناء استعلاماتSELECTالمباشرة على جدول من نوعKafka2(مع تخزين offset مستند إلى Keeper). عند تشغيل عدة استعلاماتSELECTمباشرة ومتزامنة على الجدول نفسه، يجب أن ينتظر كل منها حتى يصبح المستهلكون متاحين. تمنع هذه المهلة حالات deadlocks عندما تحتفظ queries بمجموعات فرعية مختلفة من المستهلكين. القيمة الافتراضية:30000.kafka_max_rows_per_message— الحد الأقصى لعدد rows التي تُكتب في رسالة kafka واحدة للصيغ المعتمدة على row. القيمة الافتراضية:1.kafka_autodetect_client_rack— يضبط تلقائيًا المعلَمةclient.rackفيlibrdkafkaلتفضيل نسخ Kafka المتماثلة الأقرب. المصادر المدعومة:AWS_ZONE_IDلمعرّف منطقة التوافر في AWS IMDSv2، على سبيل المثالeuc1-az1;AWS_ZONE_NAMEلاسم منطقة التوافر في AWS IMDSv2، على سبيل المثالeu-central-1a;GCP_ZONEلمنطقة خدمة البيانات الوصفية في GCP، على سبيل المثالeurope-central2-a;CLICKHOUSEلاستخدام الاكتشاف الداخلي في ClickHouse، والذي قد يعتمد على البيانات الوصفية السحابية أو الإعدادات;AWS_ZONE_NAME_THEN_GCP_ZONEلتجربةAWS_ZONE_NAMEثمGCP_ZONE. القيمة الافتراضية: سلسلة فارغة، معطّل. نصيحة: تستخدم البيئات المختلفة تنسيقات مختلفة لمناطق التوافر. يستخدم Amazon MSK عادةً معرّفات المناطق، لذا يُفضَّلAWS_ZONE_ID. ويستخدم Confluent Cloud عادةً أسماء المناطق، لذا يُفضَّلAWS_ZONE_NAME. إذا لم تكن متأكدًا، فاستخدمAWS_ZONE_NAME_THEN_GCP_ZONEأو تحقّق من قيمةbroker.rackفي عنقودك. ملاحظة: يجب تهيئة وسطاء Kafka باستخدامbroker.rackوreplica.selector.class=org.apache.kafka.common.replica.RackAwareReplicaSelector.kafka_compression_codec— برنامج ترميز الضغط المستخدَم لإنتاج الرسائل. القيم المدعومة: سلسلة فارغة،none،gzip،snappy،lz4،zstd. في حالة السلسلة الفارغة، لا يضبط الجدول برنامج ترميز الضغط، وبالتالي ستُستخدم القيم من ملفات الإعداد أو القيمة الافتراضية منlibrdkafka. القيمة الافتراضية: سلسلة فارغة.kafka_compression_level— مَعلَمة مستوى الضغط للخوارزمية المحددة بواسطة kafka_compression_codec. تؤدي القيم الأعلى إلى ضغط أفضل على حساب زيادة استخدام CPU. ويعتمد النطاق القابل للاستخدام على الخوارزمية:[0-9]لـgzip؛ و[0-12]لـlz4؛ و0فقط لـsnappy؛ و[0-12]لـzstd؛ و-1= مستوى الضغط الافتراضي المعتمد على برنامج الترميز. القيمة الافتراضية:-1.kafka_map_virtual_columns_on_write— إذا كان مُمكّنًا، فستُربَط الأعمدة ذات الأسماء الخاصة_keyو_timestampو_headers.nameو_headers.valueفي مخطط الجدول ببيانات Kafka الوصفية المقابلة للرسالة عندINSERT، وتُستبعَد من حمولة الرسالة. راجع ربط الأعمدة ببيانات Kafka الوصفية للرسائل. القيمة الافتراضية:false.
لا يدعم محرك جدول Kafka الأعمدة التي تحتوي على قيمة افتراضية. وإذا كنت بحاجة إلى أعمدة ذات قيمة افتراضية، فيمكنك إضافتها على مستوى العرض المادي (انظر أدناه).
الوصف
SELECT مفيدًا كثيرًا لقراءة الرسائل (إلا لأغراض debugging)، لأن كل رسالة لا يمكن قراءتها إلا مرة واحدة فقط. والأكثر عملية هو إنشاء تدفقات real-time باستخدام العرض المادي. وللقيام بذلك:
- استخدم الـ محرك لإنشاء مستهلك Kafka واعتبره تدفق بيانات.
- أنشئ جدولًا بالبنية المطلوبة.
- أنشئ العرض المادي يحوّل البيانات من الـ محرك ويضعها في جدول أُنشئ مسبقًا.
MATERIALIZED VIEW إلى الـ محرك، يبدأ في جمع البيانات في الخلفية. يتيح لك ذلك الاستمرار في تلقي الرسائل من Kafka وتحويلها إلى الـ تنسيق المطلوب باستخدام SELECT.
يمكن لجدول Kafka واحد أن يحتوي على أي عدد تريده من العرض المادي. وهي لا تقرأ البيانات من جدول Kafka مباشرةً، بل تتلقى سجلات جديدة (على هيئة blocks). وبهذه الطريقة يمكنك الكتابة إلى عدة جداول بمستويات مختلفة من التفصيل (مع التجميع - aggregation أو بدونه).
مثال:
ALTER، فنوصي بتعطيل العرض المادي لتجنب حدوث أي تعارض بين الجدول الهدف والبيانات التي ينتجها العرض.
التهيئة
<kafka>) ومفتاح على مستوى الـموضوع (ضمن <kafka><kafka_topic>). تُطبَّق التهيئة العامة أولًا، ثم تُطبَّق التهيئة على مستوى الـموضوع (إن وُجدت).
_) بدلًا من النقطة في تكوين ClickHouse. على سبيل المثال، ستُكتب check.crcs=true على النحو التالي: <check_crcs>true</check_crcs>.
دعم Kerberos
security_protocol بالقيمة sasl_plaintext. ويكفي الحصول على تذكرة منح التذاكر الخاصة بـ Kerberos وتخزينها مؤقتًا عبر إمكانات نظام التشغيل.
يمكن لـ ClickHouse الاحتفاظ ببيانات اعتماد Kerberos باستخدام ملف keytab. راعِ العناصر الفرعية sasl_kerberos_service_name وsasl_kerberos_keytab وsasl_kerberos_principal.
مثال:
الأعمدة الافتراضية
_topic— موضوع Kafka. نوع البيانات:LowCardinality(String)._key— مفتاح الرسالة. نوع البيانات:String._offset— إزاحة الرسالة. نوع البيانات:UInt64._timestamp— الطابع الزمني للرسالة. نوع البيانات:Nullable(DateTime)._timestamp_ms— الطابع الزمني للرسالة بالمللي ثانية. نوع البيانات:Nullable(DateTime64(3))._partition— قسم موضوع Kafka. نوع البيانات:UInt64._headers.name— مصفوفة مفاتيح ترويسات الرسالة. نوع البيانات:Array(String)._headers.value— مصفوفة قيم ترويسات الرسالة. نوع البيانات:Array(String).
kafka_handle_error_mode='stream':
_raw_message- الرسالة الخام التي تعذّر تحليلها بنجاح. نوع البيانات:String._error- رسالة الاستثناء التي حدثت أثناء تعذّر التحليل. نوع البيانات:String.
_raw_message و _error إلا عند حدوث استثناء أثناء التحليل، ويظلان فارغين دائمًا إذا تم تحليل الرسالة بنجاح.
ربط الأعمدة بالبيانات الوصفية لرسائل Kafka
INSERT INTO، يستخدم محرك Kafka دائمًا عمودًا باسم _key (من النوع String) كمفتاح لرسالة Kafka وعمودًا باسم _timestamp (من النوع DateTime) كطابع زمني لرسالة Kafka، إذا كانت هذه الأعمدة موجودة في الجدول. وبشكل افتراضي، تظهر هذه الأعمدة أيضًا في حمولة الرسالة المُنتَجة إلى جانب الأعمدة الأخرى.
عند استخدام kafka_map_virtual_columns_on_write = 1، يتغير السلوك:
_key(النوعString) — يُربَط بمفتاح رسالة Kafka._timestamp(النوعDateTime) — يُربَط بالطابع الزمني لرسالة Kafka._headers.name(النوعArray(String)) و_headers.value(النوعArray(String)) — يُربَطان بترويسات رسالة Kafka. ويتحوّل كل زوج(_headers.name[i], _headers.value[i])إلى ترويسة Kafka واحدة. ونظرًا إلى أن_headers.nameو_headers.valueيشتركان في البادئة Nested_headers، يشترط ClickHouse أن يكون حجم المصفوفتين متطابقًا في كل صف.
{"event_json":"{\"a\":1}"}، والمفتاح session-42، والطابع الزمني الحالي، ورأسين source=api وtrace_id=abc-123.
دعم تنسيقات البيانات
- في التنسيقات المستندة إلى الصفوف، يمكن التحكم في عدد الصفوف في رسالة Kafka واحدة عبر تعيين
kafka_max_rows_per_message. - في التنسيقات المستندة إلى الكتل، لا يمكن تقسيم block إلى أجزاء أصغر، لكن يمكن التحكم في عدد الصفوف في block واحد باستخدام الإعداد العام max_block_size.
محرك لتخزين الإزاحات المعتمدة في ClickHouse Keeper
allow_experimental_kafka_offsets_storage_in_keeper مفعّلًا، فيمكن عندئذٍ تحديد إعدادين إضافيين لمحرك جدول Kafka:
- يحدّد
kafka_keeper_pathالمسار إلى الجدول في ClickHouse Keeper - يحدّد
kafka_replica_nameاسم النسخة المتماثلة في ClickHouse Keeper
insert، فسيُستهلك العدد نفسه من الرسائل، مما يتيح إزالة التكرار عند الحاجة.
مثال:
القيود المعروفة
- قد يؤدي حذف الجدول بسرعة ثم إعادة إنشائه، أو تحديد مسار ClickHouse Keeper نفسه لمحركات مختلفة، إلى حدوث مشكلات. وكأفضل ممارسة، يمكنك استخدام
{uuid}فيkafka_keeper_pathلتجنب تعارض المسارات. - لضمان القراءات القابلة للتكرار، لا يمكن استهلاك الرسائل من عدة أقسام على خيط تنفيذ واحد. ومن ناحية أخرى، يجب إجراء
pollعلى مستهلكي Kafka بانتظام للحفاظ على نشاطهم. ونتيجةً لهذين الشرطين، قررنا السماح بإنشاء عدة مستهلكين فقط إذا كانkafka_thread_per_consumerمُمكّنًا؛ وإلا فسيكون من المعقد جدًا تجنب المشكلات المرتبطة بإجراءpollللمستهلكين بانتظام.