شهدت هندسة البيانات تحولاً جذرياً. لطالما اضطرت المؤسسات للاختيار بين قابلية توسع بحيرات البيانات وكفاءتها من حيث التكلفة، وأداء مستودعات البيانات وحوكمتها وامتثالها لمعاملات المعاملات المتكاملة (ACID). لقد أدت معمارية "بحيرة البيانات" (Lakehouse) إلى تفكيك هذا التناقض بشكل فعال، حيث تقدم طبقة موحدة تستفيد من التخزين منخفض التكلفة في التخزين الكائني (مثل S3 أو GCS) مع توفير موثوقية المعاملات الخاصة بقواعد البيانات.
في صميم بحيرة البيانات الحديثة توجد تنسيقات الجداول المفتوحة: Apache Iceberg و Delta Lake و Apache Hudi. تقع هذه التقنيات فوق التخزين الكائني وتقدم طبقات من البيانات الوصفية التي تدير تطور المخطط الزمني، والسفر عبر الزمن، وتنفيذ الاستعلامات عالي الأداء. في هذا المنشور، سنستكشف كيفية عمل هذه التقنيات وكيفية تنفيذها.
ثالوث تنسيقات الجداول المفتوحة
بينما تهدف جميع التنسيقات الثلاثة إلى حل نفس المشكلة، إلا أن لها أصولاً وقوى مميزة.
Delta Lake
تديره شركة Databricks، تجلب Delta Lake معاملات ACID إلى بحيرات البيانات. وهي مبنية فوق ملفات Parquet وتستخدم سجل معاملات يعتمد على JSON لتتبع التغييرات. تتميز Delta Lake بقوة كبيرة في بيئة Apache Spark وتوفر تكاملاً ممتازاً مع سير عمل التعلم الآلي.
Apache Iceberg
تم إنشاؤه بواسطة Netflix وهو الآن مشروع Apache من المستوى الأول، يركز Iceberg على التحليلات عالية الأداء والتوافق الواسع. يفصل Iceberg البيانات الوصفية عن البيانات، مما يسمح لمحركات الحوسبة المتعددة (Spark, Trino, Flink, Presto) بقراءة وكتابة نفس الجدول دون قفل البائع. غالباً ما يُثنى على Iceberg لتطوره المتفوق في التقسيم وعزلة لقطات البيانات (Snapshot Isolation).
Apache Hudi
يختص Hoodie (المعروف بـ Hudi)، الذي نشأ أصلاً من Uber، بالمعالجة التزايدية. يتيح عمليات الإدراج أو التحديث (Upserts) والحذف على نطاق واسع، مما يجعله مثالياً للتحليلات في الوقت الفعلي وخطوط أنابيب التقاط تغيير البيانات (CDC). إذا كان حالتك الاستخدامية تتطلب تحديثات متكررة للسجلات الموجودة، فإن Hudi غالباً ما يكون الخيار الأفضل.
التنفيذ العملي باستخدام Spark و Delta Lake
لننظر في مثال عملي لإنشاء جدول Delta باستخدام PySpark. يوضح هذا المثال كيفية تمكين السفر عبر الزمن وإنفاذ المخطط، وهما ميزتان حاسمتان لموثوقية البيانات.
from pyspark.sql import SparkSession
# Initialize Spark Session with Delta Lake support
spark = SparkSession.builder \
.appName("DeltaLakeExample") \
.config("spark.sql.extensions", "io.delta.sql.DeltaSparkSessionExtension") \
.config("spark.sql.catalog.spark_catalog", "org.apache.spark.sql.delta.catalog.DeltaCatalog") \
.getOrCreate()
# Write data to a Delta table with schema enforcement
data = [(1, "Alice", 30), (2, "Bob", 25)]
df = spark.createDataFrame(data, ["id", "name", "age"])
# Save as Delta format
df.write.format("delta") \
.mode("overwrite") \
.option("mergeSchema", "true") \
.save("/data/delta/lakehouse_table")
# Time Travel: Query data as it looked 1 hour ago
# df_historical = spark.read.format("delta").option("timestampAsOf", "1 hour ago").load("/data/delta/lakehouse_table")
إدارة البيانات الوصفية والحوكمة
مكون حاسم في أي معمارية لبحيرة البيانات هو إدارة البيانات الوصفية. سواء اخترت Iceberg أو Delta، يجب أن تضمن أن مستودع البيانات الوصفية لديك متاح للغاية ومحمي بنسخ احتياطي. تعتمد هذه التنسيقات على ملف فهرس (في Iceberg) أو سجل معاملات (في Delta) لتتبع حالة البيانات. إذا فقدت هذه البيانات الوصفية، فقد تصبح ملفات البيانات غير مقروءة أو غير متسقة.
علاوة على ذلك، يسمح دمج هذه تنسيقات الجداول مع فهرس موحد مثل Apache Hive أو AWS Glue بالحوكمة المركزية. يضمن ذلك أن اكتشاف البيانات،和控制 الوصول، وتتبع النسب متسقة عبر جميع محركات الحوسبة، سواء كانت تقوم باستعلامات SQL التفاعلية على Trino أو المعالجة الدفعية على Spark.
الخاتمة
يعتمد الاختيار بين Iceberg و Delta Lake و Hudi غالباً على مجموعة التكنولوجيا الحالية ومتطلبات عبء العمل المحددة لديك. ومع ذلك، فإن التحول نحو تنسيقات الجداول المفتوحة أمر لا يمكن إنكاره. من خلال فصل التخزين عن الحوسبة وإدخال طبقات بيانات وصفية قوية، يمكن للمؤسسات بناء منصات بيانات قابلة للتوسع وفعالة من حيث التكلفة وموثوقة للغاية. عند تصميم معمارية البيانات التالية، فكر ليس فقط في مكان وجود بياناتك، ولكن أيضاً في كيفية تحكم طبقات البيانات الوصفية في سلامتها وإتاحتها.