2011-11-28 16 views
8

के साथ वर्कर पूल और बहु-किरायेदार कतार मैं एक वेब एप्लिकेशन पर काम करता हूं जो एक बहु-किरायेदार क्लाउड आधारित एप्लिकेशन (कई ग्राहक, प्रत्येक अपने अलग "पर्यावरण" के साथ, लेकिन सभी हार्डवेयर के साझा सेट पर) और हम उपयोगकर्ता को बाद में प्रसंस्करण के लिए काम को बैच करने की क्षमता पेश कर रहे हैं। बैच किए गए काम के प्रकार वास्तव में महत्वपूर्ण नहीं हैं, यह केवल पर्याप्त मात्रा में है जो काम कतार के बिना ऐसा करना वास्तव में व्यावहारिक नहीं है। हमने RabbitMQ को हमारे अंतर्निहित कतार ढांचे के रूप में चुना है।खरगोश एमक्यू

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

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

उत्तर

1

आप केवल अपने कर्मचारियों का पूल ही एक ही अद्वितीय कतार का उपभोग कर सकते हैं। उसके बाद कार्य वितरित किया जाएगा और आप अपनी कार्य प्रसंस्करण क्षमता को बढ़ाने/घटाने के लिए अपने पूल को बढ़ाने/घटाने में सक्षम होंगे।

+1

मैं एक ही कतार में एकाधिक श्रमिकों को असाइन करने के बारे में नहीं पूछ रहा हूं, मैं रिवर्स के बारे में पूछ रहा हूं। मैं श्रमिकों के एक सीमित पूल को बड़ी मात्रा में उपभोग करना चाहता हूं (चलो इसे 500 ~ कॉल करें) कतारों की संख्या। – bakasan

+1

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

+0

मेरे पास एक समान आवश्यकता है, हालांकि मैं यह सुनिश्चित करना चाहता हूं कि किसी विशेष ग्राहक के संदेशों को अनुक्रमिक रूप से संसाधित किया जाए। संपर्क बनाने से पहले एक संपर्क हटाया नहीं गया है आदि। क्या वहाँ कुछ कॉन्फ़िगरेशन या रैबिटएमक्यू का सेटअप है जो इसे अभी तक श्रमिकों के बीच कतार साझा कर सकता है? (क्या यह एक नया क्यू है ...?) – Aaron

1

मुझे समझ में नहीं आता कि आप RabbitMQ के vhosts का उपयोग क्यों नहीं करते हैं और अपना ऐप RabbitMQ में लॉगिन करते हैं और प्रत्येक उपयोगकर्ता के लिए एक अलग कनेक्शन पर प्रमाणित करते हैं।

इसका मतलब यह नहीं है कि आपके पास एक कर्मचारी पर्यवेक्षक नहीं हो सकता है जो श्रमिकों को एक उपयोगकर्ता या किसी अन्य को असाइन करता है। लेकिन इसका मतलब यह है कि प्रत्येक उपयोगकर्ता के लिए सभी संदेशों को पूरी तरह से अलग एक्सचेंजों और कतारों द्वारा संसाधित किया जाता है।

0

श्रमिकों को 0+ कतार सौंपा गया है, एक्सचेंज नहीं।

तर्क यह है कि किस कार्य के लिए प्रत्येक कार्यकर्ता के लिए कतार CELERYD_CONSUMER के माध्यम से इंगित कक्षा में लागू की जाती है, जो डिफ़ॉल्ट रूप से celery.worker.consumer.Consumer है।

आप एक कस्टम उपभोक्ता कक्षा आरओ लागू कर सकते हैं जो भी आपको पसंद है। कठिन हिस्सा "निष्पक्षता" एल्गोरिदम का विवरण तय करेगा जिसका आप उपयोग करना चाहते हैं; लेकिन एक बार जब आप इसका फैसला कर लेंगे, तो आप इसे एक कस्टम उपभोक्ता वर्ग बनाने और उचित श्रमिकों को सौंपने के लिए लागू कर सकते हैं।

1

आप प्राथमिकता कतार कार्यान्वयन (जो जब यह सवाल पूछा गया था मूल रूप से लागू नहीं किया गया) पर दे सकता है: https://www.rabbitmq.com/priority.html

है कि आप के लिए काम नहीं करता है, आप क्या हासिल करना कुछ अन्य हैक्स की कोशिश कर सकते आप चाहते हैं (जो RabbitMQ के पुराने संस्करणों के साथ काम करना चाहिए):

आपके पास 100 कतार एक विषय विनिमय से बंधे हो सकते हैं और उपयोगकर्ता आईडी% 100 के हैश पर रूटिंग कुंजी सेट कर सकते हैं, यानी प्रत्येक कार्य में 1 के बीच कुंजी होगी और 100 और एक ही उपयोगकर्ता के लिए कार्य एक ही कुंजी होगी। प्रत्येक कतार 1 और 100 के बीच एक अद्वितीय पैटर्न के साथ बाध्य है।अब आपके पास एक यादृच्छिक कतार संख्या है जो प्रत्येक यादृच्छिक कतार संख्या से शुरू होती है और फिर प्रत्येक नौकरी के बाद कतार संख्या को फिर से बढ़ाती है, फिर से 100% कतार 100 के बाद कतार 1 तक चक्र।

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

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

में तेजी से और धीमे कार्यों की पहचान नहीं कर सकते हैं, तो 100 कतारों के साथ पहला सुझाव भी एक समस्या हो सकती है यदि एकल उपयोगकर्ता के लिए 100 धीमे कार्य होते हैं, तो कोई अन्य उपयोगकर्ता कार्य का बैच पोस्ट करता है। धीमे कार्यों में से एक समाप्त होने तक उन कार्यों को तब तक नहीं देखा जाएगा। यदि यह एक वैध समस्या साबित हो जाता है तो आप संभावित रूप से दो समाधानों को जोड़ सकते हैं।

संबंधित मुद्दे