यह कैसे काम करता है
यह पृष्ठ क्लाइंट और सर्वर (क्लस्टर) के बीच होने वाले वास्तविक संदेश प्रवाह के ज़रिए बताता है कि Ticketing कैसे काम करता है। वायर पर आने-जाने वाली चीज़ों का सटीक बाइट-स्तरीय विवरण प्रोटोकॉल (API) और प्रोटोकॉल (क्लस्टर) में मिलता है।
समग्र संरचना
उपयोगकर्ता अनुरोध प्राप्त करने वाली सेवाएँ (जैसे, टिकट-बिक्री खुलने को संभालने वाले इवेंट सर्वर) Ticketing क्लस्टर के सामने उसी कुंजी के लिए कतार में लगती हैं, और केवल जिस सर्वर की बारी आती है वही इन्वेंट्री घटाने या सीट असाइन करने जैसा काम आगे बढ़ाता है।
लॉक का अधिग्रहण और रिलीज़
बुनियादी प्रवाह। एक अधारित (unheld) कुंजी तुरंत दे दी जाती है; एक धारित कुंजी FIFO कतार में अपनी बारी की प्रतीक्षा करती है। जब धारक रिलीज़ करता है, तो लॉक बिना किसी पुनर्स्पर्धा के सीधे कतार के सबसे आगे वाले को सौंप दिया जाता है — अगला प्रतीक्षक तुरंत एक नए टोकन के साथ आगे बढ़ जाता है, इसलिए न तो कभी कोई ऐसा क्षण आता है जब लॉक खाली बैठा हो, और न ही कोई बीच में घुस सकता है।
leaseएक सुरक्षा जाल है। यदि कोई क्लाइंट मर जाता है या रिलीज़ करना भूल जाता है, तोleaseअवधि बीतने के बाद सर्वर कुंजी वापस ले लेता है और उसे अगले प्रतीक्षक को सौंप देता है। इसे उदारता से सेट करें — आपके क्रिटिकल सेक्शन के अधिकतम संभावित समय से अधिक। v1 केवल 1–250 सेकंड स्वीकार करता है; इससे लंबा काम स्पष्ट रूप से असमर्थित है और अस्वीकार किया जाता है।waitइस बात की ऊपरी सीमा है कि क्लाइंट कितनी देर प्रतीक्षा करेगा। यदि उस समय के भीतर उसकी बारी नहीं आती, तो सर्वर लॉक दिए बिनाT(टाइमआउट) से प्रतिक्रिया देता है, इसलिए कोई भी लॉक कभी नहीं टपकता (leak)।0का अर्थ कतार में जाए बिना एक तत्काल प्रयास है। अनंत प्रतीक्षा नहीं है।- यदि वही क्लाइंट पहले से धारित कुंजी को फिर से अधिग्रहित करने की कोशिश करता है, तो वह किसी भी अन्य प्रतीक्षक की तरह कतार में लगता है — यह पुनःप्रवेशी (reentrant) लॉक नहीं है।
प्रति कुंजी-स्थिति सर्वर व्यवहार के पूरे नियमों के लिए अनुरोध × कुंजी-स्थिति मैट्रिक्स देखें, और फ़ील्ड मान सीमाओं के लिए फ़ील्ड बाधाएँ देखें।
फेंसिंग टोकन
एक परिपूर्ण लॉक सर्वर भी क्लाइंट की घड़ी को नियंत्रित नहीं कर सकता। Ticketing अकेले पुराने धारक (stale holder) के मामले को नहीं रोक सकता: एक क्लाइंट जो लॉक पकड़े हुए GC रुकावट या ओवरलोड के कारण कुछ समय के लिए ठहर गया, फिर जागता है — यह जाने बिना कि उसका lease पहले ही समाप्त हो चुका है — और अपना काम जारी रखता है। यही कारण है कि हर अधिग्रहण प्रतिक्रिया में token एक u64 पूर्णांक है जो हर बार दिए जाने पर बढ़ने की गारंटी रखता है। वित्तीय या persistent DB में प्रति-key fencing high-water की तुलना व अद्यतन वास्तविक business write के साथ उसी DB transaction या एक conditional write में परमाणु रूप से होना चाहिए। पहले केवल fencing row अपडेट करके वास्तविक write बाद में करना सुरक्षित नहीं है।
क्रमिकता (monotonicity) पूरे क्लस्टर में भी बनी रहती है — टोकन काउंटर स्वयं सर्वसम्मति के ज़रिए प्रतिकृत (replicated) होता है, इसलिए लीडर बदलने के बाद भी नया लीडर हमेशा पहले से बड़ी संख्या से आगे बढ़ता है। सटीक फ़ील्ड फ़ॉर्मैट के लिए फेंसिंग टोकन (स्पेक) देखें।
क्लस्टर — Raft सर्वसम्मति के ज़रिए रुकावट-रहित
क्लस्टर मोड में, नोड Raft सर्वसम्मति के ज़रिए एक ही लॉक स्थिति साझा करते हैं। केवल लीडर क्लाइंट अनुरोधों को संभालता है, और हर लॉक-स्थिति परिवर्तन (अधिग्रहण, रिलीज़, समाप्ति) तभी अंतिम रूप से लागू होता है जब अधिकांश नोड इसे दर्ज कर चुके हों। किसी गैर-लीडर नोड से जुड़ने पर आपको लीडर की ओर इशारा करता एक M (स्थानांतरित) प्रतिक्रिया मिलती है।
- यदि लीडर मर जाता है, तो वर्तमान डिफ़ॉल्ट लगभग 2.3–2.5 सेकंड में नया लीडर चुनते हैं। उसी logical acquire को शेष
waitbudget में केवल तभी जारी रखा जा सकता है जब अनुरोध का कोई byte न भेजा गया हो। भेजे गए acquire की प्रतिक्रिया पुष्ट न हो तो वहIndeterminateहै और स्वतः दोबारा नहीं भेजा जाता। leaseकी समाप्ति भी सर्वसम्मति से गुज़रती है। लॉक तभी गायब होता है जब लीडर समाप्ति कमांड को कमिट करता है, इसलिए नोड्स की थोड़ी अलग घड़ियाँ कभी भी लॉक स्थिति को अलग नहीं होने देतीं।- यदि क्लस्टर अपना बहुमत खो देता है (जैसे, 3 में से 2 नोड डाउन), तो यह गलत लॉक जारी करने के जोखिम की बजाय लेखन स्वीकार करना बंद कर देता है (सुरक्षा पहले)। यदि 3 में से 2 (या 5 में से 3) नोड का volatile process state खो जाए, तो उस cluster/fencing domain को न पुनर्प्राप्त करें, न उसी identity के साथ स्वतः bootstrap करें।
क्योंकि बहुमत ही मायने रखता है, केवल 3 या 5 नोड की अनुमति है। एक सम (even) नोड संख्या केवल लागत बढ़ाती है बिना फ़ॉल्ट टॉलरेंस सुधारे, इसलिए सर्वर उसके साथ शुरू होने से इनकार कर देता है।
| नोड संख्या | रुकावट-रहित | सहनीय समवर्ती विफलताएँ | टिप्पणी |
|---|---|---|---|
| 1 | ✗ | — | token की monotonicity केवल process lifetime तक; restart होने योग्य persistent DB की सुरक्षा असमर्थित |
| 3 | ✓ | 1 | मानक रुकावट-रहित कॉन्फ़िगरेशन। अधिकांश मामलों के लिए पर्याप्त |
| 5 | ✓ | 2 | एक नोड के रखरखाव में होते हुए भी रिडंडेंसी बनी रहती है |
पीयर RPC की फ़्रेमिंग और पोर्ट नियमों के लिए प्रोटोकॉल (क्लस्टर) देखें, और नोड्स को एक-एक करके बदलने के लिए बिना रुकावट नया NodeId learner प्रतिस्थापन देखें।
क्लाइंट व्यवहार
आधिकारिक क्लाइंट सामान्यतः निम्नलिखित व्यवहार साझा करते हैं (भाषा-विशिष्ट API के लिए लाइब्रेरी देखें)।
- बैकग्राउंड में हर पते के लिए एक स्थायी कनेक्शन बनाए रखता है। एक ही पता दिए जाने पर, यह उसी नोड से दो कनेक्शन बनाए रखता है, ताकि एक सॉकेट पर संक्षिप्त गिरावट सेवा को बाधित न करे।
- लीडर-पहले, फिर राउंड-रॉबिन के आधार पर कनेक्शन चुनता है। यह
Mके ज़रिए आख़िरी बार जिस लीडर की ओर पुनर्निर्देशित किया गया था उसे याद रखता है और बाद के अनुरोध सीधे उसी को भेजता है। - अनुरोध पाइपलाइन किए जाते हैं। प्रतिक्रिया की प्रतीक्षा किए बिना अगला अनुरोध भेजा जा सकता है — अनुरोधों के साथ प्रतिक्रियाओं को कैसे जोड़ा जाता है इसके लिए प्रतिक्रिया मिलान नियम देखें।
- एक टूटा हुआ कनेक्शन एक्स्पोनेंशियल बैकऑफ़ (0.1 सेकंड से अधिकतम 3.2 सेकंड तक) के साथ फिर से जुड़ने की कोशिश करता रहता है। एक मृत कनेक्शन ब्रोकर ऑब्जेक्ट को नहीं तोड़ता — यह अपने आप ठीक हो जाता है।
- उसी logical acquire को भीतर केवल तब retry किया जाता है जब अनुरोध का कोई byte न भेजा गया हो। संबंधित
Bनिश्चित Busy/अप्राप्ति है और internal retry के बिना caller को तुरंत लौटता है।Mकेवल अगले connection का leader hint है; owner/key न होने के कारण यह पहले भेजे pending request को फिर भेजने का आधार नहीं है। पुष्ट response के बिना भेजा acquireIndeterminateबताया जाता है और critical section में प्रवेश नहीं करना चाहिए। - Explicit release और known-token compensation exact owner/token/key मिलान और bounded dedicated queue का उपयोग करते हैं। Retry request/enqueue से absolute 5-second deadline पर रुकता है, शेष lease तक नहीं चलता। success response के बिना explicit release को सफल नहीं बताया या माना जाता; server-side lease अंतिम सुरक्षा जाल है।
कनेक्शन और सुरक्षा
हर कनेक्शन (क्लाइंट या पीयर) TCP → (TLS) → चैलेंज-रिस्पॉन्स प्रमाणीकरण के क्रम में स्थापित होता है। क्लाइंट सर्वर के नॉन्स (nonce) को अपने टोकन के साथ हैश करके प्रतिक्रिया देता है, इसलिए टोकन कभी भी वायर पर प्लेनटेक्स्ट में नहीं भेजा जाता, और हर कनेक्शन पर एक नया नॉन्स रीप्ले (replay) को असंभव बना देता है। सटीक स्पेक के लिए प्रमाणीकरण हैंडशेक देखें।
संगति (कंसिस्टेंसी) पर एक नोट
- परस्पर बहिष्करण सर्वसम्मति द्वारा गारंटीकृत है। क्योंकि हर अनुदान (grant) बहुमत कमिट से गुज़रता है, नेटवर्क विभाजन या लीडर परिवर्तन के दौरान भी वही कुंजी कभी भी दो धारकों को एक साथ जारी नहीं होती।
- Persistent DB में fencing अनिवार्य है। केवल प्रति-key high-water condition, जो protected write के साथ उसी transaction/conditional write में परमाणु रूप से चले,
leaseसमाप्त होने के बाद जागे client को रोक सकती है। Lock काम का क्रम तय करता है; DB fencing अंतिम stale write रोकता है।