ইভেন্ট স্টোরের পরিবর্তে একটি "স্ন্যাপশট" প্রজেকশন থেকে সমষ্টিগুলি পুনরায় পাঠাচ্ছে


14

তাই আমি কিছুক্ষণের জন্য ইভেন্ট সোর্সিং এবং সিকিউআরএসের সাথে ফ্লার্ট করছি, যদিও আমি সত্যিকারের প্রকল্পে নিদর্শনগুলি প্রয়োগ করার সুযোগ পাইনি।

আপনার পড়া এবং উদ্বেগগুলি লেখার আলাদা করার সুবিধাগুলি আমি বুঝতে পেরেছি এবং ইভেন্ট ইভেন্টটি আপনার ইভেন্ট স্টোর থেকে আলাদা যা "পড়ুন মডেল" ডেটাবেসগুলিতে রাষ্ট্র পরিবর্তনগুলি কীভাবে সহজ করে তোলে তা আমি প্রশংসা করি।

আমি যা স্পষ্ট করে বলছি না কেন আপনি কেন ইভেন্ট স্টোর থেকে নিজের সমষ্টিগুলিকে পুনরায় হাইড্রেট করবেন।

যদি "পঠন" ডাটাবেসগুলিতে পরিবর্তনগুলি প্রজেক্ট করা খুব সহজ হয় তবে কেন সর্বদা "লিখন" ডাটাবেসে পরিবর্তিত প্রকল্পগুলি নয় কেন যার স্কিমা আপনার ডোমেন মডেলের সাথে পুরোপুরি মেলে? এটি কার্যকরভাবে একটি স্ন্যাপশট ডাটাবেস হতে পারে।

আমি ভেবেছি বন্যের ES + CQRS অ্যাপ্লিকেশনগুলিতে এটি অবশ্যই প্রচলিত হওয়া উচিত।

যদি এটি হয় তবে স্কিমা পরিবর্তনের ফলে আপনার "লেখার" ডাটাবেসটিকে পুনর্নির্মাণের সময় ইভেন্ট স্টোরটি কি কেবল কার্যকর? নাকি আমি আরও বড় কিছু মিস করছি?


কোনও রাইটিং মডেল স্টেট স্টোরটিতে অবিচ্ছিন্নভাবে লিখতে এবং সত্তা লোড করার জন্য এটি একচেটিয়াভাবে ব্যবহার করে কোনও ভুল নেই। আপনি একই কাজ করেন বা না করেন একই একই ধারাবাহিকতার সমস্যাগুলি উপস্থিত রয়েছে। এই ধারাবাহিকতার সমস্যাগুলি সমাধান করার মূল চাবিকাঠিটি হ'ল আপনার সত্তাকে আলাদাভাবে মডেল করা। ইভেন্ট সোর্সিং সম্পর্কে এমন কোনও জাদু নেই যা সেই ধারাবাহিকতার সমস্যাগুলি সমাধান করে। যাদুটি মডেলিংয়ের মধ্যে রয়েছে এবং যত্নশীল নয়। কিছু নির্দিষ্ট অ্যাপ্লিকেশন রয়েছে যার পর্যায়ে ধারাবাহিকতা প্রয়োজন যা অত্যন্ত বিতর্কিত সত্তা রয়েছে আপনি তা কীভাবে মডেল করেন এবং নির্বিশেষে বিশেষ মনোযোগ প্রয়োজন।
অ্যান্ড্রু লারসন

যতক্ষণ আপনি ইভেন্ট বিতরণের গ্যারান্টি দিতে পারেন। এটি করার জন্য, আপনার অ্যাপ্লিকেশনটিকে কেবল একটি টেকসই ইভেন্ট বাসের মধ্যে সিঙ্ক্রোনজভাবে একটি ইভেন্ট প্রকাশ করতে হবে। প্রকাশের পরে, আবেদনের কাজ সম্পূর্ণ হয়। এরপরে বাস এটি বিভিন্ন ইভেন্ট হ্যান্ডলারের কাছে পৌঁছে দেবে: একটি ইভেন্টের স্টোর আপডেট করতে, একটি স্টেট স্টোর আপডেট করার জন্য, এবং পড়ার স্টোরগুলি আপডেট করার জন্য অন্য যে কোনও প্রয়োজন। আপনি ইভেন্ট সোর্সিংটি ব্যবহার করার কারণ হ'ল আপনি তাত্ক্ষণিক ধারাবাহিকতার বিষয়ে আর চিন্তা করেন না। এটা আলিঙ্গন.
অ্যান্ড্রু লারসন

ইভেন্ট স্টোর থেকে আপনার অস্তিত্বগুলি ক্রমাগত লোড করার কোনও কারণ নেই। এটা তার উদ্দেশ্য নয়। এর উদ্দেশ্য হ'ল সিস্টেমে ঘটে যাওয়া সমস্ত কিছুর একটি কাঁচা, স্থায়ী খাতা সরবরাহ করা। সত্তার স্টেট স্টোর এবং ডেনারমালাইজড রিড মডেলগুলি লোডিং এবং পড়ার জন্য।
অ্যান্ড্রু লারসন

উত্তর:


14

আমি যা স্পষ্ট করে বলছি না কেন আপনি কেন ইভেন্ট স্টোর থেকে নিজের সমষ্টিগুলিকে পুনরায় হাইড্রেট করবেন।

কারণ "ইভেন্টগুলি" রেকর্ডের বই।

যদি "পঠন" ডাটাবেসগুলিতে পরিবর্তনগুলি প্রজেক্ট করা খুব সহজ হয় তবে কেন সর্বদা "লিখন" ডাটাবেসে পরিবর্তিত প্রকল্পগুলি নয় কেন যার স্কিমা আপনার ডোমেন মডেলের সাথে পুরোপুরি মেলে? এটি কার্যকরভাবে একটি স্ন্যাপশট ডাটাবেস হতে পারে।

হ্যাঁ; এটি প্রতিবার স্ক্র্যাচ থেকে পুনরায় জেনারেট করার পরিবর্তে সামগ্রিক রাজ্যের ক্যাশেড অনুলিপি ব্যবহার করার জন্য এটি কখনও কখনও কার্যকর পারফরম্যান্স অপটিমাইজেশন। মনে রাখবেন: পারফরম্যান্স অপটিমাইজেশনের প্রথম নিয়মটি "করবেন না"। এটি সমাধানে অতিরিক্ত জটিলতা যুক্ত করে এবং আপনার বাধ্যবাধকতাযুক্ত ব্যবসায়ের প্রেরণা না হওয়া পর্যন্ত আপনি এড়াতে পছন্দ করবেন।

যদি এটি হয় তবে স্কিমা পরিবর্তনের ফলে আপনার "লেখার" ডাটাবেসটিকে পুনর্নির্মাণের সময় ইভেন্ট স্টোরটি কি কেবল কার্যকর? নাকি আমি আরও বড় কিছু মিস করছি?

আপনি আরও বড় কিছু মিস করছেন।

প্রথম পয়েন্টটি হ'ল যদি আপনি কোনও ইভেন্টের উত্সাহিত সমাধানের বিষয়টি বিবেচনা করছেন তবে এটি হ'ল কারণ যা ঘটেছে তার ইতিহাস সংরক্ষণে আপনি সেখানে মূল্যবান মূল্য প্রত্যাশা করছেন, যার অর্থ এটি যে আপনি অ ধ্বংসাত্মক পরিবর্তন করতে চান ।

তাই আমরা ইভেন্ট স্টোরে আদৌ লিখছি।

বিশেষত, এর অর্থ হ'ল প্রতিটি পরিবর্তন ইভেন্ট স্টোরটিতে লেখা দরকার।

প্রতিদ্বন্দ্বী লেখকরা একে অপরের লেখাগুলি ধ্বংস করতে পারে বা একে অপরের সংস্থাগুলি সম্পর্কে অবগত না হলে সিস্টেমটিকে একটি অযাচিত অবস্থায় চালিত করতে পারে। সুতরাং যখন আপনার ধারাবাহিকতার প্রয়োজন হয় তখন স্বাভাবিক পদ্ধতির হ'ল আপনার লেখাগুলিকে জার্নালের একটি নির্দিষ্ট পজিশনে সম্বোধন করা (এইচটিটিপি এপিতে শর্তসাপেক্ষে পুটের অনুরূপ)। একটি ব্যর্থ লিখন লেখককে বলে যে জার্নাল সম্পর্কে তাদের বর্তমান বোঝাপড়াটি সিঙ্কের বাইরে, এবং তাদের পুনরুদ্ধার হওয়া উচিত।

একটি পরিচিত ভাল অবস্থানে ফিরে আসা এবং সেই বিন্দু থেকে যে কোনও অতিরিক্ত ইভেন্টের পুনরায় খেলানো একটি সাধারণ পুনরুদ্ধার কৌশল। স্থানীয় পরিচিতিতে যা রয়েছে তার অনুলিপি বা আপনার স্ন্যাপশট স্টোরের উপস্থাপনা হতে পারে সেই পরিচিত ভাল অবস্থানটি।

সুখী পথে আপনি মোটের স্ন্যাপশটকে স্মৃতিতে রাখতে পারেন; যখন কোনও স্থানীয় অনুলিপি উপলব্ধ না থাকে কেবল তখনই আপনাকে একটি বাহ্যিক দোকানে পৌঁছাতে হবে।

তদ্ব্যতীত, আপনার কাছে রেকর্ড বইয়ের অ্যাক্সেস থাকলে সম্পূর্ণরূপে ধরা পড়ার দরকার নেই ।

সুতরাং সাধারণ পদ্ধতির ( যদি স্ন্যাপশট সংগ্রহস্থল ব্যবহার করা হয়) তা এটিকে অবিচ্ছিন্নভাবে বজায় রাখা হয় । এইভাবে, আপনার যদি পুনরুদ্ধার করার প্রয়োজন হয়, আপনি সামগ্রীর পুরো ইতিহাস পুনরায় লোড এবং পুনরায় প্লে না করে এটি করতে পারেন।

এমন অনেকগুলি ক্ষেত্রে রয়েছে যেখানে এই জটিলতাটি আগ্রহী নয়, কারণ স্কোপড লাইফটাইমযুক্ত সূক্ষ্ম দানাযুক্ত সমষ্টিগুলি সাধারণত কোনও স্ন্যাপশট ক্যাশে বজায় রাখার ব্যয় ছাড়িয়ে যাওয়ার সুবিধার জন্য পর্যাপ্ত ইভেন্টগুলি সংগ্রহ করে না।

তবে যখন সমস্যাটির সঠিক হাতিয়ার হয় তখন লেখার মডেলটিতে সামগ্রিকভাবে বাসি উপস্থাপনা লোড করা হয়, তারপরে অতিরিক্ত ইভেন্টগুলির সাথে এটি আপডেট করা একেবারে যুক্তিযুক্ত জিনিস।


এই সব যুক্তিসঙ্গত মনে হয়। কিছুক্ষণ আগে আমি যখন ইএসের একটি ডামি বাস্তবায়ন নিয়ে ঘুরেছি তখন ধারাবাহিকতার গ্যারান্টি দিতে ইভেন্টস্টোরটি ব্যবহার করেছি তবে আপনি যেটিকে "স্ন্যাপশট সংগ্রহস্থল" বলছেন তাও আমি সমকালীনভাবে লিখেছি। এর অর্থ হ'ল বর্তমান অবস্থা ইভেন্টগুলি পুনরায় খেলানো ছাড়াই সবসময় পড়তে প্রস্তুত। আমি সন্দেহ করি এটি ভাল স্কেল করতে পারে না, তবে এটি কেবল একটি অনুশীলন যা আমি আপত্তি করি না।
মেটাফাইট

6

যেহেতু আপনি "লিখন" ডাটাবেসের উদ্দেশ্য কী হবে তা আপনি নির্দিষ্ট করেননি, তাই আমি এখানে ধরে নেব যে আপনি যা বোঝাতে চেয়েছেন তা হল: ইভেন্ট স্টোর থেকে সামগ্রিক পুনর্নির্মাণের পরিবর্তে কোনও সমষ্টিতে নতুন আপডেট নিবন্ধ করার সময় আপনি এটি "লিখুন" ডাটাবেস থেকে উত্তোলন করুন, পরিবর্তনটি বৈধ করুন এবং একটি ইভেন্ট জারি করুন।

যদি আপনি যা বোঝাতে চান এটি যদি এই হয়, তবে এই কৌশলটি অসঙ্গতির জন্য একটি শর্ত তৈরি করবে: শেষেরটির "লিখন" ডাটাবেসে তৈরি করার সুযোগ পাওয়ার আগে যদি কোনও নতুন আপডেট ঘটে, তবে নতুন আপডেটটি পুরানো ডেটার বিপরীতে বৈধতা অর্জন করবে, সুতরাং সম্ভাব্যভাবে একটি "অসম্ভব" (অর্থাত "অস্বীকৃত") ইভেন্ট জারি করা এবং সিস্টেমের অবস্থার ক্ষতি করা।

উদাহরণস্বরূপ, থিয়েটারে আসন বুকিংয়ের একটি স্থায়ী উদাহরণ বিবেচনা করুন। ডাবল বুকিং প্রতিরোধের জন্য, আপনাকে নিশ্চিত করতে হবে যে আসনটি বুক করা হচ্ছে তা ইতিমধ্যে নেওয়া হয়নি - এটিই আপনি "বৈধতা" বলছেন। এটি করার জন্য, আপনি "লেখুন" ডাটাবেসটিতে ইতিমধ্যে বুক করা আসনের একটি তালিকা সঞ্চয় করেন। তারপরে, যখন কোনও বুকিংয়ের অনুরোধ আসে, আপনি অনুরোধ করা আসনটি তালিকায় রয়েছে কিনা তা পরীক্ষা করে দেখুন এবং যদি তা না হয় তবে একটি "বুকড" ইভেন্ট জারি করুন, অন্যথায় একটি ত্রুটি বার্তার সাথে প্রতিক্রিয়া জানান। তারপরে আপনি একটি প্রক্ষেপণ প্রক্রিয়া চালান, যেখানে আপনি "বুকড" ইভেন্টগুলি শোনেন এবং বুক করা আসনগুলিকে "লিখন" ডাটাবেসের তালিকায় যুক্ত করুন।

সাধারণত, সিস্টেমটি এইভাবে কাজ করবে:

1. Request to book seat #1
2. Check in the "already booked" list: the list is empty.
3. Issue a "booked seat #1" event.
4. Projection process catches the event, adds seat #1 to the "already booked" list.
5. Another request to book seat #1.
6. Check in the list: the list contains seat #1
7. Respond with an error message.

তবে, কীভাবে অনুরোধগুলি খুব তাড়াতাড়ি উপস্থিত হয়, এবং পদক্ষেপ 4 ধাপের 4 এর আগে ঘটে?

1. Request to book seat #1
2. Check in the "already booked" list: the list is empty.
3. Issue a "booked seat #1" event.
4. Another request to book seat #1.
5. Check in the list: the list is still empty.
6. Issue another "booked seat #1" event.

এখন একই আসন বুকিংয়ের জন্য আপনার দুটি ইভেন্ট রয়েছে। সিস্টেমের অবস্থা দূষিত।

এটি যাতে না ঘটে তার জন্য, আপনাকে কখনই কোনও প্রজেকশনের বিরুদ্ধে আপডেটগুলি বৈধতা দেওয়া উচিত নয়। একটি আপডেট যাচাই করার জন্য, আপনি ইভেন্ট স্টোর থেকে সমষ্টিটি পুনর্নির্মাণ করেন, তারপরে আপডেটটির বিরুদ্ধে বৈধতা দিন। এর পরে, আপনি একটি ইভেন্ট ইস্যু করেন তবে আপনি স্টোর থেকে শেষবার পড়ার পরে কোনও নতুন ইভেন্ট জারি করা হয়নি তা নিশ্চিত করার জন্য টাইমস্ট্যাম্প গার্ড ব্যবহার করুন। যদি এটি ব্যর্থ হয়, আপনি কেবল আবার চেষ্টা করুন।

ইভেন্ট স্টোর থেকে সামগ্রিক পুনর্নির্মাণে পারফরম্যান্স পেনাল্টি বহন করতে পারে। এটি হ্রাস করতে, আপনি সরাসরি ইভেন্ট স্ট্রিমে স্ন্যাপশট তৈরি করা হয়েছিল তার আইডি সহ ট্যাগ করে মোট স্ন্যাপশট সংরক্ষণ করতে পারেন। এইভাবে, আপনি সাম্প্রতিক সময়ের স্রোত থেকে পুরো ইভেন্টের স্ট্রিমকে সর্বদা পুনরায় খেলানোর বিরোধী হিসাবে সর্বাধিক সাম্প্রতিক স্ন্যাপশট লোড করে এবং তার পরে আসা কেবলমাত্র ইভেন্টগুলি পুনরায় প্লে করে সামগ্রিক পুনর্নির্মাণ করতে পারেন।


আপনার উত্তরের জন্য ধন্যবাদ (এবং প্রতিক্রিয়া জানাতে এত দীর্ঘ সময় দেওয়ার জন্য দুঃখিত)। আপনি লেখার ডাটাবেসের বিরুদ্ধে বৈধতা দেওয়ার বিষয়ে যা বলছেন তা অবশ্যই সত্য নয়। আমি অন্য মন্তব্যে যেমন উল্লেখ করেছি, উদাহরণস্বরূপ ES প্রয়োগের সাথে আমি খেলছিলাম আমি আমার লেখার ডেটাবেস সিঙ্ক্রোনিকভাবে আপডেট করা নিশ্চিত করেছিলাম (এবং কনক্যুরঞ্জিআইডি / টাইমস্ট্যাম্প সঞ্চয় করে রেখেছি)। এটি আমাকে ইভেন্টস্টোর থেকে প্রস্তুত না করেই আশাবাদী সমঝোতা লঙ্ঘন সনাক্ত করতে দেয় allowed মঞ্জুর, একাকী লেখাগুলি একাই ডেটা দুর্নীতির বিরুদ্ধে রক্ষা করে না, তবে আমি একক-অ্যাক্সেস (একক থ্রেডযুক্ত )ও করছিলাম।
মেটাফাইট

সুতরাং, আমি আমার ধারাবাহিকতার সমস্যাগুলি সমাধান করেছি। যদিও, আমি ধরে নিয়েছি এটি স্কেল্যাবিলিটি ব্যয়ে।
মেটাফাইট

সিঙ্ক্রোনালি লেখার ডাটাবেজে লেখালেখি এখনও দুর্নীতির ঝুঁকি বহন করে: ইভেন্ট স্টোরের আপনার লেখা যদি সফল হয় তবে লেখার ডাটাবেজে আপনার লেখার ব্যর্থতা কী ঘটে?
ফায়োডর সোইকিন

1
যদি প্রজেকশন পড়তে ব্যর্থ হয় তবে এটি সফল না হওয়া পর্যন্ত এটি আবার চেষ্টা করবে। যদি এটি সরাসরি ক্র্যাশ হয় তবে এটি জেগে উঠেছে এবং যেখানে এটি ক্র্যাশ করেছে সেখান থেকে চালিয়ে যাবে - অন্য কথায়, আবার চেষ্টাও করুন। বাইরের পর্যবেক্ষণযোগ্য প্রভাবটি কিছুটা ধীর গতিতে চলার থেকে আলাদা হবে না। যদি অভিক্ষেপটি ধারাবাহিকভাবে ব্যর্থ এবং ব্যর্থ হয়, এর অর্থ এটিতে একটি বাগ রয়েছে এবং এটি স্থির করতে হবে। ফিক্সিংয়ের পরে, এটি শেষ ভাল অবস্থা থেকে আবার শুরু হবে। যদি বাগের ফলে পুরো পঠিত ডাটাবেসটি দূষিত হয়ে যায় তবে আমি ইভেন্টের ইতিহাস ব্যবহার করে স্ক্র্যাচ থেকে ডাটাবেসটি পুনরায় তৈরি করব।
ফায়োডর সোইকিন

1
কোনও ডেটা কখনও হারিয়ে যায় না, এটিই বড় বিষয়। কিছুক্ষণের জন্য ডেটা কোনও অসুবিধাগুলি (পড়ার জন্য) আকারে আটকে যেতে পারে তবে এটি কখনও হারিয়ে যায় না।
ফায়োডর সোইকিন

3

মূল কারণটি হচ্ছে পারফরম্যান্স। আপনি প্রতিটি কমিটের জন্য একটি স্ন্যাপশট সংরক্ষণ করতে পারেন (প্রতিশ্রুতি = একক কমান্ড দ্বারা উত্পন্ন ইভেন্টগুলি, সাধারণত কেবলমাত্র একটি ইভেন্ট) তবে এটি ব্যয়বহুল। স্ন্যাপশটের পাশাপাশি আপনার প্রতিশ্রুতিও সংরক্ষণ করতে হবে অন্যথায় এটি ইভেন্ট সোর্সিং হবে না। এবং এগুলি অবশ্যই পরমাণুভাবে করা উচিত, সমস্ত বা কিছুই নয়। আপনার প্রশ্নটি কেবল তখনই বৈধ যখন পৃথক ডাটাবেস / সারণী / সংগ্রহগুলি ব্যবহার করা হয় (অন্যথায় হুবহু ইভেন্ট সোর্সিং হবে) যাতে ধারাবাহিকতার গ্যারান্টি দিতে আপনাকে লেনদেনগুলি ব্যবহার করতে বাধ্য করা হয় । লেনদেনগুলি স্কেলযোগ্য নয়। একটি পরিশিষ্ট-কেবল ইভেন্ট স্ট্রিম (ইভেন্ট স্টোর) স্কেলাবিলিটির জননী।

দ্বিতীয় কারণ হ'ল সমষ্টিগত এনক্যাপসুলেশন। আপনার এটি রক্ষা করা দরকার এর অর্থ হ'ল সমষ্টিটি যে কোনও সময়ে তার অভ্যন্তরীণ উপস্থাপনা পরিবর্তন করতে মুক্ত হওয়া উচিত। আপনি যদি এটি সঞ্চয় করে থাকেন এবং এটির উপর নির্ভর করে তবে আপনার সংস্করণে খুব কঠিন সময় কাটাবেন, যা অবশ্যই ঘটবে। এমন পরিস্থিতিতে যখন আপনি স্ন্যাপশটটি কেবলমাত্র একটি অপ্টিমাইজেশন হিসাবে ব্যবহার করেন, যখন স্কিমা পরিবর্তন হয় আপনি কেবল সেই স্ন্যাপশটগুলিকে উপেক্ষা করেন ( কেবল ? আমি সত্যিই তা মনে করি না; ভাগ্য নির্ধারণ করে যে সমষ্টিটির স্কিমা পরিবর্তনগুলি - সমস্ত নেস্টেড সত্তা এবং মান অবজেক্ট সহ) - দক্ষ উপায় এবং পরিচালনা)।


যখন আমার সমষ্টিগত স্কিমা পরিবর্তন হয়, তখন কোনও আপডেট হওয়া "লিখন" ডাটাবেস উত্পন্ন করার জন্য আমার ইভেন্টগুলি পুনরায় খেলানো কি সাধারণ বিষয় হবে না?
মেটাফাইট

সমস্যাটি সেই পরিবর্তনটি সনাক্ত করছে। অনেকগুলি ফাইল / ক্লাস সহ একটি সমষ্টি খুব বড় হতে পারে।
কনস্টান্টিন গালবেনু

আমি বুঝতে পারছি না। পরিবর্তনটি একটি সফ্টওয়্যার রিলিজের সাথে ঘটবে। রিলিজটি সম্ভবত "লিখুন" ডাটাবেসটিকে নতুন করে তৈরি করতে একটি ডাটাবেস স্ক্রিপ্ট নিয়ে আসে।
মেটাফাইট

মাইগ্রেশন স্ক্রিপ্টের জন্য এটি অনেক কাজ। এটি চালানোর সময় অ্যাপটি অবশ্যই ডাউন হতে হবে।
কনস্টান্টিন গালবেনু

@ মেটাফাইট যদি স্ট্রিমটি খুব বড় হয় তবে নতুন সমষ্টিগত স্কিমাটি পুনর্নির্মাণে অনেক সময় লাগবে ... আমি এখন এমন একটি স্ন্যাপশট নিয়ে ভাবছি যা সরাসরি সম্প্রচারের একটি অবস্থা যা নতুন সমষ্টি প্রকাশের আগে চলতে পারে is স্কিমা
নারভালেক্স
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.