Pada Proyek: Streaming Data dengan Kafka kita memproses event begitu data tiba; pada proyek ini kita menghadapi sisi lainnya: data yang sudah beristirahat sebagai berkas historis dan harus diolah secara batch. Dataset yang kita proses adalah hasil ekspor basis data transaksional TokoKita: 800 ribu pesanan, 1,6 juta baris pesanan, 60 ribu pelanggan, dan 400 produk — sekitar 22,6 MB berformat parquet. Mesin pengolahnya adalah Apache Spark 4.2.0 mode lokal dengan PySpark sebagai antarmuka Python, persis seperti yang kita pelajari pada chapter Apache Spark; dokumentasi resmi ada di https://spark.apache.org/docs/latest/ dan setiap fitur yang dipakai proyek ini tercantum di sana. Seluruh angka pada sembilan bagian proyek ini adalah hasil eksekusi nyata pada mesin uji dua CPU dengan master("local[1]"); tidak ada satu pun blok keluaran yang dikarang.

Hasil akhir proyek ini berupa:

  • dataset TokoKita deterministik: empat tabel parquet yang dibangkitkan dari rumus modular sehingga dapat direplikasi di Python murni,
  • satu SparkSession local[1] yang dikonfigurasi dari satu berkas YAML (UI dimatikan, log ERROR, shuffle 8 partition, AQE aktif),
  • pipeline end-to-end: baca parquet, transformasi, join, agregasi, lalu simpan partition by bulan disertai verifikasi baca ulang,
  • pengukuran nyata: broadcast vs sort-merge join, UDF vs built-in, cache dingin vs panas, column pruning, dan predicate pushdown,
  • pembacaan query plan mode formatted, simple, dan extended, termasuk penanda PartitionFilters dan PushedFilters, dan
  • 31 uji pytest yang lulus penuh dalam satu suite serial.

Prasyarat #

Sebelum mulai, pastikan kita telah memahami chapter berikut karena seluruh keputusan teknis pada proyek ini merujuk ke sana:

  • Apache Spark dan Spark DataFrames — arsitektur eksekusi serta API DataFrame yang dipakai seluruh modul,
  • Spark SQL — dasar optimizer Catalyst yang rencananya kita baca pada Bagian 7,
  • Spark Joins serta Shuffle dan Skew — mekanisme broadcast join dan biaya shuffle yang diukur pada Bagian 5,
  • Spark Partitioning — perbedaan partition penyimpanan dan partition task yang diatur pada Bagian 6,
  • Spark Performance dan Kapan Menggunakan Spark — kerangka kerja optimasi serta batas kapan Spark tepat dipakai.

Seluruh kode berjalan pada Python 3.12 dengan PySpark 4.2.0 di atas OpenJDK 21; dependensi lain hanya PyYAML dan pytest.

Struktur Proyek #

text
pemrosesan-data-dengan-spark/
├── _index.md
├── part-1-memahami-dataset-besar/
├── part-2-menyiapkan-spark/
├── part-3-membaca-data-terdistribusi/
├── part-4-melakukan-transformasi/
├── part-5-melakukan-join-dan-aggregasi/
├── part-6-mengatur-partition/
├── part-7-menganalisis-query-plan/
├── part-8-mengoptimalkan-job/
├── part-9-menyimpan-hasil/
├── config/      (spark-local.yaml + requirements.txt)
├── data/         (parquet 22,6 MB; data/hasil/ ditulis pipeline)
├── src/          (session, generate_data, transformasi, joins, partisi, plan, optimasi, simpan, pipeline)
└── tests/        (31 uji pytest untuk seluruh modul)

Seluruh berkas kode pada folder config/, data/, src/, dan tests/ tersedia pada bagian Berkas Sumber di bawah halaman ini. Setiap bagian pengerjaan merujuk ke berkas yang sama sehingga kondisi proyek tetap utuh di setiap tahap.

Tahapan Pengerjaan #

Proyek dikerjakan dalam sembilan bagian berurutan. Setiap bagian menghasilkan artefak yang dapat dijalankan dan diuji:

  1. Bagian 1 memahami dataset: skema, distribusi, dan struktur fisik parquet.
  2. Bagian 2 menyiapkan Spark: satu berkas konfigurasi, satu SparkSession.
  3. Bagian 3 membaca data terdistribusi: schema inference vs eksplisit, partition pruning.
  4. Bagian 4 melakukan transformasi: kolom turunan, when bertingkat, null, dan UDF.
  5. Bagian 5 melakukan join dan agregasi: broadcast vs sort-merge, metrik bulanan.
  6. Bagian 6 mengatur partition: repartition, coalesce, dan berkas kecil.
  7. Bagian 7 menganalisis query plan: formatted, simple, dan extended.
  8. Bagian 8 mengoptimalkan job: cache, column pruning, predicate pushdown.
  9. Bagian 9 menyimpan hasil: parquet partition by bulan, verifikasi baca ulang.

Mulailah dari Bagian 1 dan ikuti urutannya karena setiap bagian dibangun di atas keputusan bagian sebelumnya.

Kontrak Pengujian #

Dua perintah berikut menjadi bukti bahwa proyek sehat pada setiap tahap. Perintah pertama menjalankan pipeline end-to-end; perintah kedua menjalankan seluruh uji:

bash
cd content/data-engineering/proyek/pemrosesan-data-dengan-spark
python3 -m src.pipeline
python3 -m pytest tests/ -q

Kedua perintah tersebut dijalankan nyata pada Bagian 9; keluarannya ditampilkan apa adanya, bukan karangan. Seluruh durasi pada proyek ini diukur pada mesin uji dua CPU (sekitar 3,9 GB RAM) dengan satu inti CPU per sesi — angka Anda akan berbeda antar mesin, namun pola dan rasionya stabil.