Membangun ETL Pipeline yang Scalable dengan AWS Glue (CSV ke Parquet + Partitioning)
- Habib Abdurrasyid
- 08 Apr, 2026
- Β· 6 mnt baca
Daftar isi
- Kenapa Saya Mulai Belajar AWS Glue
- CSV masuk, Parquet terpartisi keluar
- Langkah 1: Masukin Data Mentah ke S3
- Langkah 2: Biarkan Glue Crawler Menentukan Schema-nya
- Langkah 3: ETL yang Sebenarnya: PySpark di Glue
- Langkah 4: Tampilan Output di S3
- Langkah 5: Mendefinisikan Schema Manual di Athena
- Langkah 6: Query dengan Athena
- Yang Saya Ambil dari Ini
- Selanjutnya
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_salesraw_productsraw_storesraw_customersraw_calendarHasilnya, 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 GlueContextfrom pyspark.context import SparkContextfrom pyspark.sql.functions import col, to_date, year, month
sc = SparkContext()glueContext = GlueContext(sc)spark = glueContext.spark_session
# Baca dari Data Catalogdatasource = glueContext.create_dynamic_frame.from_catalog( database="choco_db", table_name="raw_sales")
df = datasource.toDF()
# Parse tanggal dan ekstrak kolom partisidf = 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-partisidf.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 PARQUETLOCATION '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_parquetWHERE 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.