समस्या और दायरा (Problem and Scope)
एक क्षेत्र (region) में तीन उपलब्धता क्षेत्रों (availability zones) में डिप्लॉय की गई एक डिस्ट्रीब्यूटेड लॉक सर्विस डिज़ाइन करें। यह 100,000 लॉक करने योग्य संसाधनों का प्रबंधन करती है, सामान्य रूप से 20,000 सक्रिय लॉक्स बनाए रखती है, और पीक पर प्रति सेकंड 2,000 अधिग्रहणों को संभालती है। डिफ़ॉल्ट लीज़ 30 सेकंड की है, क्लाइंट हर 10 सेकंड में रिन्यू करते हैं, और बिना किसी प्रतिस्पर्धा वाले अधिग्रहण के लिए p99 लक्ष्य 200 मिलीसेकंड है। संरक्षित स्टोर या सर्विस फेंसिंग टोकन्स की एटॉमिक तुलना कर सकती है और किसी पुराने धारक (holder) के अनुरोधों को अस्वीकार कर सकती है।
स्केल, लीज़ की अवधि और लेटेंसी इंटरव्यू के इनपुट्स हैं, etcd, ZooKeeper, या किसी अन्य उत्पाद के लिए परफॉर्मेंस दावे नहीं हैं। इसके दायरे में एक्सक्लूसिव लॉक्स, वेटिंग, रिन्यूअल, रिलीज़, फेलओवर और ऑब्जर्वेबिलिटी शामिल हैं। फाइन-ग्रेन्ड डेटाबेस रो लॉक्स, एक पूर्ण ट्रांजेक्शन कोऑर्डिनेटर, स्क्रैच से सर्वसम्मति (consensus) लागू करना, और एक्टिव-एक्टिव क्रॉस-रीजन लॉकिंग प्राथमिक डिज़ाइन से बाहर हैं।
यह एक प्रतिनिधि सीनियर बैकएंड, इंफ्रास्ट्रक्चर और सिस्टम डिज़ाइन प्रश्न है। Amazon का वर्तमान SDE II इंटरव्यू मार्गदर्शन स्पष्ट रूप से सिस्टम डिज़ाइन को शामिल करता है और व्यावहारिकता, सटीकता, दक्षता, विश्वसनीयता, अनुकूलन (optimization), और स्केलेबिलिटी का मूल्यांकन करता है। केंद्रीय विफलता मोड (failure mode) इन सभी को छूता है: क्लाइंट के विफल होने के बाद सेवा को लॉक को रिकवर करना होगा बिना किसी पुराने क्लाइंट को, जो बाद में फिर से शुरू होता है, नए धारक के डेटा को दूषित करने की अनुमति दिए।
इंटरव्यूअर किसका मूल्यांकन कर रहा है (What the Interviewer Is Evaluating)
पहला, क्या उम्मीदवार विफलता क्लीनअप से म्यूचुअल-एक्सक्लूज़न सुरक्षा को अलग कर सकता है? एक लीज़ उत्तर देती है कि वर्तमान धारक के गायब होने के बाद दूसरा धारक कब कार्यभार संभाल सकता है। यह ऐसे क्लाइंट को नहीं रोकता जो लंबे समय तक पॉज़ रहने के बाद फिर से शुरू होकर राइट करता है। एक सख्त डिज़ाइन के लिए संरक्षित संसाधन पर एक फेंसिंग टोकन और वैलिडेशन की भी आवश्यकता होती है।
दूसरा, क्या कंसिस्टेंसी सीमा स्पष्ट है? अधिग्रहण, रिन्यूअल और रिलीज़ को एक स्ट्रॉन्गली कंसिस्टेंट स्टेट मशीन से गुजरना होगा। एक माइनॉरिटी पार्टिशन लॉक्स जारी करना जारी नहीं रख सकता है। यदि तीन उपलब्धता क्षेत्र स्वतंत्र रूप से निर्णय लेते हैं, तो एक नेटवर्क पार्टिशन एक ही संसाधन के लिए दो धारक बना सकता है।
तीसरा, क्या क्षमता योजना (capacity planning) में रिन्यूअल ट्रैफ़िक शामिल है? हर 10 सेकंड में रिन्यू होने वाले 20,000 सक्रिय लॉक्स के साथ, अकेले रिन्यूअल प्रति सेकंड लगभग 2,000 ऑपरेशन्स उत्पन्न करते हैं। यदि पीक में प्रति सेकंड 2,000 अधिग्रहण और समान संख्या में रिलीज़ भी हैं, तो स्टेट मशीन को केवल अधिग्रहण दर ही नहीं, बल्कि प्रति सेकंड लगभग 6,000 कमिट्स की आवश्यकता होती है।
चौथा, क्या विफलता सिमेंटिक्स अनुरोध स्तर तक पहुँचते हैं? उत्तर में ऐसा अधिग्रहण शामिल होना चाहिए जो कमिट तो होता है लेकिन अपना रिस्पॉन्स खो देता है, लीज़ से अधिक समय तक पॉज़ रहने वाला क्लाइंट, एक पुराने क्लाइंट द्वारा नए धारक के लॉक को रिलीज़ करना, कोरम का नुकसान, और लीडर परिवर्तनों के दौरान मोनोटोनिक टोकन शामिल होने चाहिए।
अंत में, क्या उम्मीदवार जानता है कि इस सेवा का उपयोग कब नहीं करना है? Google Chubby को मोटे तौर पर समन्वय (coarse-grained coordination) के लिए डिज़ाइन किया गया था। यदि कोई डेटाबेस यूनिक कंस्ट्रेंट, कंडीशनल अपडेट, सिंगल-कंज्यूमर कतार, या व्यावसायिक इडेम्पोटेंसी कुंजी पहले से ही समस्या का समाधान करती है, तो एक रिमोट लॉक एक और सिंक्रोनस विफलता बिंदु जोड़ता है।
उत्तर देने से पहले स्पष्ट करने वाले प्रश्न (Clarifying Questions Before Answering)
- क्या हमें एक्सक्लूसिव या रीडर-राइटर लॉक्स की आवश्यकता है? यह डिज़ाइन एक्सक्लूसिव लॉक्स से शुरू होता है। रीडर-राइटर लॉक्स
स्टेट, अपग्रेड और स्टार्वेशन सिमेंटिक्स जोड़ते हैं जिनका आकस्मिक रूप से वादा नहीं किया जाना चाहिए।
- क्या संरक्षित संसाधन फेंसिंग टोकन को वैलिडेट कर सकता है? यह प्रॉम्प्ट नवीनतम टोकन की एटॉमिक तुलना और स्टोरेज
को मानकर चलता है। इसके बिना, एक लीज़ केवल संघर्ष विंडो को कम करती है और किसी ज़ॉम्बी क्लाइंट को सख्ती से बाहर नहीं कर सकती है।
- वेटिंग कितनी निष्पक्ष होनी चाहिए? डिफ़ॉल्ट अनुमानित FIFO है। पूर्ण निष्पक्षता रिकवरी के दौरान
और परिवर्तनशील वर्कलोड्स के तहत लचीलेपन को कम करती है।
- एक क्लाइंट कब तक प्रतीक्षा कर सकता है?
waitTimeoutसीमित और रद्द करने योग्य है ताकि वेटिंग स्टेट हमेशा के लिए न बढ़े। - क्या लीज़ की अवधि वर्कलोड के अनुसार भिन्न हो सकती है? डिफ़ॉल्ट हर 10 सेकंड में रिन्यूअल के साथ 30 सेकंड है। लंबे जॉब्स
एक सीमित नीति के तहत अवधि का अनुरोध कर सकते हैं, लेकिन लीज़ को बिना किसी सीमा के नहीं बढ़ाया जा सकता है।
- क्या अधिग्रहण का स्वचालित रूप से पुनः प्रयास (retry) किया जा सकता है? केवल वही पुनः प्रयास सुरक्षित है जिसमें समान स्थिर
requestIdहो। अन्यथा,
खोया हुआ रिस्पॉन्स एक अज्ञात परिणाम छोड़ देता है।
- कोरम के बिना क्या होता है? सुरक्षा की जीत होती है: नए अधिग्रहण और रिन्यूअल को अस्वीकार करें। प्रत्येक पार्टिशन लॉक्स जारी नहीं कर सकता।
- क्या संरक्षित ऑपरेशन को अभी भी इडेम्पोटेंट होना चाहिए? हाँ। फेंसिंग एक पुराने युग (epoch) को अस्वीकार करती है; व्यावसायिक पुनः प्रयासों और
डुप्लिकेट सबमिशन के लिए अभी भी एक व्यावसायिक इडेम्पोटेंसी कुंजी या ट्रांजेक्शन की आवश्यकता होती है।
- क्या कम लेटेंसी वाली क्रॉस-रीजन लॉकिंग की आवश्यकता है? प्राथमिक डिज़ाइन उपलब्धता क्षेत्रों के भीतर एक क्षेत्र का है। एक सख्त
क्रॉस-रीजन लॉक उच्च लेटेंसी का भुगतान करता है या पार्टिशन के दौरान उपलब्धता खो देता है और यह फॉलो-अप का विषय है।
30-सेकंड उत्तर रूपरेखा (30-Second Answer Framework)
“मैं तीन उपलब्धता क्षेत्रों में रेप्लिकेट की गई एक स्ट्रॉन्गली कंसिस्टेंट स्टेट मशीन में लॉक स्टेट को स्टोर करूँगा। प्रत्येक अधिग्रहण, रिन्यू और रिलीज़ एक कोरम द्वारा कमिट किया जाता है। एक सफल अधिग्रहण एक leaseId, एक 30-सेकंड की समाप्ति, और एक मोनोटोनिक रूप से बढ़ता हुआ fencingToken लौटाता है। क्लाइंट हर 10 सेकंड में रिन्यू करता है और रिन्यूअल अनिश्चित होने पर काम बंद कर देता है। प्रत्येक संरक्षित ऑपरेशन टोकन रखता है; संसाधन अपने द्वारा स्वीकार किए गए उच्चतम युग को स्टोर करता है और पुराने टोकन्स को अस्वीकार करता है। लीज़ एक नए धारक को अनुमति देती है, जबकि फेंसिंग फिर से शुरू हुए पुराने धारक को अस्वीकार करती है। एक डीडुप्लिकेटेड requestId एक कमिटेड अधिग्रहण को संभालता है जिसका रिस्पॉन्स खो जाता है। ऑर्डर्ड वेटर्स भीड़ (thundering herd) से बचने के लिए केवल अपने पूर्ववर्ती (predecessor) को देखते हैं। बीस हज़ार लॉक्स प्रति सेकंड लगभग 2,000 रिन्यूअल उत्पन्न करते हैं; अधिग्रहण और रिलीज़ के साथ, मैं पर्सिस्टेंस और फेलओवर के तहत प्रति सेकंड लगभग 6,000 स्टेट कमिट्स का परीक्षण करूँगा।”
चरण-दर-चरण गहन विश्लेषण (Step-by-Step Deep Dive)
घटक आरेख (component diagram) के बजाय इनवेरिएंट्स (invariants) से शुरू करें:
- एक संसाधन के लिए, कंसिस्टेंट स्टेट मशीन एक समय में अधिकतम एक वैध
leaseIdरिकॉर्ड करती है। - प्रत्येक नए अधिग्रहित लॉक को एक बड़ा फेंसिंग टोकन प्राप्त होता है।
- संरक्षित संसाधन अपने द्वारा स्वीकार किए गए उच्चतम टोकन से कम टोकन को अस्वीकार करता है।
- केवल वर्तमान
leaseIdसे मेल खाने वाला अनुरोध ही रिन्यू या रिलीज़ कर सकता है। - सेवा बिना कोरम तक पहुंचे लॉक नहीं बनाती है या रिन्यूअल सफलता का दावा नहीं करती है।
ये इनवेरिएंट्स “लॉक सर्विस किसे धारक मानती है” को “संसाधन किसके काम को अभी भी स्वीकार करेगा” से अलग करते हैं। स्टेट मशीन पहले का फैसला करती है; साइड-इफेक्ट सीमा पर फेंसिंग दूसरे का फैसला करती है।
चरण 1: API और स्टेट को परिभाषित करें।
Acquire(resource, requestId, leaseTtl, waitTimeout)
-> { leaseId, fencingToken, expiresAt }
Renew(resource, leaseId)
-> { expiresAt }
Release(resource, leaseId)
-> { released }resource एक सामान्यीकृत व्यावसायिक पहचानकर्ता है, असीमित रॉ यूज़र इनपुट नहीं। leaseId इस स्वामित्व युग (ownership epoch) के लिए एक ऐसा पहचानकर्ता है जिसका अनुमान नहीं लगाया जा सकता। fencingToken एक कमिटेड कंसेंसस लॉग के विश्व स्तर पर मोनोटोनिक संशोधन (revision) का उपयोग करता है, जबकि प्रत्येक संरक्षित संसाधन अपने द्वारा स्वीकार किए गए उच्चतम टोकन को स्टोर करता है। requestId के लिए डीडुप्लिकेशन परिणाम कम से कम कॉलर की पुनः प्रयास विंडो (retry window) तक बना रहता है। रिलीज़ इडेम्पोटेंट है, लेकिन पुराने leaseId के साथ रिलीज़ नए धारक के लॉक को हटा नहीं सकता है।
एक लॉक रिकॉर्ड में संसाधन, leaseId, धारक की पहचान, फेंसिंग टोकन, समाप्ति और एक वैकल्पिक वेटर संदर्भ शामिल होता है। निष्क्रिय लॉक रिकॉर्ड हटाए जा सकते हैं, लेकिन टोकन पीछे नहीं जा सकते। एक ग्लोबल मोनोटोनिक संशोधन किसी संसाधन का निष्क्रिय रिकॉर्ड हटाए जाने के बाद उसके युग को 1 पर रीसेट करने से बचाता है।
चरण 2: स्ट्रॉन्गली कंसिस्टेंट रेप्लिकेशन सीमा चुनें।
स्टेट मशीन के लिए एक सिद्ध कंसेंसस स्टोर या समन्वय प्रणाली का उपयोग करें; एप्लिकेशन सेवा के अंदर Raft या Paxos को फिर से लागू न करें। तीन उपलब्धता क्षेत्रों में से प्रत्येक में एक रेप्लिका रखें। कम से कम दो रेप्लिका द्वारा कमांड कमिट करने के बाद ही लीडर सफलता लौटाता है। लॉक-स्टेट रीड्स लीनियरिज़ेबल होने चाहिए या लीडर द्वारा संभाले जाने चाहिए; एक पिछड़ती हुई रेप्लिका किसी संसाधन को खाली घोषित नहीं कर सकती है।
सामान्य अधिग्रहण पथ पैरामीटर्स और डीडुप्लिकेशन कुंजी को मान्य करता है, पुष्टि करता है कि कोई लॉक मौजूद नहीं है या स्टेट मशीन ने अपनी लीज़ समाप्त कर दी है, एक नया leaseId और संशोधन असाइन करता है, उन्हें एक कोरम में कमिट करता है, और वापस लौटता है। यदि कमिट के बाद लेकिन रिस्पॉन्स आने से पहले लीडर विफल हो जाता है, तो उसी requestId के साथ पुनः प्रयास करने पर दूसरी लीज़ बनाने के बजाय नए लीडर से मूल परिणाम प्राप्त होता है।
जब तीन में से केवल एक रेप्लिका तक ही पहुँचा जा सकता है, तो सेवा अधिग्रहण और रिन्यूअल को अस्वीकार कर देती है। यह उपलब्धता को कम करता है लेकिन म्यूचुअल-एक्सक्लूज़न को सुरक्षित रखता है। माइनॉरिटी को रिन्यू करने की अनुमति देना मददगार लग सकता है, लेकिन पुन: कनेक्शन के बाद दोनों पार्टिशन किए गए धारकों को वैध मानने का कोई सुरक्षित तरीका नहीं है।
चरण 3: विफल धारकों को रिकवर करने के लिए लीज़ का उपयोग करें।
डिफ़ॉल्ट लीज़ 30 सेकंड की है और क्लाइंट हर 10 सेकंड में रिन्यू करता है, जिससे जिटर और क्षणिक विफलताओं के लिए दो रिन्यूअल अंतराल बचते हैं। आधिकारिक लीज़ समय सर्वर-साइड समन्वय स्टेट मशीन द्वारा प्रबंधित किया जाता है। एक क्लाइंट की स्थानीय घड़ी यह तय कर सकती है कि रिन्यूअल का प्रयास कब करना है, लेकिन यह स्वामित्व साबित नहीं कर सकती। बार-बार रिन्यूअल विफलताओं या अनिश्चित रिस्पॉन्स के बाद, क्लाइंट एक शांत (quiescent) स्थिति में प्रवेश करता है, कोई नया काम शुरू नहीं करता है, और जितनी जल्दी हो सके इंटरप्टिबल इन-फ़्लाइट काम को रोकता है।
लीडर परिवर्तन को शेष लीज़ समय को सावधानीपूर्वक संभालना चाहिए; नए लीडर पर एक तेज़ घड़ी समय से पहले किसी अन्य को लॉक नहीं सौंप सकती है। प्रोडक्शन सिस्टम को एक परखे हुए लीज़ कार्यान्वयन का पुनः उपयोग करना चाहिए और लीज़ बजट में अधिकतम क्लॉक स्क्यू, इलेक्शन समय और नेटवर्क रिट्राइज़ को शामिल करना चाहिए। लीज़ को सैकड़ों मिलीसेकंड तक कम करने से क्लीनअप की गति में सुधार होता है लेकिन सामान्य जिटर लगातार लॉक के नुकसान में बदल जाता है।
चरण 4: ज़ॉम्बी क्लाइंट्स को रोकने के लिए फेंसिंग टोकन का उपयोग करें।
मान लीजिए क्लाइंट A टोकन 41 प्राप्त करता है और फिर लंबे कचरा संग्रहण (garbage collection) के लिए रुक जाता है। इसकी 30-सेकंड की लीज़ समाप्त हो जाती है, क्लाइंट B टोकन 42 प्राप्त करता है, और B काम शुरू करता है। A यह जाने बिना कि उसने लॉक खो दिया है, फिर से शुरू होता है और विलंबित राइट (delayed write) भेजता है। यदि स्टोर केवल यह जानता है कि A ने कभी लॉक प्राप्त किया था, तो पुराना राइट B के नए परिणाम को ओवरराइट कर सकता है।
इसलिए प्रत्येक संरक्षित अनुरोध अपना टोकन साथ रखता है। स्टोर प्रत्येक संसाधन के लिए देखे गए उच्चतम युग को एटॉमिक रूप से याद रखता है। टोकन 42 स्वीकार करने के बाद, यह टोकन 41 वाले प्रत्येक अनुरोध को अस्वीकार कर देता है। समान टोकन वाले एकाधिक ऑपरेशन्स अभी भी वैध हो सकते हैं; उनका क्रम, इडेम्पोटेंसी और वर्ज़न टकराव व्यावसायिक प्रोटोकॉल के अंतर्गत आते हैं। तुलना समान टोकन्स को आँख मूंदकर अस्वीकार करने के बजाय नवीनतम युग से कम टोकन्स को अस्वीकार करती है।
etcd डॉक्यूमेंटेशन भी इसी सीमा को स्पष्ट करता है: अकेले एक लीज़ किसी बाहरी संसाधन पर म्यूचुअल-एक्सक्लूज़न की गारंटी नहीं देती है; उस संसाधन को एक वर्ज़न को वैलिडेट करना होगा। यदि लक्ष्य टोकन को स्टोर या तुलना नहीं कर सकता है, तो डिज़ाइन सख्त सुरक्षा का वादा नहीं कर सकता है। विकल्पों में एक डेटाबेस कंडीशनल अपडेट, यूनिक कंस्ट्रेंट, नेटिव ट्रांजेक्शनल लॉक, सिंगल-राइटर कतार, या एक राइट प्रॉक्सी शामिल है जो टोकन को लागू कर सकती है।
चरण 5: वेटिंग, निष्पक्षता और झुंड (herds) को संभालें।
कम-प्रतिस्पर्धा वाले संसाधनों के लिए, विफल कॉलर एक्सपोनेंशियल बैकऑफ़ और जिटर के साथ पुनः प्रयास कर सकते हैं। एक हॉट संसाधन के लिए जिसमें वेटिंग की आवश्यकता है, बढ़ती हुई अनुक्रम संख्याएँ (sequence numbers) असाइन करें और प्रत्येक वेटर को केवल अपने तत्काल पूर्ववर्ती को देखने दें। जब कोई पूर्ववर्ती रिलीज़ या समाप्त होता है, तो हर क्लाइंट के एक साथ दौड़ने के बजाय केवल अगला वेटर जागता है। ZooKeeper का लॉक रेसिपी इसी कारण से एफेमरल सीक्वेंशियल नोड्स और पूर्ववर्ती वॉचेस का उपयोग करता है।
कतार अनुमानित FIFO प्रदान करती है, पूर्ण निष्पक्षता नहीं। रद्दीकरण, टाइमआउट और सत्र समाप्ति वेट नोड को हटा देते हैं। यदि नोड निर्माण का रिस्पॉन्स खो जाता है, तो requestId दूसरा जोड़ने के बजाय मूल नोड ढूंढता है। प्रति-संसाधन और प्रति-टेनेंट वेटर सीमाएं एक हॉट लॉक को मेमोरी समाप्त करने से रोकती हैं।
चरण 6: क्षमता और पार्टिशनिंग का अनुमान लगाएं।
हर 10 सेकंड में रिन्यू होने वाले बीस हज़ार सक्रिय लॉक्स प्रति सेकंड लगभग 2,000 रिन्यूअल उत्पन्न करते हैं। प्रति सेकंड 2,000 अधिग्रहणों के चरम पर, और यह मानते हुए कि रिलीज़ अधिग्रहणों के लगभग बराबर हैं, कंसेंसस स्टेट मशीन प्रति सेकंड लगभग 2,000 + 2,000 + 2,000 = 6,000 राइट कमिट्स को संभालती है। एन्क्यू, रद्दीकरण, समाप्ति और डीडुप्लिकेशन रिकॉर्ड्स राइट प्रवर्धन (write amplification) जोड़ते हैं। क्षमता परीक्षणों में पीक ट्रैफ़िक, एक रेप्लिका का नुकसान और लॉग कॉम्पेक्शन को शामिल किया जाना चाहिए।
यदि 100,000 संसाधन प्रत्येक में लगभग 500 बाइट्स लॉजिकल स्टेट बनाए रखते हैं, तो लॉजिकल कुल लगभग 50 MB है। रेप्लिका, लॉग, इंडेक्स, वेटर्स और स्टोरेज-इंजन ओवरहेड वास्तविक फ़ुटप्रिंट को काफी बढ़ा देते हैं। सिंक्रोनस पर्सिस्टेंस, हॉट संसाधन और रिन्यूअल वॉल्यूम यहाँ स्थिर रिकॉर्ड आकार की तुलना में अधिक संभावित बाधाएं हैं।
बताए गए स्केल के लिए एक कंसेंसस समूह से शुरुआत करें। संसाधन के हैश द्वारा पार्टिशन केवल तभी करें जब माप दिखाते हैं कि एक समूह लक्ष्य से चूक जाता है। शार्डिंग कुल थ्रूपुट बढ़ाती है लेकिन एक अत्यधिक हॉट संसाधन को विभाजित नहीं कर सकती है, और यह संसाधनों के बीच एटॉमिक लॉकिंग को जटिल बनाती है। यह डिज़ाइन मल्टी-रिसोर्स ट्रांजेक्शनल लॉक्स का वादा नहीं करता है। यदि कॉलर को कई संसाधनों को लॉक करना होगा, तो वे एक निश्चित क्रम और एक समग्र टाइमआउट का उपयोग करते हैं, या डोमेन को एक उच्च-स्तरीय संसाधन के रूप में फिर से तैयार किया जाता है।
चरण 7: विफलता और परिचालन लूप को बंद करें।
- लीडर विफलता: नया लीडर कमिटेड स्टेट को रिकवर करता है;
requestIdअज्ञात रिस्पॉन्स वाले अनुरोधों को सुरक्षित रूप से हल करता है। - नेटवर्क पार्टिशन: केवल कोरम सेवा प्रदान करता है; माइनॉरिटी अस्वीकार करती है, और फेंसिंग अंततः एक पुराने धारक के राइट को अस्वीकार कर देती है।
- क्लाइंट पॉज़: समाप्ति के बाद एक नया लॉक जारी किया जा सकता है, जबकि फिर से शुरू हुआ क्लाइंट संसाधन-साइड टोकन वैलिडेशन में विफल रहता है।
- हॉट लॉक: प्रतीक्षा लंबाई, अधिग्रहण लेटेंसी और होल्ड समय को मापें; कतार को सीमित करें और कतार या पार्टिशन किए गए जॉब पर विचार करें।
- रिन्यूअल स्टॉर्म: क्लाइंट शेड्यूल में जिटर जोड़ें और हर लॉक को एक साथ रिन्यू करने के बजाय समाप्ति के निकटतम लीज़ को प्राथमिकता दें।
- टोकन वैलिडेशन के बिना संसाधन: स्पष्ट रूप से बेस्ट-एफ़र्ट एक्सक्लूज़न पर डाउनग्रेड करें या सख्त धन और इन्वेंट्री राइट्स को प्रतिबंधित करें।
कोर मेट्रिक्स में अधिग्रहित करना, रिन्यू करना और रिलीज़ p50/p95/p99 शामिल हैं; सफलता, टाइमआउट, संघर्ष और अज्ञात परिणाम; सक्रिय लॉक्स, वेटर्स, समाप्ति, रिन्यूअल विफलताएं, लीडर इलेक्शन अवधि, कंसेंसस कमिट लेटेंसी, फेंसिंग रिजेक्शन, और हॉट संसाधन शामिल हैं। ऑडिट लॉग संवेदनशील पेलोड के बिना संसाधन, leaseId, टोकन, कॉलर और परिणाम को कैप्चर करते हैं।
सत्यापन यूनिट परीक्षणों से आगे जाता है। स्टेट-मशीन मॉडल परीक्षण एकल स्वामित्व और मोनोटोनिक टोकन की जांच करते हैं। दोष इंजेक्शन (fault injection) कमिट के बाद खोए हुए रिस्पॉन्स, 30 सेकंड से अधिक समय तक पॉज़ रहे क्लाइंट, एक विलंबित पुराने राइट, एक रेप्लिका के अलगाव, बहुमत के नुकसान, लीडर परिवर्तन और वेटर रद्दीकरण को कवर करता है। महत्वपूर्ण एंड-टू-एंड दावा यह है: संसाधन द्वारा B के टोकन 42 को स्वीकार करने के बाद, A का टोकन 41 उस संसाधन को फिर कभी नहीं बदल सकता है।
उच्च-गुणवत्ता वाला नमूना उत्तर (High-Quality Sample Answer)
“मैं सुरक्षा लक्ष्य के साथ शुरुआत करूँगा: स्ट्रॉन्गली कंसिस्टेंट लॉक स्टेट में एक संसाधन के पास अधिकतम एक वैध लीज़ होती है, और संरक्षित संसाधन कभी भी पुराने धारक के राइट को स्वीकार नहीं करता है। सेवा एक सिद्ध कंसेंसस स्टोर पर तीन उपलब्धता क्षेत्रों में चलती है। अधिग्रहण, रिन्यू और रिलीज़ के लिए कोरम की आवश्यकता होती है। केवल माइनॉरिटी के साथ, सेवा उपलब्धता के लिए म्यूचुअल-एक्सक्लूज़न का व्यापार करने के बजाय काम को अस्वीकार कर देती है।
API एक leaseId, समाप्ति, और मोनोटोनिक रूप से बढ़ता हुआ fencingToken लौटाता है। डिफ़ॉल्ट लीज़ 30 सेकंड की है और क्लाइंट हर 10 सेकंड में रिन्यू करता है। इसकी स्थानीय घड़ी केवल रिन्यूअल शेड्यूल करती है; यदि रिन्यूअल अनिश्चित है, तो क्लाइंट काम बंद कर देता है। एक लीज़ विफलता के बाद अधिग्रहण की अनुमति देती है, लेकिन संसाधन वास्तविक सुरक्षा सीमा है: प्रत्येक संरक्षित अनुरोध टोकन रखता है, और संसाधन अपने द्वारा स्वीकार किए गए उच्चतम युग को स्टोर करता है और पुराने टोकन को अस्वीकार करता है। यदि टोकन 41 क्लाइंट टोकन 42 द्वारा कार्यभार संभालने के बाद फिर से शुरू होता है, तो उसका पुराना राइट सफल नहीं हो सकता।
प्रत्येक अधिग्रहण में एक requestId होता है। यदि सेवा कमिट हो गई लेकिन उसका रिस्पॉन्स खो गया, तो कॉलर उसी ID के साथ पुनः प्रयास करता है और दूसरा बनाने के बजाय मूल लीज़ प्राप्त करता है। रिन्यू और रिलीज़ वर्तमान leaseId से मेल खाना चाहिए, इसलिए एक पुराना क्लाइंट नए धारक को रिलीज़ नहीं कर सकता है। एक प्रतिस्पर्धी लॉक के लिए, ऑर्डर्ड वेटर्स केवल अपने पूर्ववर्ती को देखते हैं, जो बिना किसी भीड़ के अनुमानित FIFO प्रदान करते हैं।
क्षमता के लिए, हर 10 सेकंड में रिन्यू होने वाले 20,000 लॉक्स पहले से ही प्रति सेकंड लगभग 2,000 राइट्स उत्पन्न करते हैं। 2,000 अधिग्रहण और एक समान रिलीज़ दर जोड़ने पर प्रति सेकंड लगभग 6,000 कंसेंसस कमिट मिलते हैं। मैं विक्रेता बेंचमार्क को उद्धृत करने के बजाय एक रेप्लिका डाउन होने और लॉग कॉम्पेक्शन चलने के दौरान 200-मिलीसेकंड p99 को सत्यापित करूँगा। मैं एक कंसेंसस समूह से शुरुआत करूँगा और संसाधन द्वारा शार्ड केवल तभी करूँगा जब लोड परीक्षण यह साबित करते हैं कि यह आवश्यक है।
अंत में, मॉडल परीक्षण और दोष इंजेक्शन कमिट के बाद खोए हुए रिस्पॉन्स, क्लाइंट पॉज़, विलंबित पैकेट, पार्टिशन, इलेक्शन और वेटर रद्दीकरण को कवर करते हैं। मैं अधिग्रहण और रिन्यूअल लेटेंसी, संघर्ष, समाप्ति, कतार लंबाई, इलेक्शन और फेंसिंग रिजेक्शन की निगरानी करूँगा। यदि संरक्षित प्रणाली एटॉमिक रूप से टोकन की तुलना नहीं कर सकती है, तो मैं कहूंगा कि सख्त म्यूचुअल-एक्सक्लूज़न अनुपलब्ध है और डेटाबेस कंडीशनल अपडेट, यूनिक कंस्ट्रेंट, या सिंगल-राइटर कतार को प्राथमिकता दूंगा।”
सामान्य गलतियाँ (Common Mistakes)
- केवल TTL वाली कुंजी स्टोर करना → एक रुका हुआ पुराना क्लाइंट फिर से शुरू होकर राइट कर सकता है → प्रत्येक अधिग्रहण के लिए एक मोनोटोनिक टोकन जारी करें और संसाधन पर इसे वैलिडेट करें।
- प्रत्येक उपलब्धता क्षेत्र को लॉक्स जारी करने की अनुमति देना → एक पार्टिशन कई धारक बनाता है → प्रत्येक स्टेट परिवर्तन को एक कोरम-समर्थित स्टेट मशीन के माध्यम से रखें।
- क्लाइंट क्लॉक को लीज़ की सच्चाई मानना → क्लॉक स्क्यू और पॉज़ झूठे स्वामित्व का कारण बनते हैं → सर्वर-साइड लीज़ प्रबंधित करें और अनिश्चित क्लाइंट्स को रोकें।
- नई अनुरोध ID के साथ अधिग्रहण का पुनः प्रयास करना → मूल अनुरोध पहले ही कमिट हो चुका हो सकता है → पहला परिणाम प्राप्त करने के लिए एक स्थिर
requestIdका उपयोग करें। - केवल संसाधन नाम से रिलीज़ की अनुमति देना → एक पुराना अनुरोध नए धारक को हटा सकता है → रिन्यू और रिलीज़ के लिए वर्तमान
leaseIdकी आवश्यकता है। - केवल 2,000 अधिग्रहण प्रति सेकंड के लिए आकार तय करना → 2,000 रिन्यूअल और समान रिलीज़ छूट जाते हैं → प्रति सेकंड लगभग 6,000 बेसलाइन स्टेट कमिट्स का परीक्षण करें।
- प्रत्येक वेटर से लॉक रूट को वॉच करवाना → प्रत्येक रिलीज़ पूरी कतार को जगाती है → प्रत्येक वेटर को केवल अपने तत्काल पूर्ववर्ती को देखने के लिए कहें।
- तुरंत कई कंसेंसस समूहों में शार्ड करना → संचालन और क्रॉस-रिसोर्स सिमेंटिक्स पहले जटिल हो जाते हैं → एक समूह को मापें, फिर साक्ष्य के आधार पर शार्ड करें।
- प्रत्येक रो के लिए एक डिस्ट्रीब्यूटेड लॉक का उपयोग करना → समन्वय एक उच्च-आवृत्ति ट्रांजेक्शन पथ और बाधा बन जाता है → फाइन-ग्रेन्ड कॉनक्रेन्सी के लिए डेटाबेस एटॉमिक बाधाओं को प्राथमिकता दें।
- सख्त सुरक्षा का दावा करना जब लक्ष्य टोकन को वैलिडेट नहीं कर सकता → एक लीज़ विलंबित पुराने राइट को नहीं रोक सकती → गारंटी को डाउनग्रेड करें या राइट सीमा बदलें।
फॉलो-अप प्रश्न और उत्तर (Follow-up Questions and Responses)
फॉलो-अप 1: यदि लॉक में लीज़ है तो फेंसिंग टोकन क्यों आवश्यक है?
लीज़ केवल लॉक सर्विस को 30 सेकंड के बाद B को लॉक देने की अनुमति देती है। यह ऐसे ऑपरेशन को नहीं हटा सकती जिसे A ने पहले ही किसी बाहरी सिस्टम में भेज दिया है लेकिन जो नेटवर्क या प्रोसेस कतार में बना रहता है। A एक लंबे पॉज़ के बाद यह जाने बिना भी काम फिर से शुरू कर सकता है कि उसकी लीज़ समाप्त हो गई है। एक बार जब संसाधन टोकन 42 स्वीकार कर लेता है, तो टोकन 41 को अस्वीकार करना उस बिंदु पर पुराने-युग के काम को रोकता है जहां साइड इफेक्ट होते हैं। पुन: प्रयोज्य नियम यह है: एक लीज़ तय करती है कि कब एक नया धारक चुना जा सकता है; फेंसिंग तय करती है कि क्या पुराने धारक का काम अभी भी स्वीकार किया जाता है।
फॉलो-अप 2: क्या होगा यदि संरक्षित डेटाबेस फेंसिंग टोकन को स्टोर नहीं कर सकता है?
पहले UPDATE ... WHERE version = expected, एक यूनिक कंस्ट्रेंट, एक ट्रांजेक्शनल लॉक, या एक डेटाबेस एडवाइजरी लॉक जैसी समकक्ष एटॉमिक वर्ज़न शर्त की तलाश करें। राइट्स एक प्रॉक्सी या सिंगल-कंज्यूमर कतार से भी गुजर सकते हैं जो टोकन को वैलिडेट करती है। यदि कुछ भी संभव नहीं है, तो गारंटी केवल बेस्ट-एफ़र्ट एक्सक्लूज़न है; प्रोसेस पॉज़ और विलंबित संदेश अभी भी शुद्धता को तोड़ सकते हैं। धन और इन्वेंट्री वर्कफ़्लो को किसी अस्पष्ट दावे को स्वीकार नहीं करना चाहिए।
फॉलो-अप 3: आप विभिन्न क्षेत्रों में ग्लोबल लॉक कैसे डिज़ाइन करेंगे?
प्रत्यक्ष डिज़ाइन प्रत्येक संसाधन को एक होम रीजन देता है और प्रत्येक क्षेत्र को एक क्रॉस-रीजन कोरम का उपयोग करने के लिए मजबूर करता है। यह लंबी दूरी की राइट लेटेंसी जोड़ता है, और माइनॉरिटी क्षेत्र पार्टिशन के दौरान अधिग्रहण नहीं कर सकते हैं। स्वतंत्र क्षेत्रीय लॉक्स को असिंक्रोनस रूप से मर्ज नहीं किया जा सकता क्योंकि म्यूचुअल-एक्सक्लूज़न संघर्षों को बाद में पूर्ववत (undo) नहीं किया जा सकता है। यदि क्षेत्रीय उपलब्धता अधिक मायने रखती है, तो संसाधन स्वामित्व को पार्टिशन करें ताकि एक संसाधन एक क्षेत्र में राइट करने योग्य हो, बजाय इसके कि एक्टिव-एक्टिव ग्लोबल लॉकिंग का आविष्कार किया जाए।
फॉलो-अप 4: आप 30-सेकंड की लीज़ और 10-सेकंड के रिन्यूअल अंतराल को कैसे चुनेंगे?
वे प्रॉम्प्ट इनपुट हैं। वास्तविक मान सबसे लंबे सामान्य प्रोसेस पॉज़, नेटवर्क p99, इलेक्शन समय, क्लॉक-एरर बजट और स्वीकार्य विफलता-रिकवरी समय पर निर्भर करते हैं। एक लीज़ जो बहुत छोटी है, सामान्य जिटर को लॉक हानि मानती है; जो बहुत लंबी है वह विफल धारक से रिकवरी में देरी करती है। 10-सेकंड का रिन्यूअल 30-सेकंड की लीज़ के अंदर दो अतिरिक्त अवसर देता है। रैंडम जिटर जोड़ें ताकि 20,000 क्लाइंट सिंक्रनाइज़्ड रिन्यूअल स्पाइक्स न बनाएं।
फॉलो-अप 5: आप एक साथ कई लॉक्स प्राप्त करने का समर्थन कैसे करेंगे?
सबसे सरल सीमा यह है कि यह सेवा एटॉमिक क्रॉस-रिसोर्स लॉकिंग की पेशकश नहीं करती है। कॉलर एक छोटे समग्र टाइमआउट के साथ एक निश्चित क्रम में सामान्यीकृत संसाधन नाम प्राप्त करते हैं, और विफलता के बाद उल्टे क्रम में रिलीज़ करते हैं। यह डेडलॉक को कम करता है लेकिन ट्रांजेक्शनल एटॉमिकिटी नहीं है। यदि डोमेन को वास्तव में ऑल-या-नथिंग अधिग्रहण की आवश्यकता है, तो सेट को एक उच्च-स्तरीय संसाधन के रूप में मॉडल करें या सभी कुंजियों को एक कंसेंसस ट्रांजेक्शन में रखें और थ्रूपुट और जटिलता लागत को स्वीकार करें।
फॉलो-अप 6: आप कैसे साबित करेंगे कि कार्यान्वयन कभी भी दो वैध धारक नहीं बनाता है?
अधिग्रहण, रिन्यू, रिलीज़, समाप्ति और पुनः प्रयास अनुक्रम उत्पन्न करने के लिए एक स्टेट-मशीन मॉडल का उपयोग करें, यह जांचते हुए कि प्रत्येक लॉग स्थिति में अधिकतम एक वैध leaseId है और टोकन बढ़ते हैं। फिर दोष इंजेक्ट करें: कमिट के बाद रिस्पॉन्स खोना, A को लीज़ से अधिक समय तक रोकना, B को प्राप्त करने और राइट करने देना, और A को उसके पुराने राइट के साथ फिर से शुरू करना; संसाधन को पुराने टोकन को अस्वीकार करना चाहिए। माइनॉरिटी और मेजॉरिटी को भी अलग करें, बार-बार लीडर बदलें, वेटर्स को रद्द करें, और इनवेरिएंट्स के विरुद्ध प्रत्येक समवर्ती इतिहास की जांच करें।