Beralih dari warehouse ke dunia volume besar: format penyimpanan kolumnar Parquet & Avro, tabel transaksional Iceberg & Delta Lake, arsitektur lakehouse, serta praktik batch processing data besar dengan PySpark

Di episode 9 kalian mempelajari warehouse cloud — dan mungkin bertanya: apa yang terjadi jika datanya jauh lebih besar dari yang bisa ditampung warehouse? Jawabannya adalah data lake dan turunannya: lakehouse. Inilah lapisan penyimpanan yang menangani volume terabyte sampai petabyte dengan biaya rendah.
Episode ini menjelaskan fondasi teknis yang wajib dipahami setiap data engineer modern: format file (Parquet, Avro), table formats (Iceberg, Delta Lake), dan engine pemrosesan (Spark/PySpark). Di akhir, kalian menjalankan batch processing PySpark pertama.
Data lake menyimpan data sebagai file di object storage. Tapi format file menentukan segalanya. Dua format yang paling penting:
Parquet — format kolumnar (data disimpan per kolom, bukan per baris). Keunggulannya: kompresi lebih baik dan query yang mengambil beberapa kolom bisa melewatkan kolom lain — sangat cocok untuk analitik. Ini format default di hampir semua ekosistem data 2026.
Avro — format row-based dengan schema tersemat. Keunggulannya: cepat untuk menulis dan membaca seluruh baris, ideal untuk streaming dan message queue.
| Aspek | Parquet | Avro |
|---|---|---|
| Orientasi | Kolumnar | Baris |
| Terbaik untuk | Query analitik, scan sebagian kolom | Streaming, menulis berurutan |
| Schema | Di metadata file | Tersemat, evolusi schema native |
| Contoh pemakai | Spark, Trino, DuckDB | Kafka, Flink, Hadoop |
Aturan praktis: Parquet untuk penyimpanan analitik, Avro untuk transport/streaming.
File Parquet saja tidak cukup — kalian butuh cara mengelola ribuan file sebagai satu tabel dengan transaksi. Di sinilah table format bekerja. Tiga pemain utama:
Ketiganya menyelesaikan masalah yang sama: ACID di atas data lake — beberapa proses bisa menulis bersamaan tanpa saling merusak, dan kalian bisa time travel ke versi tabel sebelumnya.
MERGE INTO silver.orders AS t
USING bronze.orders_raw AS s
ON t.order_id = s.order_id
WHEN MATCHED THEN UPDATE SET
t.amount = s.amount,
t.status = s.status,
t.updated_at = s.updated_at
WHEN NOT MATCHED THEN INSERT (order_id, amount, status, created_at)
VALUES (s.order_id, s.amount, s.status, s.created_at);MERGE adalah cara kanonik melakukan incremental update di lakehouse — dasar dari topik CDC di episode 12.
Note
Perbedaan kunci: file format (Parquet/Avro) menentukan cara data disimpan, sedangkan table format (Iceberg/Delta) menentukan cara file dikelola sebagai tabel. Lakehouse = object storage + table format + query engine. Ketiganya dibutuhkan.
Lakehouse adalah arsitektur yang menyimpan data di lake (object storage, format terbuka, murah) tapi menghadirkan fitur warehouse: transaksi ACID, schema enforcement, indeks, dan query cepat.
Inilah alasan lakehouse menjadi standar de facto 2026: satu penyimpanan untuk raw (bronze), cleansed (silver), dan curated (gold) — tanpa perpindahan data antar sistem (episode 2). Databricks (Delta), Iceberg ecosystem, dan layanan cloud (episode 17) semua bergerak ke arah ini.
Apache Spark adalah engine pemrosesan terdistribusi: pekerjaan dipecah ke banyak executor yang memproses data secara paralel. PySpark adalah API Python-nya. Konsep dasarnya: DataFrame yang terdistribusi — API-nya mirip pandas/polars, tapi bekerja di atas cluster.
from pyspark.sql import SparkSession
from pyspark.sql import functions as F
spark = SparkSession.builder \
.appName("orders_batch") \
.getOrCreate()
# Baca data lake (bronze) dan filter hanya yang valid
raw = spark.read.parquet("s3://data-lake/bronze/orders/")
silver = raw.filter(F.col("status") != "cancelled") \
.withColumn("amount", F.col("amount").cast("decimal(12,2)")) \
.withColumn("order_date", F.to_date("created_at"))
# Agregasi per hari (gold)
daily = silver.groupBy("order_date") \
.agg(F.count("order_id").alias("total_orders"),
F.sum("amount").alias("total_revenue"))
daily.write.mode("overwrite").format("parquet") \
.save("s3://data-lake/gold/daily_orders/")Perhatikan polanya: bronze dibaca, dibersihkan jadi silver, diagregasi jadi gold — medallion architecture dalam aksi. Spark menangani volume yang terlalu besar untuk pandas dengan memecah pekerjaan lintas executor.
Untuk belajar, Spark bisa dijalankan di satu mesin (local mode). Jalankan di Docker agar Java & dependency bersih:
docker run -it --rm \
-v $(pwd):/work -w /work \
apache/spark:3.5 \
./bin/spark-submit pyspark_batch.pyspark-submit adalah cara menjalankan aplikasi Spark. Untuk series ini, mode local sudah cukup memahami konsep; detail tuning dan optimasi cluster kita bedah di episode 21.
Menganggap pandas dan PySpark identik. Transformasi yang valid di pandas (misalnya mutate baris per baris) bisa menjadi bencana performa di Spark. Pikirkan dalam operasi kolom yang didistribusikan.
Menyimpan semuanya sebagai CSV di lake. CSV tidak punya metadata, kompresi buruk, dan lambat di-scan. Parquet adalah standar.
File lake tanpa table format. Ribuan file Parquet tanpa Iceberg/Delta = data swamp tanpa transaksi dan tanpa lineage.
Menulis kembali semua data tiap hari. Overwrite penuh tabel besar itu mahal dan lambat. Gunakan incremental (MERGE, partitioning) sedini mungkin.
Di episode 10 ini kalian telah membangun pemahaman lake & lakehouse:
Di episode 11 selanjutnya kita beralih dari batch ke real-time: streaming (Kafka/Flink) — konsep topics, producers, consumers, arsitektur Kappa, dan praktik membangun pipeline streaming sederhana. Sampai jumpa di episode 11!