Membangun orkestrasi batch pipeline dengan Apache Airflow: konsep DAG, task, dan operators, cara scheduling bekerja, penanganan retry & failure, monitoring eksekusi, serta praktik membangun DAG ekstraksi-transformasi-load dari nol sampai berjalan

Setelah di episode 7 kalian membangun model dbt yang rapi, muncul pertanyaan operasional: siapa yang menjalankannya setiap malam? Jawabannya: orkestrator. Cron sederhana tidak cukup — pipeline produksi butuh retry otomatis, penanganan kegagalan, logging, dan visibilitas.
Episode ini membangun fondasi orkestrasi batch dengan Apache Airflow, standar industri yang (masih) paling banyak dipakai. Kalian akan memahami DAG, operators, scheduling, dan praktik membangun pipeline ekstraksi → transformasi → load yang benar-benar berjalan.
Airflow bekerja dengan Directed Acyclic Graph (DAG): sekumpulan task (unit kerja) yang dihubungkan dengan ketergantungan. "Acyclic" berarti tidak boleh ada siklus — aliran selalu maju dari awal ke akhir.
Setiap task adalah satu operator: eksekusi Python, query SQL, transfer data, atau perintah Bash. DAG adalah kode Python — dan itu kekuatan Airflow: seluruh pipeline bisa di-versioning dan di-review seperti software.
Scheduling Airflow adalah salah satu konsep yang paling sering disalahpahami. schedule_interval menentukan kapan sebuah DAG Run dimulai — dan aturan pentingnya: DAG run untuk interval T dimulai SETELAH interval T berakhir.
from airflow import DAG
from airflow.operators.python import PythonOperator
from airflow.providers.postgres.operators.postgres import PostgresOperator
from datetime import datetime, timedelta
default_args = {
"retries": 3,
"retry_delay": timedelta(minutes=5),
"retry_exponential_backoff": True,
"max_retry_delay": timedelta(hours=1),
}
with DAG(
dag_id="batch_pipeline",
default_args=default_args,
start_date=datetime(2026, 8, 16),
schedule_interval="0 2 * * *", # tiap hari pukul 02:00
catchup=False,
max_active_runs=1,
) as dag:
extract = PythonOperator(
task_id="extract_orders",
python_callable=extract_orders, # dari episode 5
)
transform = PostgresOperator(
task_id="transform_sql",
sql="sql/clean_orders.sql",
postgres_conn_id="de_lab",
)
load = PostgresOperator(
task_id="load_marts",
sql="sql/build_marts.sql",
postgres_conn_id="de_lab",
)
extract >> transform >> loadPerhatikan baris terakhir: extract >> transform >> load — sintaks Airflow untuk menyusun ketergantungan. Seluruh pipeline batch kalian bisa dibangun dari pola ini.
Cara tercepat menjalankan Airflow adalah dengan Docker Compose resmi:
curl -LfO https://airflow.apache.org/docs/apache-airflow/stable/docker-compose.yaml
mkdir -p ./dags ./logs ./plugins ./config
docker compose up -dSetelah berjalan, buka http://localhost:8080 (login default airflow/airflow). Airflow memakai PostgreSQL sebagai metadata database dan scheduler + webserver sebagai komponen utama — arsitektur ini kita bedah lebih dalam di episode 13.
Airflow memberikan visibilitas eksekusi secara out-of-the-box:
airflow dags list
airflow tasks test batch_pipeline extract_orders 2026-08-16
airflow dags trigger batch_pipelineairflow tasks test menjalankan satu task saja — alat debugging terbaik untuk memisahkan "masalah pipeline" vs "masalah kode".
Pipeline batch produksi biasanya mengikuti pola ini:
dbt build).from airflow import DAG
from airflow.operators.bash import BashOperator
from airflow.operators.python import PythonOperator
from datetime import datetime
with DAG(
dag_id="elt_daily",
start_date=datetime(2026, 8, 16),
schedule_interval="0 1 * * *",
catchup=False,
) as dag:
extract = PythonOperator(
task_id="extract_incremental",
python_callable=extract_incremental, # fungsi incremental
)
dbt_build = BashOperator(
task_id="dbt_build",
bash_command="cd ~/de-lab/dbt_project && dbt build",
)
quality = BashOperator(
task_id="data_quality",
bash_command="cd ~/de-lab/dbt_project && dbt test --select severity:error",
)
notify = BashOperator(
task_id="notify_success",
bash_command="curl -s -X POST https://webhook.example/success",
)
extract >> dbt_build >> quality >> notifyIni contoh nyata: orkestrasi memanggil tool lain (dbt) dan memberi tahu konsumen. Pipeline tidak lagi sekumpulan script, melainkan produk dengan siklus hidup — dan itulah yang membedakan data engineer junior dari senior.
Warning
Jangan pernah menjalankan transformasi dengan max_active_runs tidak terbatas tanpa catchup yang disadari. Pipeline batch yang menumpuk run (karena scheduler downtime) akan mengeksekusi ribuan backfill sekaligus. Pahami catchup, max_active_runs, dan depends_on_past sebelum naik produksi.
Salah paham scheduling. schedule_interval="0 2 * * *" berarti run untuk data kemarin mulai jam 2 pagi setelah interval — bukan jam 2 pagi untuk data hari itu. Pahami logical_date vs execution_date.
Menulis semua logika dalam satu task raksasa. Pecah menjadi task kecil agar retry hanya mengulang bagian yang gagal, bukan seluruh pipeline.
Tanpa retry dan tanpa notification. Pipeline yang gagal diam-diam adalah pembunuh kepercayaan data. Set retries dan alert.
Mengandalkan web UI untuk menjalankan DAG. Semua eksekusi harus lewat scheduler — trigger manual dari UI hanya untuk debugging.
Di episode 8 ini kalian telah membangun orkestrasi batch pipeline:
catchup dan max_active_runs.Di episode 9 selanjutnya kita naik ke level penyimpanan analitik: data warehouse cloud (Snowflake/BigQuery/Redshift) — arsitektur warehouse modern, partitioning & clustering, dan strategi cost management, plus praktik optimasi query di warehouse. Sampai jumpa di episode 9!