Delta Lake: Penyimpanan Lakehouse yang Andal dengan Transaksi ACID
Data lake yang dibangun di atas object storage memang murah dan mudah diskalakan, tetapi format file biasa tidak memberi jaminan apa pun: penulisan yang gagal di tengah jalan bisa membuat pembaca menerima data rusak, dan job yang berjalan bersamaan bisa saling menimpa. Delta Lake mengatasi ini dengan menambahkan transaction log di atas Parquet, sehingga data lake memperoleh transaksi ACID, penegakan skema, dan time travel. Tutorial ini membahas Delta Lake dari dasar melalui dua jalur praktis: library Python deltalake yang ringan (tanpa Spark) dan Apache Spark dengan delta-spark.
Apa Itu Delta Lake
Delta Lake adalah format tabel terbuka (open table format). Sebuah tabel Delta bukan satu file, melainkan sebuah direktori yang berisi:
- Satu atau lebih file data Parquet yang menyimpan baris data sebenarnya.
- Sebuah direktori transaction log bernama
deltalog, berisi file commit JSON yang berurutan (00000000000000000000.json,00000000000000000001.json, dan seterusnya) ditambah checkpoint Parquet berkala.
Setiap perubahan pada tabel dicatat sebagai commit atomik di dalam log. Pembaca merujuk pada log untuk mengetahui persis file Parquet mana yang membentuk versi tabel saat ini. Karena log adalah sumber kebenaran, pembaca tidak akan pernah melihat file yang ditulis sebagian, dan dua penulis dapat mendeteksi bahwa mereka berkonflik.
Inilah inti dari ide lakehouse: mempertahankan biaya rendah dan keterbukaan data lake (Parquet di S3, ADLS, GCS, atau disk lokal), tetapi menambahkan keandalan dan semantik transaksional seperti yang diharapkan dari sebuah data warehouse.
Mengapa Tidak Cukup dengan Parquet Saja?
Parquet biasa adalah penyimpanan kolumnar yang sangat baik, tetapi tidak memiliki konsep versi tabel atau commit. Jika sebuah job menulis sepuluh file Parquet lalu gagal setelah lima file, pembaca yang memindai direktori akan mengambil campuran data yang tidak konsisten. Tidak ada "append" yang atomik, tidak ada update bersamaan yang aman, tidak ada cara untuk rollback, dan perubahan skema sepenuhnya manual. Delta Lake tetap memakai Parquet sebagai lapisan penyimpanan dan menambahkan metadata transaksional di atasnya.
Transaction Log Secara Rinci
Direktori Delta yang umum terlihat seperti ini:
orders/
deltalog/
00000000000000000000.json
00000000000000000001.json
00000000000000000002.json
lastcheckpoint
part-00000-....snappy.parquet
part-00001-....snappy.parquet
Setiap commit JSON menjelaskan action: file ditambahkan (add), file dihapus (remove), perubahan metadata, dan perubahan protokol. Versi 0 adalah pembuatan tabel; setiap commit berikutnya menambah nomor versi sebanyak satu. Nomor versi yang monoton inilah yang memungkinkan time travel, dan action remove itulah yang nantinya memungkinkan VACUUM mengembalikan ruang disk.
Jalur 1: Library Python deltalake (Tanpa Spark)
Paket deltalake (proyek delta-rs) adalah implementasi native Rust dengan binding Python. Paket ini membaca dan menulis tabel Delta tanpa JVM atau klaster Spark, sehingga ideal untuk ETL single-node, notebook, dan menyematkan Delta ke dalam pipeline pandas atau PyArrow yang sudah ada.
Instalasi
pip install "deltalake>=0.18" pandas pyarrow
Membuat dan Menambahkan Data ke Tabel
Kita akan memodelkan tabel orders sepanjang tutorial ini.
import pandas as pd
from deltalake import writedeltalake, DeltaTable
tablepath = "data/orders"
orders = pd.DataFrame(
{
"orderid": [1, 2, 3],
"customer": ["alice", "bob", "carol"],
"amount": [120.0, 80.5, 45.0],
"status": ["paid", "paid", "pending"],
"region": ["west", "east", "west"],
}
)
Penulisan pertama membuat tabel pada versi 0.
writedeltalake(tablepath, orders, mode="overwrite")
Untuk menambah baris tanpa menulis ulang data yang ada, gunakan mode="append":
neworders = pd.DataFrame(
{
"orderid": [4, 5],
"customer": ["dave", "erin"],
"amount": [200.0, 15.0],