बिल्कुल एक बार शब्दार्थ
वास्तव में एक बार क्या है
"बिल्कुल एक बार" अक्सर दो अलग-अलग चीजों को समझा जाता है:- डिलीवरी: संदेश उपभोक्ता को ठीक एक बार दिया जाएगा।
- प्रसंस्करण: अंतिम साइड इफेक्ट (डेटाबेस को लिखना, संतुलन बदलना, एक और घटना जारी करना) ठीक एक बार होगा, भले ही अधिक डिलीवरी या प्रयास हों।
वितरित प्रणालियों में, प्रसंस्करण शब्दार्थ के बारे में बात करना अधिक विश्वसनीय है। डिलीवरी वास्तव में एक बार मुश्किल है (डुप्लिकेट और प्रतिकृति अपरिहार्य हैं), लेकिन परिणामस्वरूप राज्य को एकल उपचार के बराबर बनाया जा सकता है।
जब EOS की जरूरत है और जब नहीं
ईओएस आवश्यक है यदि:- नकद लेनदेन और शेष: डबल राइट-ऑफ की अनुमति नहीं है।
- लाइसेंस/कोटा लेखा, बिलिंग काउंटर।
- अपरिवर्तनीय बाहरी कॉल (उदाहरण के लिए, एक बार की सक्रियता)।
- प्रभाव प्रतिवर्ती या क्षतिपूर्ति योग्य हैं (सागा, रिटर्न)।
- अस्थायी डुप्लिकेट स्टोरफ्रंट/लॉग में स्वीकार्य हैं।
- पूरे रास्ते से लेनदेन खींचने की तुलना में एक आइडेम्पोटेंट सिंक प्रदान करना सस्ता है।
मॉडल: एंड-टू-एंड बनाम हॉप-बाय-हॉप
हॉप-बाय-हॉप ईओएस: प्रत्येक अनुभाग (स्रोत → प्रोसेसर → रिसीवर) गारंटी देता है कि यह अपनी कार्रवाई को ठीक एक बार लागू करेगा।
एंड-टू-एंड ईओएस: पूरी श्रृंखला यह सुनिश्चित करती है कि "तथ्य" से "साइड इफेक्ट" तक, परिणाम एकल उपचार के बराबर है।
व्यवहार में, एंड-टू-एंड प्रत्येक हॉप पर लेनदेन और/या पहचान के संयोजन द्वारा प्राप्त किया जाता है।
बुनियादी भवन ब्लॉक
1. पहचान संक्रिया
ऑपरेशन कुंजी पर एक ही क्वेरी को दोहराना एक ही परिणाम पैदा करता है।
Ключи: 'idempotency _ key '/' event _ id '/' ऑपरेशन _ id'।
कार्यान्वयन: इनपुट लॉग की TTL ≥ प्रस्तुति के साथ "देखा" संचालन की तालिका।
2. रीड-प्रोसेस-राइट लेनदेन
कार्य की एक परमाणु इकाई में, दुष्प्रभाव और पठन प्रगति (ऑफसेट/स्थिति) दोनों दर्ज किए जाते हैं। यह कदमों के बीच गिरने पर "भूत" को समाप्त कर देता है।
3. वर्शनिंग/अनुक्रम
कुल के लिए एक संस्करण/काउंटर संग्रहीत किया जाता है; परिवर्तन केवल तभी लागू होते हैं जब 'अपेक्षित _ सं एक ही घटना के दोहराव एक बार संस्करण → प्रभाव को नहीं बढ़ाते हैं।
4. डीडुप्लिकेशन
'(consumer_id, event_id)' पर या लेनदेन के प्राकृतिक 'business _ id' पर सूचकांक।
कार्यान्वयन पैटर्न
1) ऑफसेट फिक्सेशन के साथ लेन-देन लॉग + लेन-देन सिंक
धारा प्रसंस्करण के लिए आदर्श।
हम लॉग से पढ़ ते हैं (केवल पुष्ट प्रविष्टियाँ)।
हम प्रसंस्करण करते हैं।
एक लेनदेन में:- a) सिंक (डेटाबेस/टेबल) में प्रभाव लिखें,
- b) "ऑफसेट एन को पढ़ें" (उसी डेटाबेस में) फिक्स करें।
- प्रतिबद्ध। पुनः प्रारंभ करते समय, या तो सब कुछ छूट दी जाती है (और ऑफसेट को स्थानांतरित कर दिया जाता है), या कुछ भी नहीं।
गुण: बार-बार निष्पादन हानिकारक नहीं है; "बिल्कुल एक बार" प्रभाव में, भले ही संदेश दो बार पढ़ा गया हो।
2) आउटबॉक्स + पहचानने वाला उपभोक्ता
लेन-देन उत्पादक सेवाओं के लिए।
एक डेटाबेस लेनदेन में: डोमेन रिकॉर्ड बदलें और घटना को आउटबॉक्स में लिखें।
पुनरावर्तक घटना को उसी 'ईवेंट _ आईडी' के साथ बस में वितरित करता है।
उपभोक्ता घटनाओं को मूर्त रूप से लागू करते हैं ('ईवेंट _ आईडी' द्वारा डीडअप)।
गुण: निर्माता यह सुनिश्चित करता है कि कोई तथ्य खो न जाए उपभोक्ता बिल्कुल एक प्रभाव की गारंटी
3) काफ्का/फ्लिंक जैसी प्रणालियों में ईओएस (वैचारिक रूप से)
मूर्तिकार निर्माता: रिट्रीट भेजने के खिलाफ सुरक्षा करता है।
उत्पादक लेनदेन: विषयों में प्रविष्टियों का एक समूह + एक घाघ शिफ्ट परमाणु रूप से प्रतिबद्ध है; पाठक 'read _ deventizolation' का उपयोग करते हैं।
प्रसंस्करण पक्ष राज्य स्टोर को संग्रहीत करता है और लेनदेन के साथ इसे प्रतिबद
गुण: स्टोर/ड्रैग को फिर से शुरू करने से दोहरा प्रभाव नहीं पड़ ता है; डुप्लिकेट "दृश्यमान नहीं" डाउनस्ट्रीम।
4) अपसर्ट/मर्ज के माध्यम से आइडेम्पोटेंट "सिंक"
सिंक 'ऑपरेशन _ id '/' इवेंट _ id' और 'UPSERT' चलाता है... जहां मौजूद नहीं है '।
साइड इफेक्ट (उदाहरण के लिए, एक्रुअल) को परमाणु रूप से चेक के साथ किया जाता है "पहले से ही लागू नहीं किया गया है।"
गुण: वितरित लेनदेन के बिना, भंडारण के साथ किनारे पर सस्ता ईओएस विधि।
कुंजी कार्यान्वयन विवरण
ट्रांजेक्शन आईडी
पुनरावृत्ति के लिए नियतात्मक होना चाहिए (नया UUID उत्पन्न न करें जब पीछे हटना हो)।
एक स्थिर गुंजाइश है (उपभोक्ता/इकाई/प्रणाली पर)।
डीडुप्लिकेशन टेबल
Колонки: 'उपभोक्ता _ id', 'ऑपरेशन _ id', 'एप्लाइड _ at', 'ttl _ expires _ at'।
'(consumer_id, operation_id)' पर सूचकांक।
TTL ≥ अधिकतम पुनरावृत्ति विंडो (लॉग प्रतिधारण + संभावित विलंब).
आशावादी प्रतियोगिता
लेखन मॉडल में, इकाई के संस्करण को संग्रहीत करें।
किसी घटना/कमांड को लागू करते समय, 'व्हेयर वर्जन =: अपेक्षित' का उपयोग करें; डुप्लिकेट संस्करण नहीं बढ़ाएगा।
आदेश/आदेश
ईओएस "बिल्कुल एक ही क्रम नहीं है। "बैच कुंजी (सभी कुल घटनाओं - एक बैच) और/या 'अनुक्रम' तुलना के माध्यम से स्थिरता सुनिश्चित करें।
पहचान बाहरी कॉल
असुरक्षित तरीकों के लिए (उदाहरण के लिए, HTTP वेबहूक को थर्ड-पार्टी सेवा में), 'आइडेम्पोटेंसी-की' जोड़ें और साथी को इसका समर्थन करने की आवश्यकता है।
लगातार जाल
केवल एक स्थान पर ईओएस: यदि सिंक अज्ञात है, लेकिन आप बिना पहचान के माध्यमिक घटनाओं का उत्सर्जन करते हैं, तो आपको "बिल्कुल कई बार" नीचे की ओर मिलेगा।
दो प्रतिबद्ध हैं: पहले डेटाबेस में, फिर ब्रोकर में ऑफसेट प्रतिबद्ध - उनके बीच की गिरावट डुप्लिकेट प्रभाव पैदा करती है।
कच्चे सीडीसी बाहर: डीबी योजना बदलने से उपभोक्ता की पहचान टूट जाती है।
अस्थिर कुंजियाँ: 'ऑपरेशन _ आईडी' समय/यादृच्छिक पर निर्भर करता है और रिट्रे के दौरान परिवर्तन करता है।
लागत और व्यापार बंद
विलंबता: लेनदेन/पृथक पढ़ ता है → p95/p99 वृद्धि।
ओवरहेड भंडारण: डीडुप्लिकेशन टेबल, स्टेट स्टोर, लेनदेन लॉग।
ऑपरेशनल जटिलता: लेनदेन टाइमआउट, थ्रेड रिबैलेंस, अटक सत्र।
निदान: अधिक राज्य ("कामित में", "" के रूप में दिखाई देता है "" लुढ़का हुआ ")।
ईओएस पॉइंटवाइज चुनें: महत्वपूर्ण समुच्चय और प्रभाव के लिए; बाकी को पहचान और मुआवजे के साथ कवर करें।
बिल्कुल एक बार परीक्षण
1. फॉल्ट-इंजेक्शन: चरणों के बीच प्रक्रिया में गिरावट "प्रभाव दर्ज किया" और "ऑफसेट दर्ज किया।"
2. डुप्लिकेट: एक ही संदेश को 2-5 बार डाउनलोड करें, एक प्रभाव को सुनिश्चित करें।
3. पुनर्आरंभ और पुनर्संतुलन: श्रमिकों का स्टॉप/पुनः आरंभ, दोहरे प्रसंस्करण की अनुपस्थिति की जाँच करें।
4. नेटवर्क फ्लैपी: मिड-लेनदेन टाइमआउट, कमिट रीट्री।
5. लोड परीक्षण: कतार वृद्धि - क्या "लेनदेन में हमेशा के लिए" कोई गिरावट नहीं है।
मिनी टेम्पलेट्स (स्यूडो)
ऑफसेट फिक्सिंग के साथ पहचान सिंक
pseudo begin tx if not exists(select 1 from dedup where consumer_id=:c and op_id=:id)
then apply_effect(...) -- upsert / merge / add_one_time_action insert into dedup(c, id, applied_at) values(:c,:id, now)
end if update offsets set pos=:pos where consumer_id=:c commit
इकाई संस्करण के साथ कमांड
pseudo begin tx update account set balance = balance +:delta,
version = version + 1 where id=:account_id and version=:expected_version;
if row_count=0 then error CONCURRENT_MODIFICATION commit
सुरक्षा और अनुपालन
डीडुप्लीकेशन टेबल में पीआईआई/पीसीआई: न्यूनतम स्टोर करें, कच्चे डेटा के बजाय टोकन का उपयोग करें।
ऑडिट: लॉग 'ऑपरेशन _ आईडी', 'ट्रेस _ आईडी', परिणाम (APPLIED/ALREADY_APPLIED)।
भंडारण नीति: डीडअप टेबल पर टीटीएल, ऑफसेट/लॉग का संग्रह।
एंटी-पैटर्न
"वास्तविक बिल्कुल एक बार डिलीवरी": प्रभाव की पहचान के बिना परिवहन प्रोटोकॉल स्तर पर डुप्लिकेट को बाहर करने का प्रयास।
हर चीज के लिए वैश्विक वितरित लेनदेन: XA/2PC सभी सेवाओं के माध्यम से नाजुक और धीमी है।
गैर-idempotent दुष्प्रभाव का मिश्रण (उदाहरण के लिए, ऑफसेट प्रतिबद्धता से पहले भेजा गया ई-मेल)।
ऑपरेशन कुंजियों की कमी: पेलोड की "विशिष्टता" पर भरोसा करना।
उत्पादन जांच सूची
- प्रत्येक महत्वपूर्ण प्रभाव में एक पहचान कुंजी होती है।
- ऑफसेट/रीड स्थिति प्रभाव के साथ एक लेनदेन में तय की गई है।
- डीडुप्लिकेशन टेबल अनुक्रमित; TTL ≥ लॉग प्रतिधारण।
- आशावादी प्रतियोगिता (संस्करण/अनुक्रम) समुच्चय के लिए सक्षम है।
- थ्रेड्स/टॉपिक्स "कॉम्प ओनली" मोड (यदि उपलब्ध हो) में पढ़े जाते हैं।
- CI/CD में डुप्लिकेट और ड्रॉप परीक्षण मौजूद हैं।
- डैशबोर्ड: पुनरावृत्ति, असफल लेनदेन, अवरुद्ध समय, लैग्स का हिस्सा।
- 'Idempotency-Key '/retries/timeouts के लिए इंटीग्रेटर प्रलेखन।
एफएक्यू
क्या ईओएस को बिना लेनदेन के प्रदान किया जा सकता है?
अक्सर हाँ - सिंक की पहचान के माध्यम से (upsert/merge) और समुच्चय की संस्कृति। लेन-देन वारंटी को सरल बनाते हैं लेकिन लागत बढ़ाते हैं।
क्या हर किसी को एक बार की जरूरत है?
नहीं, यह नहीं है। यह महंगा है। बिंदुवार लागू करें जहां मुआवजा संभव न हो/महंगा हो।
ईओएस के साथ पत्र/वेबहूक को कैसे जोड़ें?
प्रतिबद्धता से पहले अधिसूचना को बफर करें, प्रभाव को ठीक करने के बाद भेजें; 'सूचना _ id' स्टोर करें और भेजने वाले को पहचानें।
अधिक महत्वपूर्ण क्या है - सुपुर्दगी या प्
प्रसंस्करण। प्रसव दोहराया जा सकता है; अंतिम स्थिति सही और एकमात्र होनी चाहिए।
परिणाम
वास्तव में-एक बार प्रभाव की शुद्धता के बारे में है, न कि वायरिंग में डुप्लिकेट की अनुपस्थिति के बारे में। यह निष्क्रियता, प्रभाव के परमाणु निर्धारण और पढ़ ने की प्रगति, उचित विभाजन और संस्करण अनुशासन के संयोजन से प्राप्त होता है। ईओएस लागू करें जहां त्रुटि की लागत अस्वीकार्य है, और गिरावट के साथ इसकी वास्तविकता का परीक्षण करें और परीक्षण करें - परिवहन में कोई विश्वास न