ES / CQRS समवर्ती हैंडलिंग


20

मैंने हाल ही में CQRS / ES में गोता लगाना शुरू किया क्योंकि मुझे इसे काम पर लागू करने की आवश्यकता हो सकती है। यह हमारे मामले में बहुत आशाजनक है, क्योंकि यह बहुत सारी समस्याओं का समाधान करेगा।

मैंने एक ईएस / सीक्यूआरएस ऐप को सरलीकृत बैंकिंग उपयोग मामले (पैसा वापस लेने) के संदर्भ में कैसे देखा जाना चाहिए, इस पर अपनी कठिन समझ को छोड़ दिया।

ES / CQRS

अगर व्यक्ति A कुछ पैसे निकालता है तो बस योग करने के लिए:

  • एक आदेश जारी किया जाता है
  • आदेश सत्यापन / सत्यापन के लिए सौंप दिया जाता है
  • यदि ईवेंट सफल होता है, तो ईवेंट इवेंट स्टोर में धकेल दिया जाता है
  • एक एग्रीगेटर एग्रीगेट पर संशोधन लागू करने के लिए घटना को समाप्त करता है

जो मैंने समझा था, घटना लॉग सत्य का स्रोत है, क्योंकि यह FACTS का लॉग है, हम इसके बाद किसी भी प्रक्षेपण को प्राप्त कर सकते हैं।


अब, जो मुझे समझ नहीं आ रहा है, इस भव्य योजना में, इस मामले में क्या होता है:

  • नियम: एक संतुलन नकारात्मक नहीं हो सकता
  • व्यक्ति A में 100e का संतुलन है
  • व्यक्ति A, 100e का विथड्रॉसमंड जारी करता है
  • सत्यापन पास और 100e घटना का MoneyWithdrewEvent उत्सर्जित होता है
  • इस बीच, व्यक्ति ए 100e का एक और विदड्रॉफ़ंड जारी करता है
  • पहले MoneyWithdrewEvent को अभी तक एकत्र नहीं किया गया था, इसलिए सत्यापन पास हो गया है, क्योंकि कुल के खिलाफ सत्यापन जांच (जो अभी तक अपडेट नहीं की गई है)
  • 100e का MoneyWithdrewEvent दूसरी बार उत्सर्जित होता है

==> हम एक संतुलन की असंगत स्थिति में हैं -100e पर जा रहे हैं और लॉग में 2 MoneyWithdrewEvent शामिल हैं

जैसा कि मैं समझता हूँ कि इस समस्या से निपटने के लिए कई रणनीतियाँ हैं:

  • a) ईवेंट स्टोर में ईवेंट के साथ एग्रीगेट वर्जन आईडी डालते हैं ताकि अगर मॉडिफिकेशन पर कोई बेमेल हो तो कुछ भी न हो
  • बी) कुछ लॉकिंग रणनीतियों का उपयोग करें, जिसका अर्थ है कि सत्यापन परत को किसी तरह एक बनाना है

रणनीतियों से संबंधित प्रश्न:

  • a) इस मामले में, इवेंट लॉग अब सत्य का स्रोत नहीं है, इससे कैसे निपटें? इसके अलावा, हम ग्राहक के पास वापस लौट आए, जबकि निकासी की अनुमति देना पूरी तरह से गलत था, क्या इस मामले में ताले का उपयोग करना बेहतर है?
  • बी) ताले == गतिरोध, क्या आपके पास सर्वोत्तम प्रथाओं के बारे में कोई अंतर्दृष्टि है?

कुल मिलाकर, मेरी समझ सही है कि कैसे संगामिति को संभालना है?

नोट: मैं समझता हूं कि एक ही व्यक्ति को इतने कम समय में दो बार पैसा निकालना खिड़की में असंभव है, लेकिन मैंने एक सरल उदाहरण लिया, विवरण में खो जाने के लिए नहीं


चरण 7 तक प्रतीक्षा करने के बजाय चरण 4 में समुच्चय को अपडेट क्यों न करें?
एरिक Eidt

तो आपका मतलब है कि इस मामले में, इवेंट स्टोर सिर्फ एक लॉग है जो केवल एग्रीगेट / अन्य अनुमानों को फिर से बनाने के लिए आवेदन शुरू करने पर पढ़ा जाता है?
लुई एफ

जवाबों:


19

मैंने एक ईएस / सीक्यूआरएस ऐप को सरलीकृत बैंकिंग उपयोग मामले (पैसा वापस लेने) के संदर्भ में कैसे देखा जाना चाहिए, इस पर अपनी कठिन समझ को छोड़ दिया।

यह एक घटना के आवेदन का सही उदाहरण है। चलो शुरू करते हैं।

हर बार जब कोई आदेश संसाधित होता है या उसे वापस ले लिया जाता है (आप समझ जाएंगे, धैर्य रखें) निम्न चरणों का पालन किया जाता है:

  1. आदेश एक कमांड हैंडलर तक पहुंचता है, अर्थात सेवा में Application layer
  2. कमांड हैंडलर पहचानता है Aggregateऔर इसे रिपॉजिटरी से लोड करता है (इस मामले में लोडिंग newएक Aggregateउदाहरण द्वारा की जाती है , इस एग्रीगेट के सभी पहले से उत्सर्जित घटनाओं को प्राप्त करने और उन्हें स्वयं एग्रीगेट में फिर से लागू करने के लिए; एग्रीगेट संस्करण के लिए संग्रहीत किया जाता है; बाद में उपयोग, घटनाओं के लागू होने के बाद एग्रीगेट अपनी अंतिम स्थिति में है - (चालू खाता शेष संख्या के रूप में गणना की जाती है)
  3. कमांड हैंडलर उपयुक्त विधि को कॉल करता है Aggregate, जैसे Account::withdrawMoney(100)कि उपज घटनाओं को इकट्ठा करता है, अर्थात MoneyWithdrewEvent(AccountId, 100); यदि खाते में पर्याप्त पैसा नहीं है (शेष <100) तो एक अपवाद उठाया जाता है और सभी को निरस्त कर दिया जाता है; अन्यथा, अगला चरण किया जाता है।
  4. कमांड हैंडलर Aggregateरिपॉजिटरी (इस मामले में रिपॉजिटरी है Event Store) को जारी रखने की कोशिश करता है ; Event streamयदि ऐसा होता है और यदि केवल तब भी होता है जब लोड किया गया था तब नई घटनाओं को जोड़कर ऐसा versionकरता Aggregateहै Aggregate। यदि संस्करण समान नहीं है, तो कमांड वापस ले ली गई है - चरण 1 पर जाएं । यदि versionसमान है, तो घटनाओं को जोड़ दिया जाता है Event streamऔर क्लाइंट को Successस्थिति प्रदान की जाती है ।

इस संस्करण की जाँच को आशावादी लॉकिंग कहा जाता है और यह सामान्य लॉकिंग तंत्र है। एक अन्य तंत्र निराशावादी लॉकिंग है जब वर्तमान लेखन पूरा होने तक अन्य लेखन अवरुद्ध होते हैं (जैसा कि शुरू नहीं हुआ)।

यह शब्द Event streamउन सभी घटनाओं के आसपास एक अमूर्तता है जो एक ही एग्रीगेट द्वारा उत्सर्जित की गई थीं।

आपको यह समझना चाहिए कि Event storeसिर्फ एक और प्रकार की दृढ़ता है जहां सभी परिवर्तनों को एक अंतिम राज्य के लिए नहीं, बल्कि एक सकल में संग्रहीत किया जाता है।

a) इस मामले में, इवेंट लॉग अब सत्य का स्रोत नहीं है, इससे कैसे निपटें? इसके अलावा, हम ग्राहक के पास वापस लौट आए, जबकि निकासी की अनुमति देना पूरी तरह से गलत था, क्या इस मामले में ताले का उपयोग करना बेहतर है?

इवेंट स्टोर हमेशा सच्चाई का स्रोत होता है।

बी) ताले == गतिरोध, क्या आपके पास सर्वोत्तम प्रथाओं के बारे में कोई अंतर्दृष्टि है?

आशावादी लॉकिंग का उपयोग करके आपके पास कोई लॉक नहीं है, बस कमांड रिट्रीइंग है।

वैसे भी, ताले! = गतिरोध


2
Aggregateजहां आप सभी घटनाओं को लागू नहीं करते हैं , वहां लोडिंग के संबंध में कुछ अनुकूलन हैं, लेकिन आप Aggregateअतीत में एक बिंदु तक का स्नैपशॉट रखते हैं और उस बिंदु के बाद हुई घटनाओं को लागू करते हैं।
कांस्टेंटिन गैलबेनू

ठीक है, मुझे लगता है कि मेरा भ्रम इस तथ्य से है कि इवेंट स्टोर == इवेंट बस (मेरे मन में कफ़्का है) इसलिए कुल मिलाकर फिर से निर्माण करना महंगा हो सकता है क्योंकि आपको बहुत सारी घटनाओं को फिर से पढ़ना पड़ सकता है। स्नैपशॉट होने के मामले में Aggregate, स्नैपशॉट को कब अपडेट किया जाना चाहिए? क्या स्नैपशॉट इवेंट स्टोर के समान है या क्या यह इवेंट बस से प्राप्त एक भौतिक दृश्य है?
लुई एफ

स्नैपशॉट बनाने के बारे में कुछ रणनीतियाँ हैं। एक हर n घटनाओं को एक स्नैपशॉट बनाने के लिए है। आपको स्नैपशॉट को घटनाओं के साथ, उसी स्थान पर / दृढ़ता / डेटाबेस में संग्रहीत करना चाहिए। विचार यह है कि स्नैपशॉट दृढ़ता से एग्रीगेट के संस्करण से संबंधित है।
कांस्टेंटिन गैलबेनु

ठीक है, मुझे लगता है कि मुझे इस बारे में एक स्पष्ट दृष्टि है कि इसे कैसे संभालना है। अब आखिरी सवाल, अंत में इवेंट बस की भूमिका क्या है? यदि समुच्चय को समकालिक रूप से अपडेट किया जाता है?
लुई एफ

1
हां, आप एक RabbitMQ या जो भी चैनल आप ईवेंट को रीड मॉडल में भेजना चाहते हैं, का उपयोग कर सकते हैं, लेकिन उसके बाद ही आप उन्हें इवेंट स्टोर में भेज सकते हैं। वास्तव में, किसी भी घटना का सत्यापन उनके द्वारा किए जाने के बाद नहीं किया जाता है: घटनाएं उन तथ्यों का प्रतिनिधित्व करती हैं जो हुईं; एक रीड मॉडल ऐसा हो सकता है या नहीं हो सकता है कि कुछ हुआ हो, लेकिन यह इतिहास को बदल नहीं सकता है।
कांस्टेंटिन गैलबेनू

1

मैंने एक ईएस / सीक्यूआरएस ऐप को सरलीकृत बैंकिंग उपयोग मामले (पैसा वापस लेने) के संदर्भ में कैसे देखा जाना चाहिए, इस पर अपनी कठिन समझ को छोड़ दिया।

बंद करे। समस्या यह है कि आपके "कुल" को अपडेट करने का तर्क एक अजीब जगह पर है।

अधिक सामान्य कार्यान्वयन यह है कि डेटा मॉडल जिसे आपका कमांड हैंडलर मेमोरी में रखता है, और इवेंट स्टोर में घटनाओं की धारा को सिंक्रनाइज़ रखा जाता है।

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

यदि कमांड हैंडलर को इवेंट स्टोर के साथ फिर से सिंक्रनाइज़ करने की आवश्यकता है (क्योंकि इसका आंतरिक मॉडल स्टोर से मेल नहीं खाता है), यह स्टोर से इतिहास को लोड करने और अपनी आंतरिक स्थिति के पुनर्निर्माण के द्वारा ऐसा करता है।

दूसरे शब्दों में, तीर 2 & 3 (यदि मौजूद है) आम तौर पर ईवेंट स्टोर से जुड़ा होगा, न कि एक समग्र स्टोर से।

ईवेंट स्टोर में ईवेंट के साथ एग्रीगेट वर्जन आईडी को रखें ताकि अगर मॉडिफिकेशन के बाद कोई एडिशन मिसमैच हो जाए, तो कुछ न हो

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


हम्म मुझे लगता है कि मैंने इवेंट स्टोर घटक को गलत समझा। मैंने सोचा कि सब कुछ इसके माध्यम से जाना चाहिए और प्रवाहित होना चाहिए। क्या होगा अगर मेरा इवेंट स्टोर एक काफ्का है और आसानी से पढ़ा जा सकता है? मैं सभी संदेशों के माध्यम से फिर से जाने के लिए चरण 2 और 3 पर खर्च नहीं कर सकता। ऐसा लगता है कि कुल मिलाकर मेरी दृष्टि इस से मेल खाती है: medium.com/technology-learning/…
लुइस एफ
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.