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

Kenapa Aku Mulai Belajar AWS Glue

Sekarang aku kerja dengan data yang skalanya jauh di atas apa pun yang pernah aku pegang sebelumnya. Kita bicara soal terabyte, dan tiap hari nambah terus. Detailnya nggak bisa aku cerita, tapi industri ini memang menghasilkan data yang banyaknya nggak main-main, dan menjaga data itu tetap bisa di-query dan tetap terkelola itu tantangan engineering tersendiri.

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

Pipeline-nya aku bangun pakai dataset penjualan dari Kaggle (Chocolate Sales Dataset 2023-2024) supaya pola yang aku lihat di pekerjaan bisa aku replikasi di konteks yang lebih sederhana dan bisa aku bagikan. Postingan ini adalah walkthrough-nya.


Arsitekturnya

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 groundbreaking, tapi pola inilah yang bakal kamu temuin di setup data lake sungguhan.


Step 1: Masukin Data Mentah ke S3

Pertama: upload file CSV ke S3. Sejak awal aku jaga struktur foldernya tetap rapi, karena aku belajar cukup cepat bahwa layout S3-mu itu ya model data-mu. 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 β€” jangan campur file dengan struktur beda di folder yang sama. Glue Crawler bakal berterima kasih.


Step 2: Biarkan Glue Crawler Menentukan Schema-nya

Daripada mendefinisikan semuanya manual dari awal, aku 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-ku:

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

Setelah crawl, aku dapat tabel-tabel ini:

raw_sales
raw_products
raw_stores
raw_customers
raw_calendar

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

Satu hal yang aku sadari: Crawler kadang salah nebak tipe data, terutama di kolom yang keliatannya angka padahal isinya ID, atau di kolom tanggal. Worth banget dicek ulang sebelum kamu mengandalkan schema hasil infer-nya buat sesuatu yang serius.


Step 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 aku 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.


Step 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 secara signifikan.

Salah satu hal yang kelihatan jelas kalau dipikir belakangan, tapi gampang kelewatan waktu baru mulai di data engineering.


Step 5: Mendefinisikan Schema Manual di Athena

Meski Crawler bisa detect schema, aku lebih suka mendefinisikannya manual buat tabel yang sudah diproses. Dengan cara ini aku punya kontrol eksplisit, nggak ada kejutan mismatch tipe data, dan tabelnya lebih 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.


Step 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 Aku Ambil dari Ini

Auto schema detection itu berguna, tapi rapuh. Crawler bagus buat eksplorasi data baru dengan cepat, tapi aku 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-mu adalah strategi query-mu. Aku 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. Aku sudah tahu Parquet lebih baik dari CSV buat analytics, tapi melihatnya langsung di praktik β€” query lebih cepat dan footprint storage lebih kecil β€” bikin hal itu terasa nyata. Kalau kamu membangun apa pun yang analytics-related, benar-benar nggak ada alasan buat tetap bertahan di CSV.

Glue Job itu mahal kalau konfigurasinya nggak benar. 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 nge-drive dashboard atau jadi bahan pipeline machine learning.

Itu akan aku tulis di postingan berikutnya.


Repository

Tambahkan link repository GitHub-mu di sini

Related Posts