- Oban.py adalah versi port framework pemrosesan job Oban dari Elixir ke Python berbasis PostgreSQL, sehingga job dapat dimasukkan dan diproses hanya dengan database
- Job dibuat dan di-rollback di dalam transaksi database, serta mendukung berbagai fitur seperti manajemen queue, penyimpanan hasil, dan penjadwalan cron
- Versi open-source memiliki batasan seperti eksekusi asyncio single-thread dan insert serta acknowledgement per item, tetapi versi Pro menyediakan pemrosesan paralel, workflow, dan smart concurrency
- Mekanisme internal terdiri dari lima tahap:
Insert → Notify → Fetch → Execute → Ack, dan memanfaatkan PostgreSQL FOR UPDATE SKIP LOCKED untuk mencegah konflik konkurensi
- Pemilihan leader, pemulihan job yatim, dan retry backoff juga dijalankan berbasis database, sehingga memungkinkan pemrosesan terdistribusi yang stabil tanpa broker eksternal
Ikhtisar Oban.py
- Oban.py adalah framework pemrosesan job berbasis database yang mem-porting Oban dari Elixir ke Python
- Job dimasukkan dan diproses di dalam transaksi database, dan jika gagal seluruh transaksi akan di-rollback
- Mencakup berbagai fitur kontrol seperti batas queue, penyimpanan job selesai, retensi hasil, dan penjadwalan cron
- Tersedia dalam dua versi
- Open-source (OSS): eksekusi asyncio single-thread, insert dan acknowledgement per item, pemulihan sederhana
- Versi Pro: pemrosesan paralel berbasis process pool, mendukung workflow, relay, unique job, dan smart concurrency
- OSS cocok untuk proyek pribadi atau evaluasi, sedangkan versi Pro direkomendasikan untuk lingkungan skala besar
Jalur pemrosesan job
- Setelah job dimasukkan, ia disimpan di tabel
oban_jobs dengan state='available', lalu notifikasi dikirim ke tiap node melalui PostgreSQL NOTIFY
- Stager di tiap node mendeteksi queue terkait dan membangunkan Producer, lalu Producer mengambil dan menjalankan job
- Saat memilih job, SQL
FOR UPDATE SKIP LOCKED digunakan agar pemrosesan paralel bisa dilakukan tanpa eksekusi duplikat
- Baris yang sudah terkunci dilewati, sehingga producer lain bisa segera mengambil job lain
- Job dikirim sebagai async task, dan saat selesai callback akan menangani acknowledgement
- Versi Pro menggunakan dispatcher process pool alih-alih asyncio untuk mendukung eksekusi paralel multicore
Proses latar belakang
- Pemilihan leader (Leader Election)
- Leader ditentukan dengan
INSERT ... ON CONFLICT PostgreSQL dan lease berbasis TTL
- Tanpa protokol konsensus terpisah, satu leader menangani pembersihan dan pemulihan job
- Lifeline (pemulihan job yatim)
- Jika job yang sedang berjalan berlangsung lebih lama dari waktu tertentu (
rescue_after, default 5 menit), job akan dipulihkan ke status available
- Versi Pro memeriksa apakah producer masih hidup, sedangkan OSS hanya menilai berdasarkan waktu
- Pruner (pembersihan job)
- Menghapus job selesai, dibatalkan, atau dibuang yang sudah melewati
max_age (default 1 hari)
- Cakupan penghapusan dibatasi dengan
LIMIT untuk mencegah beban database
Retry dan backoff
- Jika job memunculkan exception, Executor menentukan apakah job perlu di-retry
- Jika belum mencapai jumlah percobaan maksimum (
max_attempts), job akan di-retry; jika melampaui, job dibuang
- Backoff default menggunakan kenaikan eksponensial dengan jitter
- Mencegah retry serentak saat terjadi kegagalan massal, sehingga meredam lonjakan beban (Thundering Herd)
- Contoh: percobaan pertama sekitar 17 detik, percobaan ke-5 sekitar 47 detik, percobaan ke-10 sekitar 17 menit
- Kelas worker dapat mengimplementasikan logika backoff kustom melalui metode
backoff()
Karakteristik utama dan evaluasi
- PostgreSQL memegang peran inti
- Melalui
FOR UPDATE SKIP LOCKED, LISTEN/NOTIFY, dan ON CONFLICT, PostgreSQL menangani sekaligus kontrol konkurensi, pengiriman sinyal, dan pemilihan leader
- Tanpa Redis atau broker eksternal, satu database dapat membentuk lapisan koordinasi
- Tidak paralel, tetapi mendukung konkurensi
- Berbasis asyncio sehingga cocok untuk pekerjaan I/O-bound, sedangkan pekerjaan CPU-bound lebih cocok memakai versi Pro
- Struktur kode jelas
- Penamaan konsisten dan pemisahan tanggung jawab yang rapi membuat codebase mudah dibaca
- Pemisahan peran OSS dan Pro jelas
- OSS untuk eksperimen dan skala kecil, Pro untuk lingkungan berskala besar dan berkinerja tinggi
- Kesimpulan: port Python yang rapi dan terstruktur, yang mewujudkan job queue lengkap hanya dengan PostgreSQL, cocok bagi pengguna Elixir atau developer yang menginginkan sistem job tanpa infrastruktur eksternal
1 komentar
Komentar Hacker News
Saya pembuat Sidekiq, dan ingin mengucapkan selamat atas rilis yang dibuat Shannon dan Parker kali ini.
Dulu saya juga memikirkan hal yang sama — apakah harus fokus ke Ruby, atau memperluas Sidekiq ke bahasa lain. Saya sadar saya tidak mungkin menjadi ahli di semua bahasa, jadi saya membuat Faktory. Ini adalah struktur di mana server pusat mengelola siklus hidup antrean, sementara klien untuk tiap bahasa tetap sederhana. Misalnya ada klien seperti faktory-rs. Kekurangannya, karena tidak fokus pada komunitas bahasa tertentu, sulit menyediakan contoh yang benar-benar cocok untuk bahasa tersebut.
Pendekatan yang fokus pada satu komunitas mungkin bisa memberi hasil yang lebih baik. Waktu yang akan menjawab
Inti dari Oban adalah bahwa job bisa dimasukkan dan diproses hanya dengan database. Di dalam transaksi pembuatan pengguna, Anda bisa sekaligus memasukkan job pengiriman email, dan jika gagal semuanya di-rollback.
Banyak orang bilang jangan memakai DB relasional sebagai antrean job, tetapi mereka mengabaikan pentingnya transaksi. Tulisan Brandur Leach, Job Drain, juga menjelaskan konsep ini dengan baik
Tapi sekarang tak ada lagi yang ingat betapa menyebalkannya masalah itu. “Transactional outbox pattern” itu wajib, dan saya lebih suka pendekatan yang memberi jaminan ACID yang sama seperti data saya.
Meski tidak paham detail internal DB, meluangkan seminggu untuk mempelajari isolation level dan urutan commit bisa menghemat satu tahun debugging sistem terdistribusi
Di era ketika proses AI yang panjang sangat banyak, durabilitas seperti ini itu wajib. Di ekosistem bahasa lain Anda harus membayar untuk fitur seperti ini, tetapi di Oban itu tersedia bawaan
Tim Oban dikenal karena rekayasa yang matang di ekosistem Elixir. Namun, mengunci process pool di versi Pro terasa membingungkan.
Misalnya, paket $135/bulan mencakup eksekusi multiproses, workflow, batas global, unique job, pekerjaan massal, sumber terenkripsi, dukungan khusus, dan lain-lain.
Proyek saya Chancy sepenuhnya gratis, dan memungkinkan mencampur asyncio, proses, thread, dan subinterpreter secara bebas.
Menurut saya akan lebih baik jika fitur seperti ini dipindahkan ke OSS, dan yang berbayar difokuskan pada dukungan enterprise. Di ekosistem Python kompetitornya jauh lebih banyak
Model yang hanya menjual dukungan ternyata kurang cocok, tapi mungkin di Python hasilnya berbeda.
Di ekosistem Python memang benar-benar semuanya ada banyak
Jika Chancy menambahkan dukungan Django Tasks atau membuat paket
django-chancy, sepertinya adopsinya bisa cepatOban OSS hanya mendukung eksekusi asyncio single-threaded, sehingga job yang CPU-bound akan memblokir event loop.
Karena itu saya merasa tidak layak dicoba. Antarmuka Celery memang kurang bagus, tapi sudah familiar dan bisa diskalakan vertikal maupun horizontal tanpa batas.
Namun setelah tahu bahwa beberapa node worker bisa dijalankan, pandangan saya agak berubah
Pemisahan fitur OSS/Pro tidak masalah, tetapi kalimat seperti “versi Pro melacak kelangsungan hidup producer dengan heartbeat yang lebih pintar” terasa disayangkan.
Jika fitur terkait reliabilitas berbayar, proyek OSS jadi sulit mengadopsinya
Versi dasar seharusnya yang terbaik, lalu fitur tambahan yang berbayar. Batasnya terasa berada di posisi yang aneh
Kalimat yang dikutip itu agak kurang tepat — pelacakan kelangsungan producer sama, perbedaannya hanya pada cara pemulihan job yatim
Saya berharap workflow BI/ML/DS di Python bisa pindah ke Elixir.
Elixir yang fungsional, toleran gangguan, dan sangat konkuren menurut saya jauh lebih alami sebagai fondasi untuk pekerjaan seperti ini
Video ini dan panduan Elixir Genius adalah referensi yang bagus
Perusahaan kami juga memakai Celery, dan memang tidak terlalu bagus. Temporal terlalu berat, sementara Oban terasa ringan dan menarik.
Saya penasaran dengan perbandingan dari orang yang pernah memakai keduanya
Temporal cocok untuk organisasi yang membutuhkan jaminan workflow dan sanggup menanggung kompleksitasnya, misalnya bank.
Oban adalah antrean berbasis DB, jadi reliabilitasnya perlu diperkuat sendiri.
Menurut saya akan bagus jika keduanya ada bersama dalam satu sistem
Kami memakai kombinasi ProcessWorker sederhana dan worker ECS
Saya penasaran apakah Celery belakangan ini menjadi kurang stabil atau lebih sulit ditangani
Proyek yang menarik. Namun terlihat bahwa beberapa fitur inti hanya ada di Pro.
Proyek pendahulu yang mengimplementasikan workflow durable berbasis Postgres sebagai OSS antara lain DBOS dan Absurd.
Menyenangkan melihat pendekatan yang berpusat pada database makin banyak
Model yang sepenuhnya open source dan berjalan hanya dengan menjual dukungan adalah model impian. Semoga suatu hari bisa terwujud
Saya penasaran apakah performanya cukup untuk memproses ratusan juta job dengan Postgres. Dulu saya melihat peningkatan performa besar setelah pindah ke Redis + Sidekiq
Katanya versi OSS bisa salah memulihkan jika ada job panjang meskipun producer masih hidup.
Kalau begitu apakah hanya cocok untuk job pendek?
Timing pemulihan hanya berbeda jika tidak sempat menunggu penghentian normal