- Oban.py, Elixir'in iş işleme çatısı Oban'ın PostgreSQL tabanlı olarak Python'a taşınmış sürümü; yalnızca veritabanı ile işler eklenip işlenebiliyor
- İşler veritabanı işlemleri içinde oluşturulup geri alınabiliyor ve kuyruk yönetimi, sonuç saklama, cron zamanlama gibi çeşitli özellikleri destekliyor
- Açık kaynak sürümünde tek iş parçacıklı asyncio çalıştırma ve tek tek ekleme/onaylama işleme gibi kısıtlar bulunurken, Pro sürümü paralel işleme, workflow ve akıllı eşzamanlılık sunuyor
- İç işleyiş
Insert → Notify → Fetch → Execute → Ack olmak üzere beş adımdan oluşuyor ve PostgreSQL'in FOR UPDATE SKIP LOCKED özelliğini kullanarak eşzamanlılık çakışmalarını önlüyor
- Lider seçimi, sahipsiz iş kurtarma ve backoff tabanlı yeniden deneme de veritabanı üzerinden yürütülerek harici broker olmadan güvenilir dağıtık işleme sağlanıyor
Oban.py genel bakış
- Oban.py, Elixir'deki Oban'ın Python'a port edilmiş veritabanı tabanlı bir iş işleme çatısı
- İşler veritabanı işlemleri içinde eklenip işleniyor; başarısızlık durumunda tüm işlem geri alınıyor
- Kuyruk sınırları, tamamlanan işlerin saklanması, sonuçların tutulması, cron zamanlama gibi çeşitli kontrol özelliklerini içeriyor
- İki sürüm sunuluyor
- Açık kaynak (OSS): tek iş parçacıklı asyncio yürütmesi, tek tek ekleme/onaylama, basit kurtarma
- Pro sürüm: process pool tabanlı paralel işleme, workflow, relay, benzersiz iş, akıllı eşzamanlılık desteği
- OSS kişisel projeler veya değerlendirme için uygunken, büyük ölçekli ortamlar için Pro sürümü öneriliyor
İş işleme akışı
- İş eklendikten sonra
oban_jobs tablosuna state='available' olarak kaydediliyor ve PostgreSQL'in NOTIFY özelliğiyle her düğüme bildirim gönderiliyor
- Her düğümdeki Stager ilgili kuyruğu algılayıp Producer'ı uyandırıyor, Producer da işi alıp çalıştırıyor
- İş seçerken SQL'deki
FOR UPDATE SKIP LOCKED kullanılarak yinelenen yürütme olmadan paralel işleme mümkün oluyor
- Hâlihazırda kilitli satırlar atlanıyor, böylece başka producer'lar diğer işleri hemen alabiliyor
- İşler async task olarak dispatch ediliyor; tamamlandığında callback ile acknowledgement işleniyor
- Pro sürüm, asyncio yerine process pool dispatcher kullanarak çok çekirdekli paralel çalıştırmayı destekliyor
Arka plan süreçleri
- Lider seçimi (Leader Election)
- PostgreSQL'in
INSERT ... ON CONFLICT yapısı ve TTL tabanlı lease ile lider belirleniyor
- Ayrı bir uzlaşma protokolü olmadan tek lider iş temizleme ve kurtarma görevini üstleniyor
- Lifeline (sahipsiz iş kurtarma)
- Çalışan bir iş belirli bir süreyi (
rescue_after, varsayılan 5 dakika) aşarsa available durumuna geri alınıyor
- Pro sürüm producer'ın hayatta olup olmadığını kontrol ederken, OSS yalnızca zamana göre karar veriyor
- Pruner (iş temizleme)
- Tamamlanmış, iptal edilmiş veya terk edilmiş işler içinde
max_age (varsayılan 1 gün) süresini aşan kayıtlar siliniyor
- Veritabanı yükünü önlemek için silme kapsamı
LIMIT ile sınırlandırılıyor
Yeniden deneme ve backoff
- İş bir istisna üretirse Executor yeniden denenip denenmeyeceğine karar veriyor
- Maksimum deneme sayısının (
max_attempts) altındaysa yeniden deneniyor, aşarsa terk ediliyor
- Varsayılan backoff, jitter içeren üstel artışlı bir yapı kullanıyor
- Toplu hatalarda aynı anda yeniden denemeyi engelleyerek ani yük artışını (Thundering Herd) hafifletiyor
- Örnek: 1. denemede yaklaşık 17 saniye, 5. denemede yaklaşık 47 saniye, 10. denemede yaklaşık 17 dakika bekleme
- Worker sınıfı,
backoff() metodu ile kullanıcı tanımlı backoff mantığı uygulayabiliyor
Öne çıkan özellikler ve değerlendirme
- PostgreSQL merkezi rol oynuyor
FOR UPDATE SKIP LOCKED, LISTEN/NOTIFY, ON CONFLICT ile eşzamanlılık kontrolü, sinyal iletimi ve lider seçimi tamamen burada gerçekleştiriliyor
- Redis ya da harici broker olmadan tek veritabanıyla bir koordinasyon katmanı kuruluyor
- Paralel değil ama eşzamanlılık destekli
- asyncio tabanlı yapısı I/O bound işler için uygun; CPU bound işler için Pro sürüm öneriliyor
- Kod yapısı net
- Tutarlı adlandırma ve ayrılmış sorumluluk yapısı sayesinde okuması kolay bir kod tabanı sunuyor
- OSS ile Pro arasındaki rol ayrımı net
- OSS deneysel/küçük ölçekli kullanım için, Pro ise büyük ölçekli/yüksek performanslı ortamlar için konumlanıyor
- Sonuç: Yalnızca PostgreSQL ile tam teşekküllü bir iş kuyruğu sunan temiz ve iyi yapılandırılmış bir Python portu; Elixir kullanıcıları veya harici altyapı olmadan iş sistemi isteyen geliştiriciler için uygun
1 yorum
Hacker News görüşleri
Ben Sidekiq'in yaratıcısıyım; Shannon ve Parker'ın bu yayını için tebrikler
Geçmişte ben de aynı ikilemle uğraştım — Ruby'ye mi odaklanmalıydım, yoksa Sidekiq'i başka dillere mi genişletmeliydim. Tüm dillerde uzman olamayacağımı fark ettim ve bunun yerine Faktory'yi yaptım. Burada merkezi bir sunucu kuyruğun yaşam döngüsünü yönetiyor ve dil başına istemciler basit kalıyor. Örneğin faktory-rs gibi bir istemci var. Dezavantajı ise belirli bir dil topluluğuna odaklanmadığı için o dile uygun örnekler sunmanın zor olması.
Tek bir topluluğa odaklanan yaklaşımın daha iyi sonuç verebileceğini düşünüyorum. Zaman gösterecek
Oban'ın özü, yalnızca veritabanını kullanarak işleri ekleyip işleyebilmeniz. Kullanıcı oluşturma işleminin transaction'ı içinde e-posta gönderme işini de ekleyebiliyorsunuz ve başarısız olursa her şey rollback oluyor.
Birçok kişi ilişkisel DB'nin iş kuyruğu olarak kullanılmaması gerektiğini söyler ama transaction'ın önemini gözden kaçırıyorlar. Brandur Leach'in Job Drain yazısı da bu kavramı çok iyi anlatıyor
Ama artık kimse o acıyı hatırlamıyor. “Transactional outbox pattern” zorunlu ve ben verilerimle aynı ACID garantilerini alan bir yaklaşımı tercih ediyorum.
DB'nin iç işleyişini bilmeseniz bile, isolation level ve commit ordering öğrenmeye bir hafta ayırmak size dağıtık sistem debug etmeye harcayacağınız bir yılı kazandırabilir
Uzun süren yapay zeka süreçlerinin bol olduğu bir çağda bu tür dayanıklılık şart. Başka dil ekosistemlerinde bunun için para ödersiniz ama Oban'da bu kutudan çıktığı gibi geliyor
Oban ekibi, Elixir ekosisteminde çok rafine mühendislikleriyle tanınıyor. Ama process pool'u Pro sürüme kilitlemeleri kafa karıştırıcı.
Örneğin aylık $135 planda multi-process execution, workflow, global limits, unique jobs, bulk actions, encrypted sources ve özel destek var.
Benim projem Chancy tamamen ücretsiz ve asyncio, process, thread, sub-interpreter'ı istediğiniz gibi karıştırabiliyorsunuz.
Bence bu özellikleri OSS'ye taşıyıp ücretli kısmı kurumsal destek etrafında konumlandırmak daha iyi olabilir. Python ekosisteminde çok daha fazla rakip var
Yalnızca destek satarak ilerleyen model bize pek uymadı ama Python'da farklı olabilir.
Python ekosisteminde gerçekten her şeyden çok var
Chancy'ye Django Tasks desteği eklense ya da
django-chancypaketi çıksa hızlı benimsenebilir gibi görünüyorOSS Oban yalnızca tek iş parçacıklı asyncio yürütmesini destekliyor; bu yüzden CPU-bound işler event loop'u tıkıyor.
Bu yüzden denemeye değer olmadığını düşündüm. Celery arayüzünü çok sevmiyorum ama tanıdık ve dikey/yatay olarak sonsuza kadar ölçeklenebiliyor.
Ama birden fazla worker node çalıştırılabildiğini öğrenince fikrim biraz değişti
OSS/Pro özellik ayrımı normal ama “Pro sürüm, producer'ın hayatta olup olmadığını daha akıllı heartbeat ile izler” denmesi üzücü.
Güvenilirlikle ilgili özelliklerin ücretli olması, OSS projelerinde benimsenmesini zorlaştırıyor
En iyi olan temel sürüm olmalı, ek özellikler ücretli olmalı. Sınır biraz garip bir yerde duruyor gibi
Alıntılanan cümle biraz hatalı — producer canlılık takibi aynı, fark sadece yetim işlerin kurtarılma biçiminde
Python'daki BI/ML/DS workflow'larının Elixir'e taşındığını görmek isterdim.
Fonksiyonel, hata toleranslı ve yüksek eşzamanlılıklı Elixir'in bu işler için çok daha doğal bir temel olduğunu düşünüyorum
Bu video ve Elixir Genius rehberi iyi referanslar
Şirketimiz de Celery kullanıyor ama çok iyi sayılmaz. Temporal fazla ağır, Oban ise hafif ve hoş görünüyor.
İkisini de kullanmış birinin karşılaştırmasını merak ediyorum
Temporal, workflow garantilerini ve karmaşıklığını göze alabilen kurumlar için uygun; örneğin bankalar.
Oban ise DB tabanlı bir kuyruk; güvenilirliğini kendiniz güçlendirmeniz gerekiyor.
Bence ikisinin de aynı sistemde yeri olabilir
Basit bir ProcessWorker ile ECS worker'larını birlikte kullanıyoruz
Acaba son dönemde Celery daha az stabil ya da yönetmesi daha zor mu oldu?
İlginç bir proje. Ama bazı temel özelliklerin yalnızca Pro'da olması göze çarpıyor.
Postgres tabanlı dayanıklı workflow'u OSS olarak uygulayan önceki projeler arasında DBOS ve Absurd var.
Veritabanı merkezli yaklaşımın yaygınlaşması sevindirici
Tam açık kaynak ve yalnızca destek satışıyla yürüyen model rüya gibi bir model. Umarım bir gün mümkün olur
Postgres'in yüz milyonlarca işi kaldıracak kadar performanslı olup olmadığını merak ediyorum. Daha önce Redis + Sidekiq'e geçerken ciddi performans artışı görmüştüm
OSS sürümünde, uzun süren işler varsa producer canlı olsa bile yanlış kurtarma yapılabildiği söyleniyor.
Bu durumda sadece kısa işler için mi uygun?
Yalnızca düzgün kapanış beklenemediğinde kurtarma zamanlaması değişiyor