الانتقال إلى المحتوى الرئيسي
يوفّر واجهة شبيهة بالجداول للقراءة فقط لجداول Apache Iceberg في Amazon S3 أو Azure أو HDFS أو المخزّنة محليًا.

الصيغة

المعاملات

يتطابق وصف المعاملات مع وصفها في دوال الجداول s3 وazureBlobStorage وHDFS وfile، على التوالي. يشير format إلى تنسيق ملفات البيانات في جدول Iceberg. بالنسبة إلى icebergS3، يمكن استخدام المعامل الاختياري extra_credentials لتمرير role_arn بغرض الوصول المستند إلى الدور في ClickHouse Cloud. راجع Secure S3 للاطلاع على خطوات الإعداد.

القيمة المُعادة

جدول ذو البنية المحددة لقراءة البيانات من جدول Iceberg المحدد.

مثال

يدعم ClickHouse حاليًا قراءة الإصدارين v1 وv2 من صيغة Iceberg عبر دوال الجداول icebergS3 وicebergAzure وicebergHDFS وicebergLocal، ومحركات الجداول IcebergS3 وicebergAzure وIcebergHDFS وIcebergLocal.

تعريف مجموعة مسماة

فيما يلي مثال على تهيئة مجموعة مسماة لتخزين URL وبيانات الاعتماد:

استخدام كتالوج بيانات

يمكن أيضًا استخدام جداول Iceberg مع كتالوجات بيانات متعددة، مثل REST Catalog، وAWS Glue Data Catalog، وUnity Catalog.
عند استخدام catalog، سيحتاج معظم المستخدمين إلى استخدام محرك قاعدة البيانات DataLakeCatalog، إذ يربط ClickHouse بالcatalog لاكتشاف الجداول. ويمكنك استخدام محرك قاعدة البيانات هذا بدلًا من إنشاء جداول منفصلة يدويًا باستخدام محرك الجدول IcebergS3.
لاستخدام ذلك، أنشئ جدولًا باستخدام المحرك IcebergS3 ووفّر الإعدادات اللازمة. على سبيل المثال، عند استخدام REST Catalog مع وحدة التخزين MinIO:
أو باستخدام AWS Glue Data Catalog مع S3:

تطور المخطط

في الوقت الحالي، وبمساعدة CH، يمكنك قراءة جداول Iceberg التي تغيّر مخططها بمرور الوقت. ونحن ندعم حاليًا قراءة الجداول التي أُضيفت إليها أعمدة وأُزيلت منها أعمدة، أو تغيّر ترتيب أعمدتها. ويمكنك أيضًا تحويل عمود تكون فيه القيمة إلزامية إلى عمود يُسمح فيه بالقيمة NULL. بالإضافة إلى ذلك، ندعم تحويل الأنواع المسموح به للأنواع البسيطة، وهي:  
  • int -> long
  • float -> double
  • decimal(P, S) -> decimal(P’, S) where P’ > P.
حاليًا، لا يمكن تغيير البُنى المتداخلة أو أنواع العناصر داخل Array وMap.

استبعاد الأقسام

يدعم ClickHouse استبعاد الأقسام أثناء استعلامات SELECT على جداول Iceberg، مما يساعد على تحسين أداء الاستعلامات عبر تخطي ملفات البيانات غير ذات الصلة. لتمكين استبعاد الأقسام، اضبط use_iceberg_partition_pruning = 1. لمزيد من المعلومات حول استبعاد أقسام Iceberg، راجع https://iceberg.apache.org/spec/#partitioning

السفر عبر الزمن

يدعم ClickHouse ميزة السفر عبر الزمن في جداول Iceberg، ما يتيح لك الاستعلام عن البيانات التاريخية استنادًا إلى طابع زمني محدد أو معرّف لقطة محدد.

معالجة الجداول ذات الصفوف المحذوفة

حاليًا، لا تُدعَم إلا جداول Iceberg التي تستخدم الحذف حسب الموضع. أساليب الحذف التالية غير مدعومة:

الاستخدام الأساسي

ملاحظة: لا يمكنك تحديد المعلَمين iceberg_timestamp_ms وiceberg_snapshot_id معًا في الاستعلام نفسه.

اعتبارات مهمة

  • اللقطات تُنشأ عادةً عندما:
  • تُكتب بيانات جديدة إلى الجدول
  • يُجرى نوعٌ ما من عمليات دمج البيانات
  • تغييرات المخطط لا تُنشئ لقطات عادةً - يؤدي ذلك إلى سلوكيات مهمة عند استخدام السفر عبر الزمن مع الجداول التي خضعت لتطوّر المخطط.

أمثلة على السيناريوهات

جميع السيناريوهات مكتوبة باستخدام Spark لأن CH لا يدعم الكتابة إلى جداول Iceberg بعد.

السيناريو 1: تغييرات المخطط من دون لقطات جديدة

تأمل تسلسل العمليات التالي:
نتائج الاستعلام عند طوابع زمنية مختلفة:
  • عند ts1 وts2: يظهر العمودان الأصليان فقط
  • عند ts3: تظهر الأعمدة الثلاثة جميعها، وتكون قيمة السعر في الصف الأول NULL

السيناريو 2: الاختلافات بين المخطط التاريخي والمخطط الحالي

قد يُظهر استعلام السفر عبر الزمن في الوقت الحالي مخططًا يختلف عن مخطط الجدول الحالي:
يحدث هذا لأن ALTER TABLE لا يُنشئ snapshot جديدة، ولكن بالنسبة إلى الجدول الحالي، يأخذ Spark قيمة schema_id من أحدث ملف metadata، وليس من snapshot.

السيناريو 3: اختلافات المخطط التاريخي والحالي

والنقطة الثانية هي أنه عند استخدام السفر عبر الزمن، لا يمكنك الحصول على حالة الجدول قبل كتابة أي بيانات فيه:
في ClickHouse، يكون السلوك متوافقًا مع Spark. يمكنك ببساطة اعتبار استعلامات Select في ClickHouse بدلًا من استعلامات Select في Spark، وسيعمل الأمر بالطريقة نفسها.

تحديد ملف البيانات الوصفية

عند استخدام الدالة الجدولية iceberg في ClickHouse، يحتاج النظام إلى تحديد ملف metadata.json الصحيح الذي يصف بنية جدول Iceberg. إليك كيف تتم عملية التحديد هذه:
  1. تحديد المسار مباشرةً: *إذا عيّنت iceberg_metadata_file_path، فسيستخدم النظام هذا المسار المحدد كما هو، من خلال دمجه مع مسار دليل جدول Iceberg.
  • عند توفير هذا الإعداد، يتم تجاهل جميع إعدادات resolution الأخرى.
  1. مطابقة UUID الجدول: *إذا تم تحديد iceberg_metadata_table_uuid، فسيقوم النظام بما يلي: *ينظر فقط إلى ملفات .metadata.json في دليل metadata *يُصفّي الملفات التي تحتوي على الحقل table-uuid المطابق لـ UUID الذي حددته (غير حساس لحالة الأحرف)
  2. البحث الافتراضي: *إذا لم يتم توفير أيٍّ من الإعدادين أعلاه، تصبح جميع ملفات .metadata.json في دليل metadata مرشحين

اختيار أحدث ملف

بعد تحديد الملفات المرشحة باستخدام القواعد المذكورة أعلاه، يحدّد النظام الملف الأحدث بينها:
  • إذا كان iceberg_recent_metadata_file_by_last_updated_ms_field مُمكّنًا:
  • يُختار الملف ذو أكبر قيمة last-updated-ms
  • بخلاف ذلك:
  • يُختار الملف ذو أعلى رقم إصدار
  • (يظهر الإصدار بصيغة V في أسماء الملفات المنسّقة على النحو V.metadata.json أو V-uuid.metadata.json)
ملاحظة: جميع الإعدادات المذكورة هي إعدادات الدالة الجدولية (وليست إعدادات عامة أو على مستوى الاستعلام) ويجب تحديدها كما هو موضح أدناه:
ملاحظة: رغم أن كتالوجات Iceberg تتولى عادةً تحديد البيانات الوصفية، فإن دالة الجدول iceberg في ClickHouse تفسّر مباشرةً الملفات المخزّنة في S3 على أنها جداول Iceberg، ولذلك من المهم فهم قواعد التحديد هذه.

ذاكرة التخزين المؤقت للبيانات الوصفية

يدعم محرك الجدول Iceberg والدالة الجدولية ذاكرة تخزين مؤقت للبيانات الوصفية تُخزّن معلومات ملفات manifest وmanifest list وملف metadata json. تُخزَّن ذاكرة التخزين المؤقت هذه في الذاكرة. ويجري التحكم في هذه الميزة عبر الإعداد use_iceberg_metadata_files_cache، وهي مفعّلة افتراضيًا.

الأسماء البديلة

أصبحت الدالة الجدولية iceberg اسمًا بديلًا لـ icebergS3.

الأعمدة الافتراضية

  • _path — مسار الملف. النوع: LowCardinality(String).
  • _file — اسم الملف. النوع: LowCardinality(String).
  • _size — حجم الملف بالبايت. النوع: Nullable(UInt64). إذا كان حجم الملف غير معروف، فستكون القيمة NULL.
  • _time — وقت آخر تعديل للملف. النوع: Nullable(DateTime). إذا كان الوقت غير معروف، فستكون القيمة NULL.
  • _etag — قيمة etag للملف. النوع: LowCardinality(String). إذا كانت قيمة etag غير معروفة، فستكون القيمة NULL.

الكتابة في جدول Iceberg

بدءًا من الإصدار 25.7، يدعم ClickHouse تعديل جداول Iceberg الخاصة بالمستخدم. حاليًا، هذه ميزة تجريبية، لذا عليك أولًا تمكينها:

إنشاء جدول

لإنشاء جدول Iceberg فارغ خاص بك، استخدم الأوامر نفسها المستخدَمة للقراءة، ولكن حدِّد المخطط صراحةً. تدعم عمليات الكتابة جميع تنسيقات البيانات وفقًا لمواصفة Iceberg، مثل Parquet وAvro وORC.

مثال

ملاحظة: لإنشاء ملف تلميح الإصدار، فعِّل الإعداد iceberg_use_version_hint. إذا أردت ضغط ملف metadata.json، فحدِّد اسم خوارزمية الضغط في الإعداد iceberg_metadata_compression_method.

INSERT

بعد إنشاء جدول جديد، يمكنك إدراج البيانات باستخدام صيغة ClickHouse المعتادة.

مثال

DELETE

يدعم ClickHouse أيضًا حذف الصفوف الإضافية في تنسيق merge-on-read. سينشئ هذا الاستعلام لقطة جديدة تتضمّن ملفات حذف حسب الموضع.

مثال

تطوّر المخطط

يتيح ClickHouse إضافة الأعمدة ذات الأنواع البسيطة (غير tuple وغير array وغير map) أو حذفها أو تعديلها أو إعادة تسميتها.

مثال

الدمج

يدعم ClickHouse دمج جداول Iceberg. حاليًا، يمكنه دمج ملفات الحذف حسب الموضع في ملفات البيانات مع تحديث البيانات الوصفية. وتبقى معرّفات اللقطات السابقة والطوابع الزمنية من دون تغيير، لذا يظل بالإمكان استخدام ميزة السفر عبر الزمن بالمعرّفات والقيم الزمنية نفسها. كيفية استخدامه:

حذف اللقطات منتهية الصلاحية

تتراكم اللقطات في جداول Iceberg مع كل عملية INSERT أو DELETE أو UPDATE. ومع مرور الوقت، قد يؤدي ذلك إلى زيادة كبيرة في عدد اللقطات وملفات البيانات المرتبطة بها. يزيل الأمر expire_snapshots اللقطات القديمة وينظّف ملفات البيانات التي لم تعد أي لقطة محتفَظ بها تُشير إليها. الصياغة:
بشكل افتراضي، يحدِّد سياسة الاستبقاء اللقطات التي يجب الاحتفاظ بها (خصائص الجدول min-snapshots-to-keep وmax-snapshot-age-ms، وعمليات التجاوز لكل مرجع). عند تحديد snapshot_ids، يتم تخطي سياسة الاستبقاء ولا تُؤخذ في الاعتبار لانتهاء الصلاحية إلا اللقطات المُدرجة. الوسيطات:
  • 'timestamp' (موضعي) أو expire_before = 'timestamp' — سلسلة DateTime (مثل '2024-06-01 00:00:00') تُفسَّر وفق المنطقة الزمنية للخادم. تعمل كآلية أمان: اللقطات التي تكون قيمة timestamp-ms الخاصة بها مساوية لهذه القيمة أو أحدث منها تكون محمية من انتهاء الصلاحية، حتى لو كانت سياسة الاستبقاء ستُنهي صلاحيتها بخلاف ذلك. ويمكن دمجها مع snapshot_ids، وفي هذه الحالة لا تنتهي صلاحية اللقطات المُدرجة التي تقع عند هذا الطابع الزمني أو بعده.
  • retention_period = '<duration>' — يتجاوز قيمة history.expire.max-snapshot-age-ms على مستوى الجدول لهذا الاستدعاء فقط. تصبح اللقطات الأقدم من هذه المدة (مقاسةً من الوقت الحالي) مرشحة لانتهاء الصلاحية. وتكون القيمة سلسلة مدة تتكوّن من زوج واحد أو أكثر من {number}{unit} متصلة معًا. الوحدات المدعومة: y (365 يومًا)، w (7 أيام)، d (24 ساعة)، h (60 دقيقة)، m (60 ثانية)، s (ثانية واحدة)، ms (1 ميلي ثانية). ويمكن دمج الوحدات، مثل '3d' و'12h' و'1d12h30m' و'500ms'.
  • retain_last = N — يتجاوز قيمة history.expire.min-snapshots-to-keep على مستوى الجدول لهذا الاستدعاء فقط. ويُحتفَظ دائمًا بما لا يقل عن N من اللقطات بغضّ النظر عن عمرها.
  • snapshot_ids = [id1, id2, ...] — يُنهي صلاحية معرّفات اللقطات المُدرجة فقط (باستثناء اللقطات المشار إليها بواسطة اللقطة الحالية أو الفروع أو الوسوم). يتخطى هذا الوضع سياسة الاستبقاء بالكامل، ولا يمكن دمجه مع retention_period أو retain_last.
  • dry_run = 1 — يحسب ما الذي كان سينتهي صلاحيته ويُرجع المقاييس دون كتابة بيانات وصفية جديدة أو حذف ملفات.
يتجاوز retention_period وretain_last فقط قيم الاستبقاء الافتراضية على مستوى الجدول. أما عمليات تجاوز الاستبقاء لكل مرجع (فرع/وسم) المُعدّة في خصائص جدول Iceberg (مثل refs.<branch>.min-snapshots-to-keep) فلا يتم تجاوزها مطلقًا — بل تسري دائمًا كما هي محددة في البيانات الوصفية للجدول.
مثال:
الناتج: يعيد الأمر جدولًا بعمودين (metric_name String, metric_value Int64) ويضم صفًا واحدًا لكل مقياس. وتتبع أسماء المقاييس مواصفة Iceberg: ينفّذ الأمر الخطوات التالية:
  1. يقيّم سياسة الاحتفاظ (انظر أدناه) لتحديد اللقطات التي يجب الإبقاء عليها
  2. إذا تم توفير وسيطة طابع زمني، فإنه يحمي أيضًا جميع اللقطات عند ذلك الطابع الزمني أو الأحدث منه
  3. يُنهي صلاحية اللقطات التي لا تحتفظ بها السياسة ولا تشملها الحماية بالطابع الزمني
  4. يحسب الملفات المرتبطة حصريًا باللقطات منتهية الصلاحية
  5. في الوضع العادي: ينشئ بيانات وصفية جديدة من دون اللقطات منتهية الصلاحية
  6. في الوضع العادي: يحذف فعليًا قوائم البيان وملفات البيان وملفات البيانات التي لم يعد من الممكن الوصول إليها
  7. في وضع dry_run = 1: يتخطى الخطوتين 5 و6 ويُرجع فقط المقاييس المحسوبة

سياسة الاحتفاظ باللقطات

يراعي الأمر expire_snapshots سياسة الاحتفاظ بلقطات Iceberg. يُضبط الاحتفاظ عبر خصائص جدول Iceberg وعمليات التجاوز على مستوى كل مرجع: يمكن لكل مرجع لقطة (refs في بيانات Iceberg الوصفية) تجاوز هذه القيم من خلال حقول خاصة بكل مرجع: min-snapshots-to-keep وmax-snapshot-age-ms وmax-ref-age-ms. تقييم الاحتفاظ:
  • لكل فرع (بما في ذلك main): يُتتبَّع تسلسل الأسلاف بدءًا من رأس الفرع. ويُحتفَظ باللقطات ما دام أحد الشرطين التاليين متحققًا:
    • أن تكون اللقطة من أول min-snapshots-to-keep في التسلسل
    • أن يكون عمر اللقطة ضمن max-snapshot-age-ms (أي now - timestamp-ms <= max-snapshot-age-ms)
  • بالنسبة إلى tags: يُحتفَظ باللقطة المشار إليها ما لم يكن tag قد تجاوز max-ref-age-ms الخاص به، وعندها يُزال مرجع tag
  • المراجع غير main التي يتجاوز عمرها max-ref-age-ms تُزال بالكامل (أما فرع main فلا يُزال أبدًا)
  • المراجع المعلّقة التي تشير إلى لقطات غير موجودة تُزال مع تحذير
  • تُحفَظ اللقطة الحالية دائمًا، بغض النظر عن إعدادات الاحتفاظ
الامتيازات المطلوبة: امتياز ALTER TABLE EXECUTE مطلوب، وهو امتياز فرعي من ALTER TABLE في التسلسل الهرمي للتحكم في الوصول في ClickHouse. يمكنك منحه مباشرةً أو عبر الامتياز الأصل:
  • لا تُدعَم إلا جداول Iceberg ذات تنسيق الإصدار 2 (إذ لا تضمن لقطات v1 وجود manifest-list، وهو مطلوب لتحديد الملفات المراد تنظيفها بأمان)
  • تُحفَظ اللقطة الحالية دائمًا، حتى إذا كانت أقدم من الطابع الزمني المحدد
  • يتطلب تمكين الإعداد allow_insert_into_iceberg
  • يتطلب تمكين الإعداد allow_experimental_expire_snapshots
  • يُطبَّق التفويض الخاص بـ catalog نفسه (مثل مصادقة REST catalog وAWS Glue IAM وغيرها) بشكل مستقل عندما يحدّث ClickHouse البيانات الوصفية

إزالة الملفات اليتيمة

الملفات اليتيمة هي ملفات موجودة في التخزين لا تشير إليها أي لقطة في البيانات الوصفية لجدول Iceberg. وتتراكم بسبب عمليات الكتابة الفاشلة، والتنظيف الجزئي بعد الدمج، والعمليات المنقطعة، مما يؤدي إلى نمو غير محدود في مساحة التخزين. يحدِّد الأمر remove_orphan_files هذه الملفات اليتيمة ويزيلها. الصيغة:
المعلمات: أمثلة:
المخرجات: يعيد الأمر جدولًا يحتوي على العمودين metric_name وmetric_value، ويعرض عدد الملفات المحذوفة (أو التي كان سيُحذفها في وضع dry_run) حسب الفئة. تُصنَّف فئات الملفات باستخدام أساليب استدلالية بأفضل جهد استنادًا إلى اصطلاحات تسمية الملفات؛ أما الملفات التي لا تطابق أي نمط محدد فتُدرج افتراضيًا ضمن deleted_data_files_count: الإعدادات:
  • يتطلب Iceberg format version 2 (أو أعلى). تُرفض جداول الإصدار 1 لأنها تفتقر إلى مؤشرات manifest-list في لقطات، وهي مطلوبة لتحديد مجموعة الملفات القابلة للوصول بأمان. ويؤدي تشغيل الأمر على جدول v1 إلى إرجاع خطأ BAD_ARGUMENTS.
  • يتطلب تمكين كلٍّ من الإعدادين allow_insert_into_iceberg وallow_iceberg_remove_orphan_files
  • يُوصى بتشغيل expire_snapshots قبل remove_orphan_files حتى تُنظَّف أولًا الملفات المشار إليها بشكل فريد من خلال لقطات منتهية الصلاحية
  • استخدم dry_run = 1 لمعاينة orphan files قبل حذفها
  • تحمي عتبة older_than من حذف الملفات الناتجة عن عمليات كتابة لا تزال قيد التنفيذ — وتوفّر العتبة الافتراضية البالغة 3 أيام هامش أمان مريحًا

راجع أيضًا

آخر تعديل في ٢٥ يونيو ٢٠٢٦