- Oban.py Elixir के job processing framework Oban का PostgreSQL-आधारित Python पोर्ट है, जिसमें केवल database के ज़रिए jobs insert और process किए जा सकते हैं
- jobs database transaction के भीतर बनते और rollback होते हैं, और queue management, result storage, cron scheduling जैसी कई सुविधाओं को support करते हैं
- open source version में single-threaded asyncio execution और individual insert/ack handling जैसी सीमाएँ हैं, जबकि Pro version parallel processing, workflows, smart concurrency प्रदान करता है
- इसकी आंतरिक कार्यप्रणाली
Insert → Notify → Fetch → Execute → Ackके पाँच चरणों में बनी है, और PostgreSQL के FOR UPDATE SKIP LOCKED का उपयोग करके concurrency conflicts से बचा जाता है - leader election, orphaned job recovery, backoff retries जैसी प्रक्रियाएँ भी database-आधारित हैं, जिससे external broker के बिना स्थिर distributed processing संभव होती है
Oban.py का अवलोकन
- Oban.py Elixir के Oban का Python में पोर्ट किया गया database-आधारित job processing framework है
- jobs को database transaction के भीतर insert और process किया जाता है, और failure होने पर पूरा transaction rollback हो जाता है
- इसमें queue limits, completed job storage, result retention, cron scheduling जैसी कई control capabilities शामिल हैं
- दो versions उपलब्ध हैं
- open source (OSS): single-threaded asyncio execution, individual insert/ack, simple recovery
- Pro version: process pool-आधारित parallel processing, workflows, relays, unique jobs, smart concurrency support
- OSS personal projects या evaluation के लिए उपयुक्त है, जबकि बड़े scale के environments के लिए Pro version की सिफारिश की जाती है
job processing path
- job insert होने के बाद उसे
oban_jobstable मेंstate='available'के साथ store किया जाता है, और PostgreSQL के NOTIFY के ज़रिए हर node को सूचना भेजी जाती है - हर node का Stager संबंधित queue को detect करके Producer को जगाता है, और Producer jobs को fetch करके execute करता है
- job select करते समय SQL के
FOR UPDATE SKIP LOCKEDका उपयोग किया जाता है, जिससे duplicate execution के बिना parallel processing संभव होती है- पहले से locked rows को छोड़ दिया जाता है ताकि दूसरा producer तुरंत दूसरे jobs उठा सके
- jobs को async task के रूप में dispatch किया जाता है, और पूरा होने पर callback से acknowledgement संभाला जाता है
- Pro version asyncio की जगह process pool dispatcher का उपयोग करके multi-core parallel execution support करता है
background processes
- leader election
- PostgreSQL के
INSERT ... ON CONFLICTऔर TTL-आधारित lease के ज़रिए leader तय किया जाता है - बिना किसी अलग consensus protocol के एक single leader job cleanup और recovery संभालता है
- PostgreSQL के
- Lifeline (orphaned job recovery)
- अगर चल रहा job एक निश्चित समय (
rescue_after, default 5 minutes) से ज़्यादा टिके, तो उसे available state में restore किया जाता है - Pro version producer की liveness भी check करता है, जबकि OSS केवल समय-आधारित निर्णय लेता है
- अगर चल रहा job एक निश्चित समय (
- Pruner (job cleanup)
- completed, cancelled, और discarded jobs में से
max_age(default 1 day) से पुराने entries delete किए जाते हैं - database load से बचने के लिए
LIMITके साथ deletion range सीमित की जाती है
- completed, cancelled, और discarded jobs में से
retries और backoff
- अगर कोई job exception raise करता है, तो Executor तय करता है कि retry करना है या नहीं
- अगर job अधिकतम attempts (
max_attempts) से कम है तो retry, वरना discard
- अगर job अधिकतम attempts (
- default backoff jitter के साथ exponential increase पर आधारित है
- बड़े पैमाने पर failures के समय एक साथ retry होने से बचाकर load spike (Thundering Herd) को कम करता है
- उदाहरण: पहली बार लगभग 17 seconds, पाँचवीं बार लगभग 47 seconds, दसवीं बार लगभग 17 minutes का इंतज़ार
- worker class
backoff()method के ज़रिए custom backoff logic लागू कर सकती है
मुख्य विशेषताएँ और मूल्यांकन
- PostgreSQL की केंद्रीय भूमिका
FOR UPDATE SKIP LOCKED,LISTEN/NOTIFY,ON CONFLICTके ज़रिए concurrency control, signal delivery, leader election सब कुछ संभाला जाता है- Redis या external broker के बिना single database से coordination layer बनाई जाती है
- parallel न होकर भी concurrency support
- asyncio-आधारित होने के कारण I/O-bound कामों के लिए उपयुक्त, जबकि CPU-bound कामों के लिए Pro version बेहतर है
- code structure की स्पष्टता
- consistent naming और अलग-अलग responsibility structure के कारण codebase पढ़ना आसान है
- OSS और Pro की भूमिकाएँ स्पष्ट रूप से विभाजित
- OSS प्रयोग और छोटे scale के लिए, Pro बड़े scale और high-performance environments के लिए
- निष्कर्ष: केवल PostgreSQL से एक पूर्ण job queue लागू करने वाला यह साफ-सुथरा और संरचित Python पोर्ट है, जो Elixir users या external infrastructure के बिना job system चाहने वाले developers के लिए उपयुक्त है
1 टिप्पणियां
Hacker News की राय
मैं Sidekiq बनाने वाला व्यक्ति हूँ, और Shannon और Parker को इस रिलीज़ के लिए बधाई देता हूँ
मैंने भी पहले यही दुविधा झेली थी — Ruby पर फोकस करूँ, या Sidekiq को दूसरी भाषाओं तक बढ़ाऊँ। मुझे समझ आया कि मैं हर भाषा का विशेषज्ञ नहीं बन सकता, इसलिए मैंने Faktory बनाया। इसमें एक central server queue के lifecycle को मैनेज करता है, और हर भाषा के client सरल बने रहते हैं। उदाहरण के लिए faktory-rs जैसा client है। नुकसान यह है कि किसी एक language community पर फोकस नहीं होता, इसलिए उस भाषा के हिसाब से उदाहरण देना कठिन हो जाता है।
किसी एक community पर केंद्रित तरीका शायद बेहतर नतीजे दे सकता है। समय बताएगा
Oban की असली ताकत यह है कि केवल database के सहारे jobs insert और process किए जा सकते हैं। user creation transaction के अंदर email भेजने का job भी डाल सकते हैं, और अगर transaction fail हो जाए तो सब कुछ rollback हो जाता है।
बहुत लोग कहते हैं कि relational DB को job queue की तरह इस्तेमाल नहीं करना चाहिए, लेकिन वे transaction की अहमियत को नज़रअंदाज़ करते हैं। Brandur Leach का लेख Job Drain भी इस विचार को बहुत अच्छी तरह समझाता है
लेकिन अब किसी को वह दर्द याद भी नहीं है। “transactional outbox pattern” अनिवार्य है, और मैं ऐसा तरीका पसंद करता हूँ जिसे मेरे data जैसी ही ACID guarantees मिलें।
DB के अंदरूनी हिस्से जाने बिना भी, अगर आप isolation levels और commit ordering सीखने में एक हफ़्ता लगा दें, तो distributed systems debug करने का एक साल बचा सकते हैं
लंबे AI processes वाले इस दौर में ऐसी durability अनिवार्य है। दूसरी language ecosystems में ऐसी सुविधा के लिए पैसे देने पड़ते हैं, लेकिन Oban में यह built-in है
Oban टीम Elixir ecosystem में बेहद परिष्कृत engineering के लिए जानी जाती है। लेकिन pro version में process pool को बंद रखना उलझन पैदा करता है।
उदाहरण के लिए $135/माह वाले प्लान में multi-process execution, workflows, global limits, unique jobs, bulk actions, encrypted sources, dedicated support आदि शामिल हैं।
मेरा प्रोजेक्ट Chancy पूरी तरह मुफ़्त है, और इसमें asyncio, process, thread, sub-interpreter को अपनी ज़रूरत के मुताबिक़ मिलाकर इस्तेमाल किया जा सकता है।
मुझे लगता है कि ऐसी सुविधाओं को OSS में लाना और paid offering को enterprise support पर केंद्रित करना बेहतर होगा। Python ecosystem में प्रतियोगिता कहीं ज़्यादा है
सिर्फ support बेचने वाला मॉडल हमारे लिए ख़ास काम नहीं किया, लेकिन Python में स्थिति अलग हो सकती है।
Python ecosystem में सचमुच हर चीज़ बहुत है
अगर Chancy में Django Tasks support जोड़ दिया जाए या
django-chancypackage बनाया जाए, तो इसका अपनाया जाना तेज़ हो सकता हैOSS Oban केवल single-threaded asyncio execution को support करता है, इसलिए CPU-bound jobs event loop को block कर देते हैं।
इसलिए मुझे लगा कि इसे आज़माने का कोई ख़ास मतलब नहीं है। Celery का interface अच्छा नहीं है, लेकिन वह परिचित है, और vertical तथा horizontal scaling लगभग असीमित है।
हालाँकि अब जब पता चला कि कई worker nodes चलाए जा सकते हैं, तो मेरी राय थोड़ी बदली है
OSS/Pro feature विभाजन ठीक है, लेकिन “Pro version ज़्यादा smart heartbeat से producer liveness को track करता है” वाली बात निराश करती है।
reliability से जुड़ी सुविधाएँ paid होने से OSS projects में इसे अपनाना कठिन हो जाता है
base version सबसे अच्छा होना चाहिए, और extra features paid होने चाहिए। सीमा कुछ अजीब जगह पर खींची हुई लगती है
उद्धृत वाक्य थोड़ा सटीक नहीं है — producer liveness tracking तो समान है, फ़र्क सिर्फ orphaned job recovery के तरीके में है
काश Python में BI/ML/DS workflows Elixir की तरफ़ आ जाएँ।
मुझे लगता है कि functional, fault-tolerant, concurrent गुणों वाला Elixir इस तरह के काम के लिए कहीं अधिक स्वाभाविक आधार है
यह वीडियो और Elixir Genius guide अच्छे संदर्भ हैं
हमारी कंपनी भी Celery इस्तेमाल करती है, और वह बहुत अच्छा नहीं है। Temporal बहुत भारी लगता है, जबकि Oban हल्का और पसंद आने वाला लगता है।
दोनों इस्तेमाल कर चुके लोगों की तुलना जानने की जिज्ञासा है
Temporal उन संगठनों के लिए उपयुक्त है जो workflow guarantees और उससे जुड़ी complexity वहन कर सकते हैं, जैसे बैंक।
Oban एक DB-आधारित queue है, जिसमें reliability को आपको खुद मज़बूत करना पड़ता है।
मुझे लगता है कि दोनों का एक ही system में साथ होना अच्छा है
हम एक साधारण ProcessWorker और ECS workers के संयोजन का उपयोग कर रहे हैं
सोच रहा हूँ कि क्या हाल के वर्षों में Celery कम stable या संभालने में ज़्यादा मुश्किल हो गया है
दिलचस्प प्रोजेक्ट है। लेकिन यह साफ़ दिखता है कि कुछ core features केवल Pro में हैं।
Postgres-आधारित durable workflows को OSS में लागू करने वाले पहले के प्रोजेक्ट्स में DBOS और Absurd शामिल हैं।
database-centric approach का बढ़ना अच्छी बात है
पूरी तरह open source मॉडल और केवल support बेचकर चलने वाला मॉडल एक सपने जैसा मॉडल है। उम्मीद है कि कभी यह संभव होगा
क्या Postgres की performance पर्याप्त है कि वह सैकड़ों मिलियन jobs संभाल सके? पहले मैंने Redis + Sidekiq पर जाते हुए performance में बड़ा सुधार देखा था
कहा गया है कि OSS version में लंबे jobs होने पर producer जीवित होने के बावजूद गलत recovery हो सकती है।
तो क्या इसका मतलब है कि केवल छोटे jobs ही इस्तेमाल करने चाहिए?
recovery timing केवल उन मामलों में अलग होती है जहाँ normal shutdown का इंतज़ार नहीं किया जा सका