Apache Ecosystem

تحسين Apache Iceberg لتخزين سحابي فعّال من حيث التكلفة

أصبح Apache Iceberg بسرعة معيارًا لمصطلحات الجداول المفتوحة في منظومة البيانات الضخمة، حيث يوفر معاملات ACID وتطور المخطط وإمكانية السفر عبر الزمن. ومع ذلك، كما هو الحال مع أي حل لبحيرة بيانات واسعة النطاق، فإن الكفاءة من حيث التكلفة هي مصدر قلق رئيسي لفِرق الهندسة. العمليتان الأكثر أهمية للتحكم في التكاليف والأداء في Iceberg هما ضغط الملفات وانتهاء صلاحية اللقطات. سوء إدارة هذه العمليات يمكن أن يؤدي إلى فوات تخزين مفرطة وتدهور أداء الاستعلامات.

فهم ضغط الملفات

مع مرور الوقت، تؤدي الكتابات الصغيرة المتكررة إلى جدول Iceberg إلى مجموعة متجزئة من الملفات الصغيرة. وعلى الرغم من أن الملفات الصغيرة ممتازة للتوازي في عملية الإدخال، إلا أنها كارثية للتحليلات. فمسح آلاف الملفات الصغيرة يترتب عليه تكاليف عالية لاستدعاءات API في مخازن الكائنات مثل S3 أو GCS، ويبطئ محركات الاستعلام مثل Spark وTrino. يدمج ضغط الملفات (أو "تعبئة الحاويات") هذه الملفات الصغيرة في ملفات أكبر بحجم مثالي (عادةً 128 ميغابايت إلى 256 ميغابايت).

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

// مثال: الضغط باستخدام Spark Iceberg
import org.apache.iceberg.spark.SparkCatalog
import org.apache.spark.sql.SparkSession

val spark = SparkSession.builder()
  .appName("Iceberg Compaction")
  .config("spark.sql.catalog.demo", "org.apache.iceberg.spark.SparkCatalog")
  .config("spark.sql.catalog.demo.type", "hadoop")
  .config("spark.sql.catalog.demo.warehouse", "s3://my-bucket/iceberg/warehouse")
  .getOrCreate()

// إعادة كتابة الملفات الصغيرة في ملفات أكبر
spark.sql("REWRITE FILES TABLE demo.my_table")

// اختياريًا، تحديد حجم ملف مستهدف
spark.sql("REWRITE FILES TABLE demo.my_table OPTIONS('target-file-size-bytes' 134217728)")

إدارة انتهاء صلاحية اللقطات

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

يؤدي انتهاء صلاحية اللقطات إلى إزالة اللقطات القديمة، والأهم من ذلك، حذف ملفات البيانات التي لم تعد تشير إليها أي لقطة متبقية. هذا أمر أساسي للتحكم في التكاليف. ومع ذلك، يجب أن توازن بين فترة الاحتفاظ واحتياجات عملك للتدقيق أو قدرات التراجع.

// مثال: انتهاء صلاحية اللقطات الأقدم من 7 أيام
import org.apache.iceberg.Table

val table = spark.catalog.table("demo.my_table")

// انتهاء صلاحية اللقطات الأقدم من 7 أيام
table.expireSnapshots()
  .retainLast(3) // احتفظ بآخر 3 لقطات بغض النظر عن العمر
  .olderThan(System.currentTimeMillis() - (7L * 24L * 60L * 60L * 1000L))
  .commit()

أفضل الممارسات لتحسين التكاليف

  • جدولة الصيانة المنتظمة: استخدم مجدولًا مثل Airflow أو Dagster أو cron لتشغيل عمليات الضغط وانتهاء الصلاحية يوميًا أو أسبوعيًا.
  • مراقبة عدد الملفات: أطلق تنبيهًا إذا تجاوز عدد الملفات في جدول عتبة معينة، مما يشير إلى الحاجة إلى ضغط فوري.
  • اختبار سياسات انتهاء الصلاحية: قم بمحاكاة انتهاء صلاحية اللقطات في بيئة تجريبية للتأكد من أنك لا تحذف بيانات مطلوبة للامتثال أو التراجع.
  • استخدام ORC أو Parquet: اختر تنسيقات أعمدة ذات نسب ضغط عالية لتقليل تكاليف التخزين بشكل أكبر.

الخلاصة

يتطلب تحسين Apache Iceberg لتخزين سحابي فعّال من حيث التكلفة نهجًا استباقيًا لإدارة دورة حياة البيانات. من خلال الضغط المنتظم للملفات الصغيرة وإنهاء صلاحية اللقطات القديمة، يمكنك تقليل تكاليف التخزين بشكل كبير وتحسين أداء الاستعلامات. تنفيذ عمليات الصيانة الآلية ليس اختياريًا؛ بل هو ممارسة مثالية لأي نشر إنتاجي لـ Iceberg. ابدأ صغيرًا، وراقب مقاييسك، وعدّل سياساتك لتناسب متطلبات حمل عملك المحدد.

Share: