3.3

अंग्रेज़ी में देखें

3.3 वितरित सिस्टम

अवलोकन और प्रेरणा

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

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

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

मुख्य सिद्धांत

  • नेटवर्क विश्वसनीय नहीं है। हर रिमोट इंटरैक्शन को यह मानकर डिज़ाइन करें कि यह धीमा हो सकता है, विफल हो सकता है, दोहरा सकता है, या क्रम बदल सकता है।
  • किसी विभाजन (partition) के दौरान आप पूर्ण संगति और पूर्ण उपलब्धता दोनों नहीं पा सकते। प्रति इंटरैक्शन जानबूझकर चुनें (CAP/PACELC), और याद रखें कि विभाजन न होने पर भी विलंबता एक लागत है।
  • ऑपरेशनों को इडेम्पोटेंट बनाएं। यदि किसी ऑपरेशन को सुरक्षित रूप से फिर से आज़माया जा सकता है, तो अधिकांश वितरित विफलता प्रबंधन सुगम्य हो जाता है।
  • हर रिमोट कॉल को एक टाइमआउट चाहिए। असीमित प्रतीक्षा एक धीमी निर्भरता को पूरे सिस्टम के आउटेज में बदल देती है।
  • जहां व्यवसाय अनुमति देता है वहां अंततः संगति (eventual consistency) को प्राथमिकता दें, लेकिन इसे स्पष्ट बनाएं। उपयोगकर्ताओं और ऑडिटरों को यह समझना चाहिए कि उन्हें कब पुराना डेटा दिख सकता है।
  • विफलताओं को अलग करें। बल्कहेड और सर्किट ब्रेकर एक विफल घटक को सभी में फैलने से रोकते हैं।
  • आप वह डीबग नहीं कर सकते जो आप देख नहीं सकते। वितरित प्रवाहों (flows) को हर हॉप में सहसंबद्ध ट्रेसिंग, मेट्रिक्स, और लॉग चाहिए।
  • “एक-बार-ही डिलीवरी” एक मिथक है; एक-बार-ही प्रोसेसिंग एक इंजीनियरिंग उपलब्धि है। डीडुप्लीकेशन के साथ कम-से-कम-एक-बार (at-least-once) के लिए डिज़ाइन करें।

सिफारिशें

CAP और PACELC के साथ संगति के बारे में तर्क करें

CAP प्रमेय कहता है कि एक नेटवर्क विभाजन के दौरान एक सिस्टम को संगति (हर रीड नवीनतम राइट देखे) और उपलब्धता (हर अनुरोध को एक प्रतिक्रिया मिले) के बीच चुनना होगा। PACELC एक दूसरा व्यापार जोड़ता है: अन्यथा (Else) (जब कोई विभाजन न हो) आप अभी भी विलंबता (Latency) को संगति (Consistency) के विरुद्ध व्यापार करते हैं। इसे एक पूरे-सिस्टम लेबल के रूप में मुहर न लगाएं। इसे प्रति ऑपरेशन तय करें। एक बैंक के बैलेंस ट्रांसफर को मज़बूत संगति चाहिए और वह डबल-स्पेंड का जोखिम लेने के बजाय मना कर देगा। एक सोशल फ़ीड या एक उत्पाद-दृश्य काउंटर उपलब्धता और गति के बदले पुरानापन स्वीकार कर सकता है। लिख लें कि हर डेटा प्रवाह किस संगति मॉडल का उपयोग करता है (मज़बूत, कारणात्मक, अपनी-लिखी-चीज़ें-पढ़ना, या अंततः), ताकि कोई भी ऐसी गारंटी न मान ले जो सिस्टम वास्तव में प्रदान नहीं करता।

इडेम्पोटेंसी, टाइमआउट, पुनःप्रयास, और बैकऑफ़ को साथ बनाएं

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

झरने (cascades) को रोकने के लिए सर्किट ब्रेकर और बल्कहेड जोड़ें

एक सर्किट ब्रेकर किसी निर्भरता के कॉल को देखता है और, विफलताओं की एक सीमा के बाद, “खुल” जाता है: यह एक शीतलन अवधि के लिए तुरंत विफल हो जाता है, बजाय इसके कि संघर्ष कर रही सेवा पर और अनुरोध जमा करे, फिर रिकवरी का परीक्षण करने के लिए “आधा-खुला” हो जाता है। यह उस झरने को रोकता है जहां एक धीमी डाउनस्ट्रीम सेवा हर कॉलर के थ्रेड को समाप्त कर देती है जब तक पूरा सिस्टम रुक न जाए। बल्कहेड संसाधनों (थ्रेड पूल, कनेक्शन पूल) को विभाजित करते हैं ताकि एक निर्भरता में संतृप्ति दूसरों को चाहिए होने वाली क्षमता न खा सके। दोनों को सुंदर क्षीणन (graceful degradation) के साथ जोड़ें: जब कोई गैर-महत्वपूर्ण निर्भरता अनुपलब्ध हो, तो पूरे अनुरोध को विफल करने के बजाय कैश्ड या डिफ़ॉल्ट प्रतिक्रियाएं लौटाएं।

वितरित लेनदेन को सागा से प्रबंधित करें, टू-फ़ेज़ कमिट से नहीं

आप आमतौर पर कई सेवाओं या डेटाबेस में एक ही ACID (Atomicity, Consistency, Isolation, Durability) लेनदेन नहीं रख सकते। वितरित टू-फ़ेज़ कमिट धीमा है, संसाधनों को लॉक करता है, और उपलब्धता कम करता है। इसके बजाय सागा पैटर्न (saga pattern) का उपयोग करें। किसी व्यावसायिक लेनदेन को स्थानीय लेनदेन के एक क्रम के रूप में मॉडल करें, हर एक अगले को ट्रिगर करने वाला एक इवेंट प्रकाशित करता है, हर चरण के लिए एक प्रतिपूरक क्रिया (compensating action) के साथ ताकि यदि बाद का कोई चरण विफल हो जाए तो उसे पूर्ववत किया जा सके। सागा दो प्रकार के होते हैं। कोरियोग्राफी (choreography) में सेवाएं एक-दूसरे के इवेंट पर प्रतिक्रिया देती हैं, बिना किसी केंद्रीय नियंत्रक के। ऑर्केस्ट्रेशन (orchestration) में एक केंद्रीय समन्वयक चरणों को चलाता है, जिसके बारे में तर्क करना और निगरानी करना आसान है। सागा अंततः संगति (eventual consistency) को अपनाते हैं: सिस्टम मध्यवर्ती अवस्थाओं से गुज़रता है और फिर अभिसरित (converge) होता है। इसलिए उपयोगकर्ता अनुभव और ऑडिट ट्रेल को “प्रगति में” और “प्रतिपूरित” अवस्थाओं के लिए हिसाब देने योग्य डिज़ाइन करें।

एक-बार-ही को कम-से-कम-एक-बार प्लस डीडुप्लीकेशन के रूप में मानें

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

वितरित प्रवाहों को शुरू से अंत तक इंस्ट्रूमेंट करें

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

ट्रेड-ऑफ: फायदे और नुकसान

तकनीकफायदेनुकसान / लागत
मज़बूत संगतिसरल मानसिक मॉडल, कोई पुराना रीड नहींविभाजन के दौरान कम उपलब्धता, अधिक विलंबता, समन्वय लागत
अंततः संगतिउच्च उपलब्धता, कम विलंबता, स्केलेबलपुराने रीड, जटिल तर्क, संघर्ष समाधान की ज़रूरत
बैकऑफ़ के साथ पुनःप्रयासअस्थायी विफलताओं को स्वचालित रूप से पार करते हैंगलत उपयोग होने पर भार बढ़ाते हैं; इडेम्पोटेंसी और सीमाओं की ज़रूरत
सर्किट ब्रेकर / बल्कहेडझरने वाली विफलता को रोकते हैं, तुरंत विफल होते हैंजोड़ी गई जटिलता, सीमाओं को ट्यून करना, समय से पहले ट्रिप होने का जोखिम
सागा (बनाम 2PC)स्केलेबल, उपलब्ध, कोई वितरित लॉक नहींअंततः संगति, प्रतिपूरण तर्क, तर्क करना कठिन

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

अपनी टीम के साथ चर्चा करने के लिए प्रश्न

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

  2. क्या आपके टाइमआउट और पुनःप्रयास बजट पूरी कॉल चेन में संयोजित (compose) होते हैं, या एक गहरा अनुरोध खुद को एक आउटेज में पुनःप्रयास कर लेता है? एक ही अनुरोध अक्सर कई हॉप पार करता है, और यदि हर परत स्वतंत्र रूप से अपने खुद के टाइमआउट के साथ तीन बार पुनःप्रयास करती है, तो सबसे भीतरी विफलता गुणित हो जाती है और बाहरी कॉलर किसी भी मानव-सहनीय सीमा से बहुत आगे तक प्रतीक्षा करता है। उपयोगकर्ता-सामना करने वाले अनुरोध के लिए एक कुल समय बजट सेट करें और इसे चेन में बांटें, ताकि एक आंतरिक सेवा को पता हो कि उसके पास कितना कम समय बचा है और वह तूफ़ान में पुनःप्रयास करने के बजाय जल्दी विफल हो जाए। अपना निर्भरता ग्राफ़ और एक वास्तविक ट्रेस लाएं, फिर सबसे खराब स्थिति टाइमआउट और पुनःप्रयास संयोजन जोड़ें और इसकी तुलना करें कि उपयोगकर्ता वास्तव में कितना प्रतीक्षा करेगा। जिटर के साथ एक्सपोनेंशियल बैकऑफ़ और कुल प्रयासों पर एक सीमा एक संक्षिप्त गड़बड़ी को स्वयं-निर्मित सेवा-अस्वीकृति बनने से रोकती है। गहरी, बातूनी समकालिक (synchronous) चेन यहां दुश्मन हैं, इसलिए उत्तर आपको असिंक्रोनस प्रवाहों या कम हॉप की ओर धकेल सकता है।

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

  4. हर प्रमुख डेटा प्रवाह के लिए, क्या स्वामी टीम उस संगति मॉडल का नाम बता सकती है जो वह प्रदान करता है, और क्या वह विकल्प इस बात से मेल खाता है कि व्यवसाय को वास्तव में क्या चाहिए? CAP और PACELC प्रति ऑपरेशन एक जानबूझकर विकल्प के लिए मजबूर करते हैं, फिर भी एक बड़े संगठन में डिफ़ॉल्ट है बहाव: एक प्रवाह जो एक कम-दांव वाले काउंटर के लिए अंततः संगत शुरू हुआ था, उसे किसी ऐसी चीज़ के लिए पुनः उपयोग किया जाता है जो अब भुगतान स्वीकृत करती है या पहुंच देती है, और कोई भी गारंटी का पुनर्परीक्षण नहीं करता। प्रतिस्पर्धी विचार वास्तविक हैं, क्योंकि मज़बूत संगति की कीमत विभाजन के दौरान उपलब्धता और विभाजन न होने पर भी विलंबता है, जबकि अंततः संगति स्पीड खरीदती है पुराने रीड और संघर्ष समाधान की कीमत पर जिसे आपको डिज़ाइन करना होगा। अपने शीर्ष डेटा प्रवाहों की एक सूची लाएं, हर एक को उसके वर्तमान मॉडल (मज़बूत, कारणात्मक, अपनी-लिखी-चीज़ें-पढ़ना, या अंततः) के साथ और एक पुराने या खोए रीड के व्यावसायिक परिणाम के साथ लेबल किया हुआ, फिर उन बेमेलों को खोजें जहां गारंटी दांव से ज़्यादा या कम मज़बूत है। एंटरप्राइज़ वित्त में और सरकारी लाभ या पहचान सिस्टम में, एक आधिकारिक निर्णय के पीछे एक अंततः संगत रीड उस तरह का मूक दोष है जो महीनों बाद एक ऑडिट फ़ाइंडिंग या एक गलत अस्वीकृति के रूप में सामने आता है, इसलिए समीक्षा स्वयं वह प्रमाण है जिसे ऑडिटर देखना चाहेंगे।

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

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

क्षेत्रीय दृष्टिकोण

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

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

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

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

उदाहरण

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

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

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

व्यावसायिक मामला: प्रेरणाएं, ROI, और TCO

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

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

एंटी-पैटर्न और नुकसान

  • कोई टाइमआउट नहीं। एक भी अटकी हुई निर्भरता हर थ्रेड को समाप्त कर देती है और पूरे सिस्टम को गिरा देती है।
  • गैर-इडेम्पोटेंट ऑपरेशनों को पुनःप्रयास करना। डुप्लिकेट साइड इफ़ेक्ट: दोहरे चार्ज, डुप्लिकेट रिकॉर्ड, दोहरे ईमेल।
  • पुनःप्रयास तूफ़ान। बैकऑफ़ और जिटर के बिना समन्वित पुनःप्रयास जो एक छोटी गड़बड़ी को एक आउटेज में बढ़ा देते हैं।
  • एक-बार-ही डिलीवरी मान लेना। ऐसे उपभोक्ता बनाना जो उन डुप्लिकेट संदेशों पर टूट जाते हैं जिन्हें ब्रोकर अंततः डिलीवर करेगा।
  • साझा डेटाबेस के माध्यम से वितरित लेनदेन। एक डेटाबेस के माध्यम से सेवाओं को जोड़कर ACID का नाटक करना, एक वितरित मोनोलिथ को फिर से बनाना।
  • आंशिक विफलता की अनदेखी। ऐसा कोड जो मानता है कि एक रिमोट कॉल या तो पूरी तरह सफल होता है या पूरी तरह विफल, बिना “समय समाप्त लेकिन शायद पूरा हुआ” के लिए किसी संभाल के।
  • कोई सहसंबंध ID नहीं। दस मशीनों पर असंबंधित लॉग को ग्रेप करके एक क्रॉस-सर्विस घटना को डीबग करना।
  • बातूनी समकालिक कॉल चेन। गहरे समकालिक निर्भरता ग्राफ़ जहां कोई भी एक धीमा हॉप पूरे अनुरोध को रोक देता है।

परिपक्वता मॉडल

  • स्तर 1: आरंभ करें। रिमोट कॉल को स्थानीय कॉल की तरह माना जाता है। टाइमआउट अनुपस्थित या भोले हैं, पुनःप्रयास अनुपस्थित या लापरवाह हैं, और विफलताएं पूरे सिस्टम में झरने की तरह फैलती हैं। संगति या डिलीवरी का कोई साझा दृश्य नहीं है, और एक क्रॉस-सर्विस घटना को डीबग करने का अर्थ है बाद में प्रति-मशीन लॉग की खुदाई।
  • स्तर 2: विकसित करें। कुछ टीमें टाइमआउट और बुनियादी पुनःप्रयास और थोड़ी इडेम्पोटेंसी जोड़ती हैं, लेकिन अभ्यास सेवा-दर-सेवा असंगत हैं। लॉग केंद्रीकृत हैं फिर भी सहसंबद्ध नहीं हैं, इसलिए हॉप में एक अनुरोध को ट्रेस करना मैन्युअल है। वितरित लेनदेन के काम करने की उम्मीद की जाती है न कि उन्हें मॉडल किया जाता है, और संगति गारंटी व्यक्तिगत इंजीनियरों के दिमाग़ में रहती हैं।
  • स्तर 3: मानकीकृत करें। इडेम्पोटेंसी, सीमित पुनःप्रयास, जिटर के साथ बैकऑफ़, सर्किट ब्रेकर, और बल्कहेड साझा लाइब्रेरी के माध्यम से पूरे संगठन में मानक हैं। प्रतिपूरक क्रियाओं वाले सागा बहु-सेवा लेनदेन को संभालते हैं, सहसंबंध ID वाली वितरित ट्रेसिंग मौजूद है, और हर प्रमुख डेटा प्रवाह अपने संगति मॉडल और डिलीवरी गारंटी का दस्तावेज़ीकरण करता है। नियम लिखे गए हैं और पूरे संगठन में लागू किए गए हैं, हर टीम पर नहीं छोड़े गए हैं।
  • स्तर 4: प्रबंधित करें। रेज़िलिएंस को आधार रेखाओं के विरुद्ध मापा जाता है, केवल मौजूद नहीं है। आप प्रति सेवा और निर्भरता त्रुटि दर, विलंबता प्रतिशतक, संतृप्ति, और थ्रूपुट ट्रैक करते हैं, पुनःप्रयास अनुपात और सर्किट-ब्रेकर खुलने की दरें देखते हैं, और उपयोगकर्ता-दृश्य लक्षणों पर सेवा-स्तर उद्देश्य निर्धारित करते हैं। कुल समय बजट कॉल चेन में संयोजित होने के लिए सत्यापित किए जाते हैं, क्रॉस-सर्विस घटनाओं के लिए औसत-पुनर्प्राप्ति-समय एक निगरानी की गई मेट्रिक है, और फॉल्ट-इंजेक्शन और गेम-डे परिणाम उन आंकड़ों को फ़ीड करते हैं जो हर बदलाव को गेट करते हैं।
  • स्तर 5: समन्वित करें। रेज़िलिएंस निरंतर सुधारा गया प्लेटफ़ॉर्म डिफ़ॉल्ट है, पूरे संगठन में एकीकृत और परिस्थितियों के अनुकूल। फॉल्ट इंजेक्शन तंग ब्लास्ट रेडियस के साथ नियमित रूप से उत्पादन में चलता है, सिस्टम डिज़ाइन के अनुसार सुंदर ढंग से क्षीण होते हैं, और संगति और डिलीवरी विकल्पों का पुनरीक्षण किया जाता है जैसे-जैसे भार और व्यावसायिक दांव बदलते हैं। स्तर 4 के मेट्रिक्स स्वचालित प्रतिक्रियाओं और स्थिर वास्तुशिल्प विकास को चलाते हैं, इसलिए वितरित संपत्ति हर घटना के साथ केवल जीवित रहने के बजाय अधिक मज़बूत होती जाती है।

चर्चा के लिए विचार

  1. आपके कौन से महत्वपूर्ण ऑपरेशन आज वास्तव में इडेम्पोटेंट हैं, और कौन से चुपचाप नहीं हैं?
  2. हर प्रमुख डेटा प्रवाह के लिए, क्या आपकी टीम संगति मॉडल और डिलीवरी गारंटी को याद से बता सकती है?
  3. आपके पिछले झरने वाले आउटेज को एक सर्किट ब्रेकर कहां रोक सकता था?
  4. फ़िलहाल एक विफल हो रहे अनुरोध को उन सभी सेवाओं में ट्रेस करने में कितना समय लगता है जिन्हें वह छूता है?
  5. आपके कौन से “वितरित लेनदेन” वास्तव में भाग्य पर निर्भर हैं, और कौन से प्रतिपूरणों के साथ सच्चे सागा हैं?
  6. यदि आपका मैसेज ब्रोकर एक घंटे के लिए हर संदेश को दो बार फिर से डिलीवर करे, तो क्या टूटेगा?

मुख्य बातें

  • मान लें कि नेटवर्क अविश्वसनीय है और विफलताएं आंशिक हैं; हर रिमोट इंटरैक्शन को धीमेपन, हानि, दोहराव, और क्रम-बदलाव के लिए डिज़ाइन करें।
  • CAP/PACELC का उपयोग करके प्रति ऑपरेशन संगति बनाम उपलब्धता तय करें; हर प्रवाह जो मॉडल प्रदान करता है उसका दस्तावेज़ीकरण करें।
  • इडेम्पोटेंसी, टाइमआउट, सीमित पुनःप्रयास, और जिटर-के-साथ-बैकऑफ़ एक पैकेज हैं; अन्य तीन के बिना कभी पुनःप्रयास न अपनाएं।
  • सर्किट ब्रेकर और बल्कहेड विफलताओं को नियंत्रित करते हैं; प्रतिपूरणों वाले सागा अकार्यशील वितरित लेनदेन को बदल देते हैं।
  • डिलीवरी को कम-से-कम-एक-बार मानें और एक-बार-ही प्रभाव हासिल करने के लिए प्रोसेसिंग को इडेम्पोटेंट बनाएं।
  • सहसंबद्ध ट्रेसिंग, मेट्रिक्स, और लॉग वितरित प्रवाहों को समझने और संचालित करने का एकमात्र तरीका है।

संदर्भ और आगे का पठन

  • Martin Kleppmann, Designing Data-Intensive Applications
  • Andrew Tanenbaum and Maarten van Steen, Distributed Systems: Principles and Paradigms
  • Michael Nygard, Release It!: Design and Deploy Production-Ready Software
  • Sam Newman, Building Microservices
  • Chris Richardson, Microservices Patterns (sagas, transactional messaging)
  • Eric Brewer, “CAP Twelve Years Later” and Daniel Abadi on PACELC
  • Leslie Lamport, “Time, Clocks, and the Ordering of Events in a Distributed System”
  • Cindy Sridharan, Distributed Systems Observability
  • Nassim Nicholas Taleb की एंटीफ्रैजिलिटी (antifragility) की अवधारणा (जैसा कि रेज़िलिएंस-इंजीनियरिंग साहित्य में लागू किया गया है)