Type something to search...
Membangun ETL Pipeline yang Scalable dengan AWS Glue (CSV ke Parquet + Partitioning)

Membangun ETL Pipeline yang Scalable dengan AWS Glue (CSV ke Parquet + Partitioning)

AWS Glue ETL Data Engineering
Daftar isi

Kenapa Saya Mulai Belajar AWS Glue

Sekarang saya kerja dengan data yang skalanya jauh di atas apa pun yang pernah saya pegang sebelumnya. Kita bicara soal terabyte, dan tiap hari nambah terus. Detailnya nggak bisa saya ceritakan, tapi datanya memang banyaknya nggak main-main. Menjaga data sebesar itu tetap bisa di-query dan tetap terkelola itu tantangan engineering tersendiri.

Pengalaman itu bikin saya pengin tahu lebih dalam: sebenarnya pipeline data skala besar itu dibangun gimana? AWS Glue terus muncul sebagai tools utama buat kerjaan kayak gini, jadi saya memutuskan untuk benar-benar duduk dan membangun sesuatu dari nol, bukan cuma baca dokumentasi.

Pipeline-nya saya bangun pakai dataset penjualan dari Kaggle (Chocolate Sales Dataset 2023-2024) supaya pola dari pekerjaan bisa saya tiru dalam konteks yang lebih sederhana dan bisa saya bagikan. Postingan ini walkthrough-nya.


CSV masuk, Parquet terpartisi keluar

Idenya simpel: ambil file CSV mentah, olah ke format yang lebih ramah buat query, lalu buka aksesnya lewat Athena. Alurnya kayak gini:

graph LR
    A[S3 raw CSV] --> B[Glue Crawler]
    B --> C[Data Catalog]
    C --> D[Glue Job PySpark]
    D --> E[S3 Parquet]
    E --> F[Athena]

Nggak istimewa, tapi pola inilah yang bakal kamu temuin di setup data lake sungguhan.


Langkah 1: Masukin Data Mentah ke S3

Pertama, upload file CSV ke S3. Sejak awal saya jaga struktur foldernya tetap rapi, karena saya belajar cukup cepat bahwa layout S3 itu ya model datanya sendiri. Kalau dari awal berantakan, semua yang di downstream ikut berantakan.

raw/
β”œβ”€β”€ sales/
β”œβ”€β”€ products/
β”œβ”€β”€ stores/
β”œβ”€β”€ customers/
└── calendar/

Tiap folder isinya satu file CSV. Simpel. Satu folder, satu schema, jadi jangan campur file dengan struktur beda di folder yang sama. Glue Crawler bakal berterima kasih.


Langkah 2: Biarkan Glue Crawler Menentukan Schema-nya

Daripada mendefinisikan semuanya manual dari awal, saya biarin Glue Crawler yang scan folder S3 dan nebak schema-nya sendiri. Prosesnya cuma butuh beberapa menit, dan semua tabel langsung terdaftar di Data Catalog.

Konfigurasi Crawler saya:

  • Data source: s3://<bucket>/raw/
  • Crawl subfolders: yes
  • Database: choco_db
  • Table prefix: raw_

Setelah crawl, saya dapat tabel-tabel ini:

raw_sales
raw_products
raw_stores
raw_customers
raw_calendar

Hasilnya, data mentah langsung bisa di-query lewat Athena. Ini berguna banget buat sanity-check sebelum transformasi.

Satu hal yang saya sadari: Crawler kadang salah nebak tipe data, terutama di kolom yang keliatannya angka padahal isinya ID, atau di kolom tanggal. Sekarang saya selalu cek ulang dulu sebelum mengandalkan inferred schema buat sesuatu yang serius.


Langkah 3: ETL yang Sebenarnya: PySpark di Glue

Ini bagian intinya. Glue Job baca dari Data Catalog, jalanin beberapa transformasi ringan, lalu nulis balik ke S3 dalam format Parquet dengan partitioning berdasarkan tahun dan bulan.

Kodenya lebih bersih dari yang saya duga buat PySpark:

from awsglue.context import GlueContext
from pyspark.context import SparkContext
from pyspark.sql.functions import col, to_date, year, month
sc = SparkContext()
glueContext = GlueContext(sc)
spark = glueContext.spark_session
# Baca dari Data Catalog
datasource = glueContext.create_dynamic_frame.from_catalog(
database="choco_db",
table_name="raw_sales"
)
df = datasource.toDF()
# Parse tanggal dan ekstrak kolom partisi
df = df.withColumn("order_date", to_date(col("order_date"), "yyyy-MM-dd"))
df = df.withColumn("year", year(col("order_date")))
df = df.withColumn("month", month(col("order_date")))
# Tulis sebagai Parquet ter-partisi
df.write \
.mode("overwrite") \
.partitionBy("year", "month") \
.parquet("s3://<your-bucket>/processed/sales_parquet/")

Baris .partitionBy("year", "month") inilah yang ngangkat hampir semua pekerjaan di sini. Glue, lewat Spark di bawahnya, otomatis nyusun output ke dalam subfolder sesuai nilai kolom tersebut.


Langkah 4: Tampilan Output di S3

Setelah job selesai, struktur folder di S3 jadi kayak gini:

processed/sales_parquet/
β”œβ”€β”€ year=2023/
β”‚ β”œβ”€β”€ month=1/
β”‚ β”œβ”€β”€ month=2/
β”‚ └── ...
β”œβ”€β”€ year=2024/

Di sinilah partitioning jadi sangat berguna. Waktu kamu query β€œkasih semua penjualan Januari 2023”, Athena nggak perlu scan seluruh dataset. Dia cukup baca folder year=2023/month=1/. Buat dataset besar, ini memangkas waktu dan biaya query jauh.

Kelihatannya jelas kalau dipikir belakangan, tapi gampang kelewatan waktu baru mulai di data engineering.


Langkah 5: Mendefinisikan Schema Manual di Athena

Meski Crawler bisa detect schema, saya lebih suka mendefinisikannya manual buat tabel yang sudah diproses. Dengan cara ini saya punya kontrol penuh, nggak ada kejutan mismatch tipe data, dan tabelnya gampang didokumentasikan.

CREATE EXTERNAL TABLE processed_sales_parquet (
order_id STRING,
order_date DATE,
product_id STRING,
store_id STRING,
customer_id STRING,
quantity BIGINT,
unit_price DOUBLE,
discount DOUBLE,
revenue DOUBLE,
cost DOUBLE,
profit DOUBLE
)
PARTITIONED BY (
year INT,
month INT
)
STORED AS PARQUET
LOCATION 's3://<your-bucket>/processed/sales_parquet/';

Lalu jalankan ini biar Athena mengenali partisi yang sudah ada:

MSCK REPAIR TABLE processed_sales_parquet;

Tanpa itu, Athena akan lihat tabel kosong padahal datanya sudah ada semua di S3.


Langkah 6: Query dengan Athena

Cek count dasar buat mastiin semuanya ter-load dengan benar:

SELECT COUNT(*) FROM processed_sales_parquet;

Lalu query yang partition-aware buat verifikasi filtering-nya benar-benar jalan:

SELECT COUNT(*)
FROM processed_sales_parquet
WHERE year = 2023 AND month = 1;

Kalau dua query ini ngasih angka yang beda, berarti partitioning-mu jalan.


Yang Saya Ambil dari Ini

Auto schema detection itu berguna, tapi rapuh. Crawler bagus buat eksplorasi data baru dengan cepat, tapi saya nggak akan mengandalkannya buat schema production. Dia cenderung nebak kolom partisi sebagai string padahal harusnya integer, dan itu bikin partition pruning rusak.

Struktur folder S3 itu ya strategi query-mu. Saya baru benar-benar ngeh soal ini setelah lihat sendiri seberapa langsung dampaknya ke performa query. Jadi pikirin dulu kamu mau nge-query datanya gimana sebelum memutuskan cara mempartisinya.

Parquet itu bedanya kerasa banget. Saya sudah tahu Parquet lebih baik dari CSV buat analytics, tapi melihatnya langsung di praktik, query lebih cepat dan storage footprint lebih kecil, bikin hal itu terasa nyata. Kalau kamu membangun apa pun yang berkaitan dengan analitik, benar-benar nggak ada alasan buat tetap bertahan di CSV.

Soal biaya, ini yang paling sering bikin kaget. Glue Job itu mahal kalau konfigurasinya nggak benar, dan DPU cepat numpuk. Buat project kecil ini masih OK, tapi di workload sungguhan kamu perlu tune jumlah worker dan pertimbangkan mau pakai G.1X atau G.2X tergantung job-nya.


Selanjutnya

Ini baru fondasi. Bagian menariknya datang berikutnya: join kelima tabel (sales, products, customers, stores, calendar) buat membangun dataset analytics yang benar-benar enriched. Dari situ kamu mulai masuk ke model yang bisa dipakai dashboard atau jadi bahan pipeline machine learning.

Itu akan saya tulis di postingan berikutnya.

Related Posts