Data Engineering

گشودن تراکنش‌های ACID در دریاچه‌های داده: نگاهی عمیق به Apache Hudi

در منظره در حال تحول مهندسی داده، معماری سنتی دریاچه‌های داده با یک گلوگاه حیاتی روبرو شده است: عدم پشتیبانی بومی از تراکنش‌های ACID (اتمی بودن، سازگاری، جداسازی، پایداری). اگرچه دریاچه‌های داده مقیاس‌پذیری عظیم و ذخیره‌سازی کم‌هزینه را ارائه می‌دهند، اما در حفظ یکپارچگی داده‌ها هنگامی که چندین نویسنده همزمان تلاش برای تغییر داده‌ها دارند، با مشکل مواجه می‌شوند. در اینجا Apache Hudi (مخفف Hadoop Upserts Deletes and Incrementals) به عنوان یک چارچوب متن‌باز وارد میدان می‌شود که این مشکل را با امکان‌پذیر کردن به‌روزرسانی‌های کارآمد داده و پردازش داده‌های افزایشی مستقیماً روی سیستم‌های ذخیره‌سازی توزیع‌شده مانند HDFS، S3 و ADLS حل می‌کند.

Apache Hudi چه مشکلی را حل می‌کند؟

به طور تاریخی، اگر می‌خواستید یک رکورد را در یک فایل Parquet یا ORC که در یک دریاچه داده ذخیره شده است به‌روزرسانی کنید، مجبور بودید کل فایل را بازنویسی کنید. این فرآیند از نظر محاسباتی پرهزینه و ناکارآمد است. Apache Hudi مفهوم «آپسرت‌ها» (Upserts - ترکیب Update و Insert) و «حذف‌ها» (Deletes) را در سطح فایل معرفی می‌کند. این سیستم این تغییرات را با نگهداری متادیتا و استفاده از فرمت‌های ذخیره‌سازی کارآمد مدیریت می‌کند که امکان کوئری‌های نقطه‌ای در زمان (point-in-time) و یکپارچه‌سازی پیوسته داده‌ها را فراهم می‌سازد.

با پیاده‌سازی کلید رکورد (Record Key) و مسیر پارتیشن (Partition Path)، Hudi می‌تواند رکوردهای خاص را در میان مجموعه‌های داده عظیم شناسایی کند و اطمینان حاصل کند که تنها فایل‌های مورد نیاز به‌روزرسانی می‌شوند، نه کل مجموعه داده. این قابلیت بنیادی برای ساخت دریاچه‌خانه‌های داده (Data Lakehouses) مدرن است.

مفاهیم معماری هسته

برای بهره‌برداری مؤثر از Hudi، توسعه‌دهندگان باید اجزای اصلی آن را درک کنند. این سیستم برای مدیریت ورود داده‌ها به چند پارامتر کلیدی متکی است:

  • کلید رکورد (Record Key): یک شناسه منحصر به فرد برای هر سطر (مثلاً user_id).
  • مسیر پارتیشن (Partition Path): ساختار دایرکتوری که برای پارتیشن‌بندی داده‌ها استفاده می‌شود (مثلاً ds=2023-10-01).
  • انواع عملیات: Hudi از عملیات INSERT، UPSERT و DELETE پشتیبانی می‌کند.

Hudi از چندین نوع جدول پشتیبانی می‌کند، از جمله Copy-On-Write (COW) و Merge-On-Read (MOR). جداول COW برای بارهای کاری با خواندن سنگین بهینه شده‌اند، جایی که به‌روزرسانی‌ها روی فایل‌های پایه اعمال می‌شوند. جداول MOR، در مقابل، برای بارهای کاری با نوشتن سنگین طراحی شده‌اند و تغییرات اخیر را در فایل‌های لاگ جداگانه نگه می‌دارند تا تأخیر نوشتن را به حداقل رسانده و میزان عبور داده (throughput) را به حداکثر برسانند.

پیاده‌سازی عملی با Spark

یکپارچه‌سازی Apache Hudi با Apache Spark کاملاً روان است. در زیر یک مثال عملی از نحوه ثبت یک جدول Hudi و انجام یک عملیات آپسرت با استفاده از PySpark آورده شده است. این مثال نشان می‌دهد که چگونه یک DataFrame را به عنوان یک جدول Hudi بنویسید و نوع جدول را به عنوان COW برای عملکرد خواندن بهینه مشخص کنید.

from pyspark.sql import SparkSession

spark = SparkSession.builder \
    .appName("HudiUpsertExample") \
    .getOrCreate()

# Sample data to be ingested
data = [
    (1, "Alice", 30, "2023-10-01"),
    (2, "Bob", 25, "2023-10-01"),
    (3, "Charlie", 35, "2023-10-01")
]

df = spark.createDataFrame(data, ["id", "name", "age", "dt"])

# Define the table properties for Hudi
props = {
    "hoodie.table.name": "hudi_test_table",
    "hoodie.datasource.write.partitionpath.field": "dt",
    "hoodie.datasource.write.recordkey.field": "id",
    "hoodie.table.type": "COPY_ON_WRITE",
    "hoodie.datasource.write.operation": "upsert"
}

# Write the DataFrame to Hudi
df.write \
    .format("hudi") \
    .options(**props) \
    .mode("overwrite") \
    .save("s3://my-bucket/data/hudi_table")

سفر در زمان و کوئری‌های افزایشی

یکی از قدرتمندترین ویژگی‌های Hudi «سفر در زمان» (Time Travel) است. از آنجا که Hudi هر تغییری را ثبت (commit) می‌کند، می‌توانید وضعیت داده‌های خود را در هر نقطه از زمان گذشته کوئری کنید. این ویژگی برای عیب‌یابی مسائل کیفیت داده یا بازتولید حالت‌های تاریخی بدون نگهداری عکس‌های لحظه‌ای (snapshots) تاریخی جداگانه، بی‌نظیر است. علاوه بر این، Hudi کوئری‌های افزایشی را امکان‌پذیر می‌سازد و به فرآیندهای پایین‌دست اجازه می‌دهد تنها تغییرات انجام شده از آخرین ورود داده را دریافت کنند که این امر هزینه‌های پردازش را به طور قابل توجهی کاهش می‌دهد.

نتیجه‌گیری

Apache Hudi شکاف بین دریاچه‌های داده سنتی و نیازهای تراکنشی قوی تحلیلات مدرن را پر می‌کند. با ارائه پشتیبانی بومی برای آپسرت‌ها، حذف‌ها و سفر در زمان، به مهندسان داده قدرت می‌بخشد تا معماری‌های دریاچه‌خانه داده (Data Lakehouse) قابل اعتماد، مقیاس‌پذیر و مقرون‌به‌صرفه بسازند. اگرچه این ابزار پیچیدگی‌هایی در پیکربندی و مدیریت ایجاد می‌کند، اما مزایای رعایت ACID روی ذخیره‌سازی اشیاء ارزان، آن را به گزینه‌ای جذاب برای سازمان‌هایی که با مجموعه‌های داده با حجم بالا و به‌روزرسانی مکرر سروکار دارند، تبدیل می‌کند.

Share: