प्रतिनिधि इंटरव्यू विषय

Kafka बैकएंड इंटरव्यू: Share Groups को कतार (Queue) सेमेंटिक्स कब प्रदान करने चाहिए?

बैकएंडकठिन
Offer.cc संपादकीय टीमप्रकाशित अपडेट किया गया

प्रश्न

एक ऑर्डर-प्रोसेसिंग सेवा चाहती है कि कई उपभोक्ता प्रति-रिकॉर्ड पावती और पुनः प्रयास के साथ एक ही Kafka टॉपिक से स्वतंत्र कार्यों (jobs) को प्रोसेस करें। Share Groups की तुलना Consumer Groups से करें, समझाएं कि प्रत्येक कब सुरक्षित है, और बताएं कि आप क्रमबद्धता, डुप्लिकेट्स और माइग्रेशन को कैसे संभालेंगे।

समस्या और दायरा

ऑर्डर सूचनाएं, इमेज ट्रांसफॉर्मेशन और बिलिंग गणनाएं अक्सर स्वतंत्र कार्य आइटम होते हैं। टीम पहले से ही Kafka में इवेंट्स लिखती है, लेकिन एक पारंपरिक Consumer Group एक समय में एक पार्टीशन केवल एक सदस्य को सौंपता है; पार्टीशन की संख्या से अधिक वर्कर्स जोड़ने से सीधे तौर पर पैरेलेलिज्म नहीं बढ़ता है। कई उपभोक्ताओं के लिए कार्य पर सहयोग करने का एक ऐसा तरीका डिज़ाइन करें जिसमें प्रति-रिकॉर्ड पावती, पुनः प्रयास और वितरण के प्रयासों की निगरानी संभव हो, साथ ही उन व्यावसायिक प्रक्रियाओं की पहचान करें जिन्हें अभी भी पार्टीशन क्रमबद्धता की आवश्यकता है।

यह प्रश्न Apache Kafka KIP-932 द्वारा वर्णित Share Group मॉडल का उपयोग करता है। KIP नियमित टॉपिक्स पर सहकारी उपभोग (cooperative consumption) के लिए एक नए ग्रुप प्रकार का वर्णन करता है; यह Kafka को पूरी तरह से RabbitMQ जैसा नहीं बनाता है। एक मजबूत उत्तर उत्पादन (production) में उपयोग की सिफारिश करने से पहले परिनियोजित (deployed) ब्रोकर संस्करण, क्लाइंट समर्थन और API उपलब्धता की पुष्टि करता है।

साक्षात्कारकर्ता क्या परख रहा है

  • क्या आप अनन्य पार्टीशन असाइनमेंट (exclusive partition assignment) और सहकारी रिकॉर्ड अधिग्रहण (cooperative record acquisition) के बीच अंतर कर सकते हैं?
  • क्या आप acknowledge, release, reject और लॉक समाप्ति (lock expiry) को प्रोसेसिंग अवस्थाओं से मैप कर सकते हैं?
  • क्या आप जानते हैं कि एक Share Group में सामान्य की-ऑर्डर (key-order) अंतर्ज्ञान को बनाए रखे बिना पार्टीशन से अधिक उपभोक्ता हो सकते हैं?
  • क्या आपके उत्तर में पुनः प्रयास, पॉइज़न रिकॉर्ड्स (poison records), प्रोसेसिंग की समय सीमा और कॉन्करेंसी सीमाएं एक ही विफलता मॉडल में फिट होती हैं?
  • क्या आप केवल KIP का नाम लेने के बजाय क्लाइंट, ब्रोकर, ACL, मॉनिटरिंग और रोलबैक विवरणों की पुष्टि करेंगे?

एक कमजोर उत्तर कहता है "Kafka एक कतार (queue) भी हो सकता है।" एक मजबूत उत्तर कतार जैसे लाभ, बदलने वाली गारंटियों और रोलआउट से पहले आवश्यक शर्तों (gates) का उल्लेख करता है।

पहले पूछे जाने वाले स्पष्टीकरण प्रश्न

  1. क्या कार्य वास्तव में स्वतंत्र हैं? यदि एक ऑर्डर के इवेंट्स को की (key) के क्रम में लागू किया जाना चाहिए, तो Share Groups गलत विकल्प हो सकते हैं।
  2. क्या विफलता अस्थायी है, मैन्युअल रूप से पुनर्प्राप्ति योग्य है, या स्थायी रूप से अमान्य है? यह release, reject और क्वारंटाइन (quarantine) व्यवहार को निर्धारित करता है।
  3. p99 प्रोसेसिंग समय, अधिकतम कॉन्करेंसी और सहन किए जाने वाले डुप्लिकेट साइड इफेक्ट्स क्या हैं? वे अधिग्रहण लॉक (acquisition lock) और आइडेम्पोटेंसी डिज़ाइन को आकार देते हैं।
  4. क्या व्यवसाय को शुरू से अंत तक Kafka ट्रांजैक्शन की आवश्यकता है? यह न मानें कि एक Share Group मौजूदा Consumer Group की ट्रांजैक्शन योजना को स्वचालित रूप से इनहेरिट कर लेता है।
  5. क्या टॉपिक अभी भी ब्रॉडकास्ट या रीप्ले उपभोक्ताओं को सेवा दे रहा है? एक ग्रुप को बदलने से दूसरे ग्रुप के रीड कॉन्ट्रैक्ट में बदलाव नहीं होना चाहिए।

30-सेकंड का उत्तर

"मैं पहले पुष्टि करूँगा कि क्या कार्य बिना किसी क्रम के पूरे हो सकते हैं और क्या परिनियोजित Kafka और क्लाइंट्स KIP-932 का समर्थन करते हैं। एक Share Group सदस्यों को किसी टॉपिक से रिकॉर्ड्स को सहयोगात्मक रूप से प्राप्त करने की अनुमति देता है, सदस्यों की संख्या को पार्टीशन की संख्या से अधिक होने देता है, और प्रति-रिकॉर्ड पावती (acknowledge), रिलीज़ (release) और अस्वीकृति (reject) का समर्थन करता है। पार्टीशन-स्थानीय क्रमबद्धता और ऑफसेट-आधारित रीजनिंग के लिए Consumer Group अभी भी बेहतर विकल्प है। मैं प्रत्येक साइड इफेक्ट को आइडेम्पोटेंट बनाऊँगा, प्रोसेसिंग लेटेंसी के आधार पर लॉक और पुनः प्रयास नीति सेट करूँगा, acquire, acknowledge, release, reject और टाइमआउट अवस्थाओं की निगरानी करूँगा, और पॉइज़न रिकॉर्ड्स को क्वारंटाइन करूँगा। यदि क्रमबद्धता, ट्रांजैक्शन सीमाएं या क्लाइंट समर्थन अनसुलझे हैं, तो मैं एक Consumer Group बनाए रखूँगा और माइग्रेट करने से पहले एक छोटे समूह के साथ एक अलग कार्य टॉपिक को मान्य करूँगा।"

चरण-दर-चरण तर्क

1. दो असाइनमेंट मॉडलों को समझें

एक Consumer Group सामान्यतः सदस्यों को पार्टीशन सौंपता है; उस ग्रुप के भीतर एक सदस्य किसी दिए गए पार्टीशन को पढ़ता है, इसलिए पैरेलेलिज्म पार्टीशन की संख्या तक सीमित होता है। एक Share Group सदस्यों को सब्सक्राइब किए गए टॉपिक्स से सहयोगात्मक रूप से रिकॉर्ड प्राप्त करने की अनुमति देता है। कई सदस्य एक पार्टीशन से अलग-अलग रिकॉर्ड प्रोसेस कर सकते हैं, और सदस्यों की संख्या पार्टीशन की संख्या से अधिक हो सकती है। यह स्वतंत्र कार्यों के लिए उपयोगी है, लेकिन यह ग्लोबल क्रमबद्धता का संकेत नहीं देता है।

text
Consumer Group:  partition-0 -> worker-A
                 partition-1 -> worker-B
                 extra workers wait for another partition

Share Group:     partition-0 records -> worker-A, worker-B, worker-C
                 each acquired record is locked for one consumer

Share Group को चुनने का कारण लचीला कार्य अधिग्रहण और प्रति-रिकॉर्ड पूर्णता होना चाहिए, न कि केवल यह कि "पार्टीशन बहुत कम हैं।" यदि किसी एक ग्राहक के इवेंट्स को क्रम में लागू किया जाना चाहिए, तो एक Consumer Group बनाए रखें या एप्लिकेशन स्तर पर एक सीरियलाइज्ड स्टेट मशीन जोड़ें।

2. रिकॉर्ड लाइफसाइकिल को मॉडल करें

KIP-932 एक समय-सीमित अधिग्रहण लॉक (time-limited acquisition lock) का वर्णन करता है। एक रिकॉर्ड प्राप्त करने के बाद, उपभोक्ता सफलता की पावती (acknowledge) दे सकता है, इसे दूसरे वितरण के लिए रिलीज़ (release) कर सकता है, इसे अप्रक्रियाशील मानकर अस्वीकार (reject) कर सकता है, या लॉक समाप्त होने तक कुछ नहीं कर सकता है। KIP 30-सेकंड के डिफ़ॉल्ट का वर्णन करता है, लेकिन उत्पादन व्यवहार को परिनियोजित ब्रोकर सेटिंग का उपयोग करना चाहिए; डिफ़ॉल्ट कोई SLA नहीं है।

text
available -> acquired -> acknowledged
                    -> released -> available
                    -> rejected  -> terminal or quarantine
                    -> lock timeout -> available

हैंडलर को किसी बाहरी साइड इफेक्ट से पहले एक आइडेम्पोटेंसी की (key) रजिस्टर करनी चाहिए। अन्यथा क्लाइंट क्रैश या लॉक समाप्ति से दो बार चार्ज, शिप या सूचित किया जा सकता है। एक पावती (acknowledgement) यह दर्शाती है कि यह अधिग्रहण पूरा हो गया है; यह किसी अन्य सिस्टम द्वारा पहले से कमिट किए गए साइड इफेक्ट को रोलबैक नहीं कर सकती है।

3. पुनः प्रयास, पॉइज़न रिकॉर्ड्स और कॉन्करेंसी को सीमित करें

वितरण-प्रयास गणना (delivery-attempt counts) अस्थायी विफलताओं को स्थायी रूप से अमान्य रिकॉर्ड्स से अलग करने में मदद करती है। नेटवर्क विफलता के लिए बैकऑफ़ करें और रिलीज़ करें। एक क्वारंटाइन टॉपिक या मैन्युअल कतार में डिटरमिनिस्टिक स्कीमा या सत्यापन त्रुटियों को reject करें। हमेशा के लिए रिलीज़ न करते रहें: एक पॉइज़न रिकॉर्ड अनिश्चित काल के लिए लॉक्स और डाउनस्ट्रीम क्षमता का उपभोग कर सकता है।

लॉक को सामान्य p99 प्रोसेसिंग समय से ऊपर एक स्पष्ट जिटर मार्जिन के साथ सेट करें। बहुत छोटा होने पर ओवरलैपिंग पुनः वितरण होता है; बहुत लंबा होने पर रिकवरी में देरी होती है। साथ ही प्रति पार्टीशन अधिग्रहित रिकॉर्ड्स को सीमित करें और वर्कर सेमाफोर, डेटाबेस पूल और बाहरी API कोटा का समन्वय करें। सक्रिय लॉक्स, लॉक टाइमआउट, प्रयास वितरण, अस्वीकृतियों और एंड-टू-एंड पूर्णता लेटेंसी की एक साथ निगरानी करें।

4. क्रमबद्धता और डुप्लिकेट गारंटियों को पुनः स्पष्ट करें

Kafka के स्पष्टीकरण अक्सर "पार्टीशन के अंदर क्रमित" को "व्यावसायिक प्रोसेसिंग क्रमित है" में बदल देते हैं। Share Group के सदस्य समवर्ती रूप से रिकॉर्ड प्राप्त कर सकते हैं, इसलिए एक की (key) के लिए पूर्णता का क्रम लेखन के क्रम से भिन्न हो सकता है; रिलीज़ और पुनः वितरण इस अंतर को और बढ़ा देते हैं। यदि क्रम महत्वपूर्ण है, तो एप्लिकेशन में की-स्तरीय सीरियलाइजेशन, संस्करण जांच (version checks), या एक स्टेट मशीन को एनकोड करें। केवल "Kafka क्रमित है" कहकर उत्तर न दें।

Exactly-once भी ग्रुप प्रकार से स्वचालित रूप से प्रकट नहीं होता है। रिकॉर्ड अधिग्रहण, व्यावसायिक राइट्स (writes) और पावती के बीच की सीमाओं को ट्रैक करें। एक बाहरी डेटाबेस या भुगतान सेवा को अभी भी आइडेम्पोटेंसी कीज़, एक डिडप्लीकेशन कंस्ट्रेंट, या एक ट्रांजैक्शनल आउटबॉक्स की आवश्यकता होती है। यदि कोई संयोजन असमर्थित है, तो इसे exactly-once कहने के बजाय यह बताएं कि डिज़ाइन आइडेम्पोटेंसी के साथ at-least-once है।

5. माइग्रेशन और रोलबैक की योजना बनाएं

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

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

उच्च गुणवत्ता वाला नमूना उत्तर

"मैं यह पूछकर शुरुआत करूँगा कि क्या कार्य बिना किसी क्रम के पूरे हो सकते हैं, क्या प्रोसेसिंग आइडेम्पोटेंट है, और क्या परिनियोजित ब्रोकर और क्लाइंट KIP-932 का समर्थन करते हैं। एक Share Group स्वतंत्र टॉपिक रिकॉर्ड्स को सहकारी कार्य के रूप में मानता है: कई सदस्य एक पार्टीशन से विभिन्न रिकॉर्ड प्राप्त कर सकते हैं, सदस्यों की संख्या पार्टीशन की संख्या से अधिक हो सकती है, और प्रत्येक रिकॉर्ड में acknowledge, release, reject और लॉक-समाप्ति पथ होते हैं। यह पारंपरिक ग्रुप के आवंटन और क्रमबद्धता के अंतर्ज्ञान को बदल देता है, इसलिए जब किसी व्यावसायिक की को क्रम की आवश्यकता होती है तो मैं एक Consumer Group बनाए रखूँगा या संस्करण जांच जोड़ूँगा।

मैं प्रत्येक रिकॉर्ड को एक आइडेम्पोटेंसी की असाइन करूँगा, p99 प्रोसेसिंग समय से अधिग्रहण लॉक सेट करूँगा, और सक्रिय लॉक्स तथा डाउनस्ट्रीम कॉन्करेंसी को सीमित करूँगा। अस्थायी विफलताएं बैकऑफ़ के साथ रिलीज़ होती हैं; डिटरमिनिस्टिक खराब डेटा को क्वारंटाइन में अस्वीकार कर दिया जाता है; एक प्रयास सीमा स्वचालित पुनः प्रयास को रोकती है। मैं acquire, acknowledge, release, reject, टाइमआउट, डुप्लिकेट साइड इफेक्ट्स और पूर्णता लेटेंसी की निगरानी करूँगा। माइग्रेशन से पहले मैं एक अलग टॉपिक पर संस्करणों, ACL, क्लाइंट व्यवहार और इंजेक्ट की गई विफलताओं को सत्यापित करूँगा। जब तक रिकॉर्ड अधिग्रहण, व्यावसायिक राइट्स और पावती एक सिद्ध ट्रांजैक्शन सीमा साझा नहीं करते हैं, मैं डिज़ाइन को exactly-once के बजाय आइडेम्पोटेंसी युक्त at-least-once कहूँगा।"

सामान्य गलतियां

  • Share Group को RabbitMQ का क्लोन कहना → स्टोरेज, रीप्ले और प्रशासन भिन्न हैं → केवल KIP-932 द्वारा प्रलेखित सहकारी अधिग्रहण और पावती सेमेंटिक्स का वादा करें।
  • वर्कर्स को पार्टीशन संख्या तक सीमित करना → Share Groups कई सदस्यों को एक पार्टीशन प्रोसेस करने की अनुमति देते हैं → लॉक्स, डाउनस्ट्रीम क्षमता और एंड-टू-एंड लेटेंसी द्वारा कॉन्करेंसी को सीमित करें।
  • यह मान लेना कि की-ऑर्डर बरकरार रहता है → समवर्ती अधिग्रहण और पुनः वितरण पूर्णता के क्रम को बदल देते हैं → क्रम की आवश्यकता होने पर कीज़ को सीरियलाइज़ करें या संस्करणों की जांच करें।
  • आइडेम्पोटेंसी के बिना पावती (acknowledge) देना → क्रैश या लॉक समाप्ति से रिकॉर्ड पुनः वितरित हो सकता है → पावती से पहले व्यावसायिक की द्वारा डिडुप्लिकेट करें।
  • पॉइज़न रिकॉर्ड्स को हमेशा के लिए रिलीज़ करना → पुनः प्रयास लॉक्स और डाउनस्ट्रीम बजट को समाप्त कर देते हैं → त्रुटि प्रकार, प्रयास गणना और क्वारंटाइन नीति द्वारा स्वचालित पुनः प्रयास रोकें।
  • 30 सेकंड को गारंटी के रूप में मानना → ब्रोकर कॉन्फ़िगरेशन और प्रोसेसिंग लेटेंसी भिन्न होती है → परिनियोजित लॉक सेटिंग का p99 के विरुद्ध परीक्षण करें।

फॉलो-अप प्रश्न और उत्तर

क्या होगा यदि एक ऑर्डर के इवेंट्स को सख्ती से क्रमित किया जाना चाहिए?

सीधे Share Group पर स्विच न करें। ऑर्डर ID द्वारा पार्टीशन किया गया Consumer Group बनाए रखें, या एप्लिकेशन-स्तरीय सीरियलाइज्ड स्टेट मशीन का उपयोग करें। यदि साझा अधिग्रहण अनिवार्य है, तो संस्करण जांच, पूर्वापेक्षा सत्यापन (prerequisite validation) और विफलता पुनर्रचना जोड़ें, और अतिरिक्त जटिलता को स्वीकार करें।

यदि अधिग्रहण के बाद कोई उपभोक्ता दो मिनट के लिए हैंग हो जाता है तो क्या होगा?

सामान्य p99 से थोड़ा ऊपर एक लॉक सेट करें और लॉक टाइमआउट पर अलर्ट करें। समाप्ति के बाद पुनः वितरण की अनुमति दें, लेकिन आइडेम्पोटेंट व्यावसायिक हैंडलिंग अनिवार्य करें। लंबे कार्य के लिए, लॉक को अनिश्चित काल तक बढ़ाने के बजाय इसे पुनः शुरू करने योग्य चरणों में विभाजित करें या किसी बाहरी लीज (lease) का उपयोग करें।

आप लगातार पांच स्कीमा विफलताओं को कैसे संभालते हैं?

उन्हें डिटरमिनिस्टिक त्रुटियों के रूप में मानें: एक सीमा के बाद अस्वीकार (reject) करें और पेलोड, स्कीमा संस्करण और कारण को क्वारंटाइन में लिखें। उपभोक्ता को ठीक करने के बाद, एक नियंत्रित प्रक्रिया के तहत रीप्ले करें। मुख्य वर्कफ़्लो को हमेशा के लिए पुनः प्रयास न करने दें।

वर्तमान सिस्टम Kafka ट्रांजैक्शन पर निर्भर करता है। क्या यह सीधे स्विच कर सकता है?

ट्रांजैक्शन की रीड, प्रोसेसिंग और राइट सीमाओं को सूचीबद्ध करें, फिर वास्तविक Share Group क्लाइंट और ट्रांजैक्शन समर्थन को सत्यापित करें। यदि कोई बाहरी साइड इफेक्ट उसी ट्रांजैक्शन के बाहर है, तो आउटबॉक्स, आइडेम्पोटेंसी की और क्षतिपूर्ति (compensation) का उपयोग करें। जब समर्थन अप्रमाणित हो तो Consumer Group बनाए रखें।

आप कैसे साबित करेंगे कि माइग्रेशन ने ग्राहकों से दो बार शुल्क नहीं लिया?

डिडुप्लीकेशन कंस्ट्रेंट के साथ एक अद्वितीय व्यावसायिक की के तहत प्रत्येक निष्पादन को रिकॉर्ड करें। क्रैश, लॉक समाप्ति, पुनः प्रयास और रोलबैक इंजेक्ट करें, फिर निष्पादन और पावती गणनाओं की तुलना करें। ट्रैफ़िक का विस्तार केवल तभी करें जब साइड-इफेक्ट गणना, लेटेंसी और त्रुटि-दर के इनवेरिएंट्स सही साबित हों।

सार्वजनिक स्रोत

संबंधित प्रश्न