Orchestration at Scale — Data Engineering

Orchestration at Scale Setelah Airflow, ada generasi baru orchestrator yang mengatasi limitasi Airflow: Prefect dan Dagster. Keduanya menawarkan developer…

Orchestration at scale adalah menjalankan banyak pipeline milik banyak tim yang saling bergantung, tepat urutan, tepat data, dan ketahuan kalau ada yang macet. Satu DAG Airflow dari pelajaran sebelumnya cuma awalnya. Bayangin bandara. Banyak maskapai, banyak pesawat, satu menara kontrol. Pesawat lanjutan ke Makassar menunggu penumpang transit dari Medan yang mendarat telat; dia gak berangkat cuma karena jamnya sudah tiba, lalu meninggalkan separuh penumpangnya. Kalau satu pesawat tertahan terlalu lama, papan bandara menulis DELAYED supaya semua orang tahu. Menara kontrol itu orchestrator, jam keberangkatan itu cron, "berangkat setelah pesawat transit mendarat" itu penjadwalan berbasis data, dan papan DELAYED itu alert.

🧪 Tebakan cepat: Malam Minggu ke Senin, extract MySQL Toko Buku telat sampai 01:30. penjualan dijadwalkan cron 01:00, laris_mingguan cron 02:00, dan pemilik membacanya jam 06:00. Laporannya lengkap, kurang, atau gak ada? Tebak dulu, jawabannya ada di bagian "Cron atau data-aware".

Dari satu DAG ke banyak tim

Di pelajaran Airflow, satu DAG mengerjakan semuanya. Begitu tim bertambah, pipeline-nya terpecah, dan yang menyambungkan mereka adalah aset: tabel atau file yang dihasilkan satu pipeline dan dibaca pipeline lain. Graf aset kecil Toko Buku di Lab:

Aset Pemilik Dibaca oleh
raw_order_lines tim data, extract MySQL jam 00:05 penjualan
penjualan tim data, satu partisi per hari laris_mingguan, segmen_pelanggan
laris_mingguan tim data pemilik toko, Senin 06:00
segmen_pelanggan tim marketing kampanye email

segmen_pelanggan milik tim lain, di repo lain, dengan jadwal sendiri. Pertanyaannya: kapan dia boleh jalan?

Cron atau data-aware

Ada dua cara memicu penjualan:

Malam Minggu 4 ke Senin 5 Oktober, replica MySQL tertinggal dan raw_order_lines baru selesai 01:30. Partisi 4 Oktober berisi pesanan 8 milik Maya (1 Laskar Pelangi). Hasil Lab, dijalankan di SQLite:

Penjadwalan penjualan[2026-10-04] laris_mingguan siap Minggu 28 September
cron 01:00 jalan 01:00, 0 baris 02:00 12 buku, baris "Tidak diketahui" hilang
data-aware jalan 01:31, 1 baris 01:33 13 buku, lengkap

Dengan cron, laporannya kurang dan datang tepat waktu, tanpa error dan tanpa alarm. Itu jawaban tebakannya. Data-aware sedikit lebih lambat tapi benar, dan tim marketing ikut menunggu data yang lengkap.

Di Airflow 3, penjadwalan berbasis aset ditulis dengan Asset. Kode ini diparse Airflow 3.3.2 tanpa import error:

import pendulum
from airflow.sdk import Asset, dag, task

WIB = "Asia/Jakarta"
raw_order_lines = Asset("raw_order_lines")
penjualan = Asset("penjualan")


@dag(schedule="5 0 * * *", start_date=pendulum.datetime(2026, 9, 28, tz=WIB), catchup=False)
def extract_mysql():
    @task(outlets=[raw_order_lines])
    def muat_raw() -> None:
        ...  # salin pesanan kemarin dari replica MySQL

    muat_raw()


@dag(schedule=[raw_order_lines], start_date=pendulum.datetime(2026, 9, 28, tz=WIB), catchup=False)
def bangun_penjualan():
    @task(outlets=[penjualan])
    def muat_penjualan() -> None:
        ...  # DELETE lalu INSERT satu tanggal

    muat_penjualan()


extract_mysql()
bangun_penjualan()

Di Dagster (1.13.26), aset adalah pusatnya: tiap fungsi @dg.asset menghasilkan satu tabel, dan automation_condition mengatur kapan dia dibangun ulang. Potongan kode yang dijalankan di laptop dengan DuckDB:

harian = dg.DailyPartitionsDefinition(start_date="2026-09-28", timezone="Asia/Jakarta")


@dg.asset(partitions_def=harian)
def penjualan(context: dg.AssetExecutionContext) -> dg.MaterializeResult:
    tanggal = context.partition_key  # misalnya "2026-10-04"
    ...  # DELETE lalu INSERT satu tanggal
    return dg.MaterializeResult(metadata={"baris": baris})


@dg.asset(
    deps=[penjualan],
    automation_condition=dg.AutomationCondition.eager(),
    freshness_policy=dg.FreshnessPolicy.time_window(fail_window=timedelta(hours=30)),
    owners=["team:data"],
)
def laris_mingguan() -> dg.MaterializeResult: ...

AutomationCondition.eager() artinya "bangun ulang begitu upstream berubah". Di Prefect (3.8.8), pipeline-nya fungsi Python biasa dengan @flow dan @task(retries=2, retry_delay_seconds=300); sebuah deployment dijadwalkan dengan cron atau dipicu event lewat automation.

Sensor atau event

Kadang yang ditunggu bukan aset di orchestrator yang sama, misalnya file stok dari marketplace di folder SFTP.

Pakai event kalau sumbernya bisa memberi tahu, sensor kalau gak bisa.

SLA, freshness, dan alert

Pemilik membaca laris_mingguan Senin 06:00. Janji "laporan siap sebelum 06:00" disebut SLA (service level agreement), dan freshness adalah seberapa baru datanya. Ada dua alarm yang dibutuhkan:

Di Airflow 3, fitur SLA lama dihapus dan diganti Deadline Alerts. Dagster punya FreshnessPolicy seperti di kode atas (gagal kalau lebih dari 30 jam gak diperbarui). dbt punya source freshness dari pelajaran dbt. Hati-hati: cek kesegaran gak tahu isinya benar atau gak. Dengan cron di malam telat tadi, ceknya bilang OK, karena laporannya memang diperbarui jam 02:00. Tes kualitas data (pelajaran kualitas data) yang menangkap isinya.

Backfill besar dan idempotensi

Backfill adalah menjalankan ulang aset untuk tanggal-tanggal lama, misalnya setelah aturan transform diperbaiki. Backfill penjualan 28 September sampai 4 Oktober dengan Dagster 1.13.26, satu partisi sekali jalan, lalu laris_mingguan:

for tanggal in ["2026-09-28", "2026-09-29", "2026-09-30", "2026-10-01", "2026-10-02", "2026-10-03", "2026-10-04"]:
    hasil = dg.materialize([penjualan], partition_key=tanggal)
    meta = hasil.asset_materializations_for_node("penjualan")[0].metadata
    print(tanggal, hasil.success, meta["baris"].value)

hasil = dg.materialize([laris_mingguan])  # metadata-nya: jumlah buku minggu 28 September
print("laris_mingguan", hasil.success, hasil.asset_materializations_for_node("laris_mingguan")[0].metadata["buku_minggu_28_sep"].value)
2026-09-28 True 3
2026-09-29 True 1
2026-09-30 True 2
2026-10-01 True 2
2026-10-02 True 1
2026-10-03 True 0
2026-10-04 True 1
laris_mingguan True 13

Backfill aman cuma kalau tiap partisi idempoten, seperti di pelajaran ETL: DELETE tanggal itu dulu, baru INSERT. Dengan INSERT saja, tiap partisi yang sudah terisi jadi dobel, dan minggu itu jadi 26 buku. Di skala besar, waktunya juga dihitung. Setahun = 365 partisi; tiap partisi 2 menit, paling banyak 4 bersamaan: 92 gelombang, 184 menit. Batas paralel itu disengaja, supaya replica MySQL gak dibanjiri 365 query sekaligus.

Biaya

Orchestrator sendiri nyala 24 jam: scheduler, worker, database metadata, dan untuk Airflow juga triggerer dan API server. Sensor poke yang lama menunggu memakan slot worker. Backfill membayar compute warehouse untuk tiap partisi. Layanan terkelola memindahkan urusan server ke vendor, dengan harga bulanan: Astronomer, Google Cloud Composer, dan Amazon MWAA untuk Airflow; Dagster+ untuk Dagster; Prefect Cloud untuk Prefect. Untuk Toko Buku, cron plus satu DAG dari pelajaran Airflow masih cukup; orchestration at scale mulai terasa perlu waktu ada beberapa tim dan puluhan pipeline yang saling bergantung.

Airflow, Dagster, Prefect

Ketiganya open source (Apache 2.0) dan ditulis dengan Python. Versi per Oktober 2026: Airflow 3.3.2 (17 September 2026), Dagster 1.13.26 (9 Oktober 2026), Prefect 3.8.8 (6 Oktober 2026).

Airflow Dagster Prefect
Unit utama DAG dan task aset (tabel atau file) flow dan task (fungsi Python)
Data-aware aset sejak 3.0 (dataset sejak 2.4) inti desainnya, plus partisi dan backfill trigger dari event lewat automation
Coba di laptop airflow dags test dg.materialize(...) panggil fungsi flow-nya langsung
Kekuatan khas ekosistem operator dan provider terbesar lineage aset, integrasi dbt pipeline Python yang dinamis

Prefect dan Dagster lahir sesudah Airflow, dengan API Python native, penjadwalan berbasis data, dan pengalaman developer yang dirancang dari awal; itu perbedaan yang paling sering disebut. Airflow menyusul: TaskFlow API sejak 2.0, dataset sejak 2.4, aset dan import airflow.sdk di 3.0. Tim yang sudah punya ratusan DAG Airflow biasanya lebih untung meneruskannya; tim yang berpikir dalam tabel dbt sering cocok dengan Dagster; tim yang punya banyak script Python dan butuh retry serta trigger cepat sering cocok dengan Prefect. Pilih dari kebutuhan tim, bukan dari mana yang terdengar paling baru.

⚠️ Jebakan yang sering ketemu

TL;DR: Orchestration at scale menyambung pipeline banyak tim lewat aset: raw_order_lines, penjualan, laris_mingguan, dan segmen_pelanggan milik tim marketing. Cron menjalankan di jam tetap; data-aware menjalankan saat upstream diperbarui. Saat extract telat sampai 01:30, cron membuat laporan tepat waktu tapi kurang (12 buku), data-aware membuatnya 01:33 dan lengkap (13). Airflow 3 menulisnya outlets=[Asset(...)] dan schedule=[Asset(...)], Dagster dengan @dg.asset dan AutomationCondition.eager(), Prefect dengan deployment dan automation. Sensor mengecek berkala (37 cek untuk menunggu 3 jam), event memicu sekali. Pasang alarm gagal dan cek kesegaran (Deadline Alerts di Airflow 3, FreshnessPolicy di Dagster), dan ingat cek kesegaran gak menilai isi. Backfill aman cuma dengan partisi idempoten (INSERT saja: 26 buku, bukan 13), dan dibatasi paralelnya. Airflow 3.3.2, Dagster 1.13.26, dan Prefect 3.8.8 dipilih dari kebutuhan tim, bukan diperingkat.

Yang akan kamu pelajari