Executor

Membandingkan executor Local, Celery, dan Kubernetes beserta pertimbangan arsitekturnya.

Daftar isi

Topik ini membahas executor, yaitu komponen Airflow yang menjalankan task instance, beserta pertimbangan arsitekturnya. Tiga executor resmi dibandingkan berdampingan: LocalExecutor, CeleryExecutor, dan KubernetesExecutor. Aspek perbandingannya mencakup penempatan task, kebutuhan infrastruktur tambahan, isolasi dependensi, dan biaya operasional. Setelah topik ini, pemilihan executor dapat diputuskan berdasarkan kapasitas yang dibutuhkan dan kompleksitas yang mampu ditanggung.

Definisi dan batas tanggung jawab executor#

Executor adalah komponen yang mengambil task instance yang telah siap dari scheduler dan mengeksekusinya di suatu tempat. Scheduler menentukan kapan sebuah task layak dijalankan, sedangkan executor menentukan di mana dan bagaimana task tersebut dijalankan. Tempat eksekusinya dapat berupa proses anak pada mesin yang sama, pesan yang diambil worker terdistribusi, atau pod baru pada cluster Kubernetes. Satu instalasi Airflow menggunakan satu executor aktif pada satu waktu, dan nilai executor tersebut disimpan pada kunci core.executor.

Pemilihan executor sepenuhnya merupakan keputusan sisi deployment. Definisi DAG tidak memuat executor sama sekali, sehingga berkas DAG yang sama berjalan apa adanya meskipun executor diganti. DAG kecil berikut digunakan sebagai contoh sepanjang topik ini, dan tidak ada satu baris pun di dalamnya yang mengatur tempat eksekusi.

python dag_rekap_suhu.py
from airflow.sdk import dag, task
from pendulum import datetime


@dag(dag_id="rekap_suhu", schedule=None, start_date=datetime(2026, 11, 4))
def rekap_suhu():
    @task
    def kumpulkan_suhu() -> list[float]:
        return [24.5, 25.0, 23.8]

    @task
    def hitung_rata_rata(nilai: list[float]) -> float:
        return round(sum(nilai) / len(nilai), 2)

    hitung_rata_rata(kumpulkan_suhu())


rekap_suhu()

Dua task pada DAG rekap_suhu hanya berisi logika data, yaitu mengumpulkan deret suhu lalu menghitung rata-ratanya. Ketika executor diganti dari LocalExecutor menjadi CeleryExecutor, kedua task tersebut tetap berjalan dengan kode yang persis sama. Perubahan yang diperlukan hanya menyangkut infrastruktur dan konfigurasi Airflow.

Nilai bawaan pada Airflow 3#

Airflow 3.x menjadikan LocalExecutor sebagai nilai bawaan core.executor. Pada Airflow 2, pemasangan lokal menggunakan SequentialExecutor yang menjalankan task satu per satu. Versi 3.0 menghapus SequentialExecutor karena LocalExecutor mendukung SQLite dengan mode WAL (write-ahead logging), yaitu pencatatan perubahan ke berkas log sebelum diterapkan, dan memberikan paralelisme yang lebih baik. Pemasangan lokal tanpa PostgreSQL pun tetap dapat menjalankan task secara paralel.

Nilai executor yang efektif dibaca dengan perintah CLI berikut.

bash
# baca nilai executor efektif dari konfigurasi
export AIRFLOW_HOME=/tmp/ra-executor
airflow config get-value core executor
text Keluaran
LocalExecutor

Executor dapat diganti dengan variabel lingkungan tanpa menyunting airflow.cfg. Pola nama variabel lingkungan adalah AIRFLOW__BAGIAN__KUNCI, sehingga kunci core.executor menjadi AIRFLOW__CORE__EXECUTOR. Contoh berikut menimpa nilai executor hanya untuk satu proses tersebut.

bash
# timpa executor lewat variabel lingkungan untuk proses ini saja
export AIRFLOW_HOME=/tmp/ra-executor
AIRFLOW__CORE__EXECUTOR=CeleryExecutor airflow config get-value core executor
text Keluaran
CeleryExecutor

Untuk deployment permanen, nilai yang sama dinyatakan sebagai variabel lingkungan, misalnya di dalam berkas docker-compose.yaml berikut.

yaml
# contoh: menetapkan executor beserta koneksi broker melalui variabel lingkungan
environment:
  AIRFLOW__CORE__EXECUTOR: CeleryExecutor
  AIRFLOW__CELERY__BROKER_URL: redis://broker:6379/0

LocalExecutor#

LocalExecutor menjalankan task sebagai proses anak pada mesin yang sama dengan scheduler. Paralelisme executor ini dibatasi oleh kunci [core] parallelism yang nilai bawaannya 32, sehingga banyak task dapat berjalan serentak tanpa layanan tambahan apa pun. Penambahan kapasitas bersifat vertikal, yaitu menambah CPU dan memori mesin tersebut, karena seluruh task berbagi sumber daya mesin yang sama.

Executor ini cocok untuk pemasangan tunggal, lingkungan belajar, hingga tim kecil dengan beban moderat. Batas utama LocalExecutor adalah isolasi dependensi yang lemah, yaitu seluruh task berbagi satu lingkungan Python dan satu kumpulan library. Ketika satu task memerlukan versi library yang berbeda dari task lain, LocalExecutor tidak menyediakan pemisahan apa pun di antara keduanya.

CeleryExecutor#

CeleryExecutor menyerahkan eksekusi task ke framework Celery. Task dikirim ke broker, yaitu layanan antrean pesan perantara, lalu diambil oleh worker Celery yang dapat berjalan pada banyak mesin terpisah. Kebutuhan tambahannya adalah broker yang aktif, umumnya Redis atau RabbitMQ, beserta paket provider apache-airflow-providers-celery yang terpasang di seluruh node. Nilai bawaan celery.broker_url menunjuk ke redis://redis:6379/0, sehingga host broker perlu disesuaikan dengan topologi masing-masing.

Penambahan kapasitas bersifat horizontal, yaitu menambah jumlah mesin worker tanpa menyentuh scheduler. Dokumentasi deployment production mencantumkan dua catatan penting. Pertama, seluruh node harus memuat berkas DAG dan konfigurasi yang sama. Kedua, pemantauan kesehatan worker dapat memanfaatkan alat flower yang disediakan ekosistem Celery. Biaya operasional CeleryExecutor lebih tinggi daripada LocalExecutor karena satu layanan tambahan harus dijaga ketersediaannya.

KubernetesExecutor#

KubernetesExecutor menjalankan task dengan membuat satu pod per task pada cluster Kubernetes melalui paket provider apache-airflow-providers-cncf-kubernetes. Setiap pod dibuat tepat ketika task perlu berjalan dan dihapus setelah selesai. Dengan demikian, kapasitas komputasi mengikuti beban. Scheduler tetap berjalan di luar cluster atau di dalam cluster, sedangkan eksekusi task tersebar ke seluruh node yang tersedia.

Isolasi dependensi menjadi paling tegas pada executor ini karena setiap task membawa image kontainer, batas CPU, dan batas memori sendiri. Kompleksitas operasinya paling tinggi karena cluster Kubernetes harus dikelola, hak akses ke cluster harus diatur, dan setiap image per task harus tersedia. Waktu mulai task juga lebih lama daripada di LocalExecutor karena pod menunggu penjadwalan dan penarikan image terlebih dahulu.

Perbandingan dan pertimbangan#

AspekLocalExecutorCeleryExecutorKubernetesExecutor
Batas penempatansatu mesinbanyak mesin workerbanyak node cluster
Layanan tambahantidak adabroker Redis atau RabbitMQcluster Kubernetes
Isolasi dependensiberbagi satu lingkunganper workerper pod, paling tegas
Menambah kapasitasvertikalhorizontal melalui workerotomatis melalui pod
Kompleksitas operasirendahsedangtinggi
Cocok untukpemasangan tunggal dan belajartim dengan beban yang tumbuhdependensi beragam dan banyak tim

Empat pertimbangan mendasar melandasi tabel di atas. Dari sisi throughput, yaitu jumlah task yang dapat diselesaikan per satuan waktu, kedua executor terdistribusi menambah kapasitas dengan menambah mesin. LocalExecutor terbatas pada kapasitas satu mesin. Dari sisi isolasi, pod per task memberikan pemisahan paling tegas, diikuti oleh worker Celery, sedangkan LocalExecutor tidak memisahkan apa pun. Dari sisi biaya operasional, LocalExecutor paling murah, sedangkan setiap layanan tambahan seperti broker atau cluster membutuhkan penjagaan ketersediaan. Dari sisi kompleksitas, peringkatnya mengikuti urutan biaya, sehingga executor paling sederhana yang memenuhi kebutuhan biasanya menjadi pilihan yang tepat.

Kesalahan umum#

Mencari SequentialExecutor pada Airflow 3.x. Executor tersebut dihapus sejak versi 3.0 dan digantikan LocalExecutor, termasuk pada pemasangan dengan SQLite. Tutorial lama yang menyarankan SequentialExecutor tidak lagi berlaku untuk versi 3.x.

Mengira pergantian executor menuntut penulisan ulang DAG. Definisi DAG tidak menyentuh executor, sehingga yang berubah hanya konfigurasi Airflow dan infrastruktur pendukungnya. Ujilah dengan DAG rekap_suhu di awal topik ini, yang sama sekali tidak menyebut executor.

Memilih executor terdistribusi untuk lingkungan belajar satu mesin. Broker maupun cluster yang baru disiapkan menambah pekerjaan operasional tanpa menambah kapasitas yang terpakai. LocalExecutor dengan nilai bawaan sudah menjalankan task secara paralel pada satu mesin.

Ringkasan#

  • Executor menjalankan task instance hasil keputusan scheduler, dan pilihannya berada sepenuhnya di sisi deployment tanpa menyentuh kode DAG.
  • Airflow 3.x menjadikan LocalExecutor sebagai nilai bawaan, sedangkan SequentialExecutor telah dihapus sejak versi 3.0.
  • LocalExecutor berbagi satu mesin, CeleryExecutor mendistribusikan task melalui broker dan worker, serta KubernetesExecutor membuat satu pod per task.
  • Pertimbangan pemilihannya adalah throughput, isolasi dependensi, biaya operasional, dan kompleksitas yang siap ditanggung.

Referensi#