- RabbitMQ को हटाकर PostgresDB में SQL-आधारित queue से बदल दिया
- इस बदलाव में करीब आधा दिन लगा, और source code 580 lines कम हो गया
- इससे भी ज़्यादा महत्वपूर्ण यह है कि stability और resiliency में बड़ा सुधार हुआ
- यह RabbitMQ जैसे queue system की समस्या पर लेख नहीं है, बल्कि चीज़ों को सरल बनाए रखने की कोशिश का हिस्सा है
- यह लेख लिखने वाली Prequel एक ऐसा product है जो बड़े पैमाने के data pipeline के ज़रिए B2B SaaS कंपनियों को अपने ग्राहकों के DB के साथ sync करने में मदद करता है
- इसे RabbitMQ + AQMP + Helm + GoLang wrapper के साथ बनाया गया था; कुछ समय तक सब ठीक चला, लेकिन फिर समस्याएँ दिखने लगीं
- message delivery में बहुत ज़्यादा delay होने लगा, जिससे messages cancel होने लगे
- consumer जब messages prefetch करता था, तो current message पूरा होने तक अगला message पकड़े रखता था
- इस prefetch को 0 करने पर यह infinite हो जाता है, इसलिए prefetch को disable करना संभव नहीं था
- message लेकर process करने वाले काम आमतौर पर long-running tasks (data transfer) होते थे, इसलिए यह समस्या आती थी
- उन्हें ठीक-ठीक समझ आ गया कि क्या हो रहा है, लेकिन तुरंत fix करने का तरीका नहीं था. production customers पर असर पड़ रहा था, इसलिए इंतज़ार करना संभव नहीं था
- इसलिए Postgres में सिर्फ एक simple table का इस्तेमाल करके read/write करने वाला तरीका अपनाया गया
- read/write के लिए Row-Level Lock का इस्तेमाल करके यह सुनिश्चित किया गया कि एक समय में सिर्फ एक consumer ही काम पढ़ सके
- यह हैरान कर देने जितना simple है, लेकिन पूरी तरह काम कर रहा है
- इसका फायदा यह भी है कि application state अब RabbitMQ और Postgres में बँटी नहीं रहती, बल्कि एक ही जगह integrated रहती है
6 टिप्पणियां
मैंने भी mysql में row level lock के साथ queue को सीधे implement किया है, और यह कई वर्षों से प्रोडक्शन में अच्छी तरह काम कर रहा है.
मैं बस इतना चाहता था कि कई workers को queue जैसी functionality मिले, और साथ ही queue के भीतर waiting/in-progress/failed (completed होने पर delete) status सहित payload भी स्टोर किया जा सके.
लेख में जिस तरह थोड़े समय में RabbitMQ से DB पर स्विच किया गया, उसे देखकर लगता है कि शायद अलग से किसी specialized queue service की generality या उसकी विविध features और configuration options की वास्तव में ज़रूरत नहीं थी.
लगता है मैनुअल ACK भेजने और DB transaction के बीच देरी होने से समस्या हुई,
और इसे engineering से हल करने के बजाय RabbitMQ को ही हटाने का फैसला करना दिलचस्प है।
RabbitMQ की तो शायद कोई गलती नहीं थी...
https://news.ycombinator.com/item?id=35526846
टिप्पणियों में काफ़ी सारी राय हैं।
इसी तरह काम करने वाला https://github.com/pjongy/jasyncq जैसा कुछ और भी है।
ऐसा लगता है कि एक ही समय में
selectहोने की संभावना हो सकती है, तो यह जानना चाहूंगा कि उसे कैसे हल किया गया।यहाँ
row level lockलिखा हुआ है।