Redis पर एक संदेश कतार कैसे लागू करें?


29

कतार के लिए रेडिस क्यों?

मैं इस धारणा के तहत हूं कि रेडिस एक कतारबद्ध प्रणाली को लागू करने के लिए एक अच्छा उम्मीदवार बना सकता है। इस बिंदु तक हम मतदान के साथ हमारे MySQL डेटाबेस का उपयोग कर रहे हैं, या RabbitMQ। RabbitMQ के साथ हमें कई समस्याएं हैं - क्लाइंट लाइब्रेरी बहुत खराब और छोटी हैं और हम उन्हें ठीक करने में बहुत सारे डेवलपर-घंटों का निवेश नहीं करना चाहते हैं, सर्वर प्रबंधन कंसोल, आदि के साथ कुछ समस्याएं और समय के लिए। कम से कम, हम मिलीसेकंड के लिए या गंभीर रूप से प्रदर्शन को गंभीरता से नहीं पकड़ रहे हैं, इसलिए जब तक एक प्रणाली में एक वास्तुकला है जो एक कतार का समर्थन करता है बुद्धिमानी से हम शायद अच्छे आकार में हैं।

ठीक है, इसलिए वह पृष्ठभूमि है। अनिवार्य रूप से मेरे पास एक बहुत ही क्लासिक, सरल कतार मॉडल है - काम का उत्पादन करने वाले कई उत्पादकों और काम का उपभोग करने वाले कई उपभोक्ता, और उत्पादकों और उपभोक्ताओं दोनों को समझदारी से स्केल करने में सक्षम होने की आवश्यकता है। यह पता चलता है कि एक भोला PUBSUBव्यक्ति काम नहीं करता है, क्योंकि मैं नहीं चाहता कि सभी ग्राहक काम का उपभोग करें, मैं सिर्फ एक ग्राहक को काम प्राप्त करना चाहता हूं । पहली बार में, यह मुझे लगता है जैसे BRPOPLPUSHएक बुद्धिमान डिजाइन है।

क्या हम BRPOPLPUSH का उपयोग कर सकते हैं?

आपके साथ मूल डिज़ाइन BRPOPLPUSHएक कार्य कतार और एक प्रगति कतार है। जब कोई उपभोक्ता काम करता है तो वह वस्तु को प्रगति की कतार में धकेल देता है, और जब वह काम पूरा कर लेता है तो वह उसे पूरा कर LREMलेता है। यह काम के ब्लैकहोलिंग को रोकता है अगर ग्राहक मर जाते हैं और निगरानी को बहुत आसान बना देते हैं - उदाहरण के लिए हम बता सकते हैं कि क्या कोई समस्या है जिसके कारण उपभोक्ताओं को कार्य करने में लंबा समय लगता है, इसके अलावा यह बताने के लिए कि कार्यों की एक बड़ी मात्रा है।

यह सुनिश्चित करता है

  • काम ठीक एक उपभोक्ता को दिया जाता है
  • कार्य प्रगति की कतार में चल रहा है, इसलिए यदि कोई उपभोक्ता ब्लैकहोल नहीं कर सकता है

कमियां

  • यह मेरे लिए अजीब लगता है कि मैंने जो सबसे अच्छा डिज़ाइन पाया है वह वास्तव में उपयोग नहीं करता है PUBSUBक्योंकि ऐसा लगता है कि रेडिस पर ध्यान केंद्रित करने के बारे में सबसे अधिक ब्लॉग पोस्ट क्या हैं। इसलिए मुझे लगता है कि मुझे कुछ स्पष्ट याद आ रहा है। एक ही तरीका PUBSUBजिसे मैं दो बार उपभोग किए बिना कार्यों का उपयोग करने के लिए देखता हूं, वह केवल एक अधिसूचना को धक्का देता है जो काम आ गया है, जो उपभोक्ता तब गैर-ब्लॉकिंग-लाइक कर सकते हैं RPOPLPUSH
  • एक समय में एक से अधिक कार्य आइटम का अनुरोध करना असंभव है, जो एक प्रदर्शन समस्या प्रतीत होती है। हमारी स्थिति के लिए बहुत बड़ा नहीं है, लेकिन यह स्पष्ट रूप से कहता है कि यह ऑपरेशन उच्च थ्रूपुट या इस स्थिति के लिए डिज़ाइन नहीं किया गया था
  • संक्षेप में: क्या मैं बेवकूफ कुछ भी याद कर रहा हूं?

इसके अलावा नोड.जेएस टैग जोड़ना, क्योंकि मैं जिस भाषा के साथ काम कर रहा हूं। नोड एकल-थ्रेडेड और नॉनब्लॉकिंग प्रकृति को देखते हुए लागू करने में कुछ सरलीकरण कर सकता है, लेकिन इसके अलावा मैं नोड-रेडिस लाइब्रेरी का उपयोग कर रहा हूं और समाधान अपनी शक्तियों और कमजोरियों के लिए भी संवेदनशील होना चाहिए।

जवाबों:


5

यदि आप Node.js में एक संदेश कतार के लिए Redis का उपयोग करना चाहते हैं और इसके लिए किसी मॉड्यूल का उपयोग करने में आपको कोई आपत्ति नहीं है, तो आप RSMQ - Redis सरल संदेश पंक्ति नोड के लिए आज़मा सकते हैं । यह उस समय उपलब्ध नहीं था जब यह प्रश्न पूछा गया था लेकिन आज यह एक व्यवहार्य विकल्प है।

यदि आप वास्तव में कतार को स्वयं लागू करना चाहते हैं जैसा कि आपने अपने प्रश्न में कहा है तो आप RSMQ के स्रोत को पढ़ना चाह सकते हैं क्योंकि यह कोड की सिर्फ 20 स्क्रीन है जो वास्तव में वही करती है जो आप पूछ रहे हैं।

देख:


जब तक मैं बाद में यह नहीं जानता कि यह वास्तव में दोषपूर्ण है या टूटा हुआ है या कुछ और है, मैं इसे स्वीकार करता हूँ।
djechlin

22

मैंने कुछ कठिनाइयों में भाग लिया है, इस प्रकार मैं यहाँ दस्तावेज़ करना चाहूँगा।

आप फिर से तर्क को कैसे संभालते हैं?

यह एक कठिन समस्या है और एक संदेश कतार को डिजाइन और कार्यान्वित करने में विशेष रूप से कठिन समस्या है। जब उपभोक्ता ऑफ़लाइन होते हैं, तो संदेश कहीं न कहीं कतारबद्ध होना चाहिए, इसलिए एक साधारण पब-उप पर्याप्त रूप से मजबूत नहीं होता है, और उपभोक्ताओं को सुनने की स्थिति में पुन: कनेक्ट करने की आवश्यकता होती है। चबूतरे को अवरुद्ध करना मुश्किल राज्य है, क्योंकि वे एक गैर-सुनसान राज्य हैं । श्रवण एक निष्क्रिय ऑपरेशन होना चाहिए, फिर भी जब एक अवरुद्ध पॉप के संबंध में एक डिस्कनेक्ट के साथ काम करते हैं, तो आपको यह सोचने में बहुत खुशी होती है कि क्या ऑपरेशन सफल होने से ठीक पहले या ऑपरेशन विफल होने से पहले हुआ था। यह अचूक नहीं है, लेकिन यह अवांछनीय है।

इसके अलावा, श्रवण ऑपरेशन यथासंभव सरल होना चाहिए आदर्श रूप से इसमें ये गुण होने चाहिए:

  • सुनना आलस्यपूर्ण है।
  • उपभोक्ता हमेशा सुन रहा है, और थ्रॉटलिंग तर्क सुनने के तर्क कोड के बाहर संसाधित किया जाता है। RabbitMQ उपभोक्ता को उसके पास मौजूद अप्रभावित संदेशों की संख्या से बाध्य करके इसका एनकाउंटर करता है।
    विशेष रूप से मैं एक खराब डिजाइन के साथ गया था जिसमें एक अवरुद्ध पॉप में फिर से प्रवेश करना पिछले ऑपरेशन की सफलता पर आकस्मिक था, जो भंगुर था और कठिन सोच की आवश्यकता थी।

मैं अब Redis PUBSUB + RPOPLPUSH समाधान का पक्ष ले रहा हूं। यह काम की खपत से काम की अधिसूचना को डिकॉउंड करता है, जो हमें एक साफ सुनने के समाधान का कारक देता है। PUBSUB केवल काम की अधिसूचना के लिए जिम्मेदार है। RPOPLPUSH की परमाणु प्रकृति खपत के लिए जिम्मेदार है, और बिल्कुल एक उपभोक्ता को काम सौंपती है। पहले तो यह समाधान अवरुद्ध पॉप की तुलना में अनावश्यक रूप से जटिल लगता था, लेकिन अब मैं देखता हूं कि जटिलता बिल्कुल भी अनावश्यक नहीं थी; यह एक कठिन समस्या को हल कर रहा था।

हालांकि यह समाधान काफी तुच्छ नहीं है:

  • उपभोक्ताओं को फिर से कनेक्ट करने के लिए भी काम करना चाहिए।
  • उपभोक्ता किसी भी तरह नए काम के लिए एक सर्वेक्षण करना चाह सकते हैं, अतिरेक के लिए। क्या वास्तव में मतदान सफल होना चाहिए, एक चेतावनी को उत्सर्जित किया जाना चाहिए, क्योंकि यह केवल PUBSUB पर खपत और RPOPLPUSH पर मतदान के बीच होना चाहिए। इसलिए कई चुनाव सफलताएँ एक टूटी हुई सदस्यता प्रणाली का संकेत देती हैं।

ध्यान दें कि PUBSUB / RPOPLPUSH डिजाइन में भी स्केलिंग की समस्या है। प्रत्येक उपभोक्ता को प्रत्येक संदेश की एक हल्की सूचना प्राप्त होती है , जिसका अर्थ है कि इसमें अनावश्यक अड़चन है। मुझे संदेह है कि चैनल का उपयोग काम को तेज करने के लिए संभव है लेकिन यह अच्छी तरह से काम करने के लिए एक मुश्किल डिजाइन है।


सुनिश्चित नहीं है कि मैं उपभोक्ताओं को अवरुद्ध करने के साथ समस्या का पालन करता हूं। यह मुझे लगता है कि अगर उपभोक्ताओं को संसाधित करने के लिए कोई काम नहीं है, तो कुछ होने तक ब्लॉक करना चाहिए, हालांकि मुझे लगता है कि अगर उपभोक्ता अन्य चीजें भी कर रहा है जो एक अलग कहानी हो सकती है, लेकिन क्या यह अनुप्रयोग के भीतर एक समस्या नहीं है और कतार के लिए इतना नहीं? IE एक बड़े ऐप के भीतर एक थ्रेड ब्लॉक कर रहा है जो एक अधिक सुरुचिपूर्ण समाधान है, जहां थ्रेड तब ऐप को अधिसूचित करने में सक्षम होगा जब उसने कतार से नौकरी प्राप्त की थी। शायद यह केवल नोड का उपयोग है जो जटिलता पैदा कर रहा है।
एरोनम

9
मैं उत्सुक हूं कि आप पिछले अगस्त से कितनी दूर आए हैं। क्या आप अपनी संतुष्टि के लिए अपनी समस्याओं को हल करने में सक्षम थे? आपने उन्हें कैसे हल किया?
एरोनम

3
एएए: ठीक @AaronM की तरह मैं यह सुनना पसंद करूंगा कि आपने कैसे प्रगति की है।
bjornl

माना। यह कैसे आगे बढ़ा है? मुझे स्टैक से रैबिटएमक्यू हटाने का विचार पसंद है और रेडिस का उपयोग करें जो वैसे भी है। मेरा मुद्दा यह है कि RSMQ (नोड लिब) का उपयोग करके उपभोक्ता को कैसे पंजीकृत किया जाए।
ra9r

@raiglstorfer ने दो साल तक वहां काम नहीं किया है: P अनुसंधान और पद के लिए स्वतंत्र महसूस ...
djechlin

0

तो Redis पर RabbitMQ का उपयोग करने का सबसे बड़ा कारण विफलता परिदृश्य और क्लस्टरिंग है।

यह लेख वास्तव में इसे सबसे अच्छा समझाता है, इसलिए मैं सिर्फ लिंक प्रदान करूंगा:

https://aphyr.com/posts/283-jepsen-redis

Redis sentinel और अधिक हाल ही में redis क्लस्टरिंग बहुत मूल विफलता परिदृश्यों की एक संख्या को संभालने में सक्षम नहीं हैं जो इसे एक कतार के लिए एक बुरा विकल्प बना दिया।

RabbitMQ के मुद्दों का अपना सेट है, हालांकि कहा जा रहा है कि यह उत्पादन में अविश्वसनीय रूप से ठोस है और एक अच्छा संदेश कतार है।

यहाँ खरगोश के लिए पोस्ट है:

https://aphyr.com/posts/315-jepsen-rabbitmq

जब आप कैप प्रमेय (स्थिरता, उपलब्धता और विभाजन से निपटने) को देखते हैं, तो आप केवल 3 में से 3 चुन सकते हैं। हम अपने संदेश लोड के साथ सीपी (संगतता और विभाजन से निपटने) के लिए RMQ का लाभ उठा रहे हैं, यदि हम अनुपलब्ध हैं, तो यह ' t दुनिया का अंत। संदेशों को न खोने के लिए, हम संदेशों को न खोने के लिए विभाजन से निपटने के लिए उपेक्षा का उपयोग करते हैं। स्रोत UUID का प्रबंधन करने के बाद से डुप्लिकेट को संभाला जा सकता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.