آموزش Event Sourcing بخش هشتم
آیا Eventها را میتوانم تغییر دهم یا حذف کنم؟
مطالب آموزشی Event Sourcing:
- بخش اول مقدمهای بر Event Sourcing
- بخش دوم آشنایی مقدماتی با ساختار داخلی Event Store
- مقایسه رویکردهای State-Oriented و State-Transition
- مزیتهای Event Sourcing
- سلام به دنیا به روش Event Sourcing
- سلام به دنیا به روش Event Sourcing-بخش دوم
- بخش هفتم Projection
- ویرایش event ها در EventSourcing
- Message، Command یا Event، کدوم رو انتخاب کنم؟
- مقدمه
همانطور که در پستهای قبلی بیان شد در رویکرد Event Sourcing، ما لاگی از تمام تغییرات رخداده در سیستم را نگه میداریم. وضعیت جاری(آخرین وضعیت) سیستم با اعمال این eventها به ترتیب وقوعشان از آغاز بدست میآید. داشتن یک لاگ از تمامی تغییرات بوقوع پیوسته در دومین میتواند مزیتهای بسیار مهمی برای ما به ارمغان داشته باشد، مانند قابلیت auditing، قابلیت مقیاسپذیری و مقاومت در برابر خطاها.
باید توجه داشت که این قابلیتهای مهم بر پایه یکی از اصول کلیدی Event Sourcing، یعنی پایبندی به عدم تغییر eventهای رکورد شده در event stream استوار است. به بیان دیگر eventها باید immutable باشند. به این معنی که پس از ذخیره event، آن را نمیتوان تغییر یا حذف کرد. اصلاح رویدادها این اصل را نقض میکند و سلامت لاگ رویداد را به خطر میاندازد.
هر event که در یک stream ذخیره شده است، در اصل یک حقیقت یا fact رخداده شده در سیستم را ریکورد کرده است. طبیعی است که ما هیچوقت نباید یک fact اتفاق افتاده در زمان گذشته را در ویرایش یا حذف کنیم.
فرض کنید مبلغ ۵۰ دلار به حساب مسعود بهرامی به اشتباه واریز شده است. این حقیقت که ۵۰ دلار به حساب مسعود بهرامی واریز شده است، را نمیتوان تنها با ویرایش کردن event آن و تغییر ۵۰ دلار به ۰ دلار تغییر داد. در چنین شرایطی ما یک event دیگر را به سیستم اضافه میکنیم که وظیفه آن تصحیح event اشتباه مورد نظر است.
.چرا نباید event را ویرایش یا حذف کرد؟
ما در Event Sourcing تنها به نگهداشت اخرین وضعیت هر resource در سیستم بسنده نمیکنیم. در عوض تمامی تغییرات وضعیتهای آن ریسورس از روز اول همگی نگه داشته میشود. هر بخش از سیستم به فراخور نیازمندی خود میتواند از این تغییر وضعیتها استفاده کند. به عنوان مثال یک پروجکتور میتواند eventهای یک استریم را دریافت کند و یک representation جدید از یک resource را در سیستم برای ما ایجاد کند(این موضوع در پست قبلی مفصلتر مورد بحث قرار گرفت). حالا اگر ما از وسط ایونتهای موجود در این فایل لاگ چیزی را به هر دلیل ویرایش و در سناریوی بدتر حذف کنیم ممکن است دچار مشکلات جدی شویم. در ادامه به برخی از این مشکلات اشاره خواهم کرد.
یکپارچگی سیستم
یکی از مهمترین مشکلات و چالشهای پیش رو در ویرایش یا حذف یک event به خطر افتادن جدی یکپارچگی سیستم است(اگر نگوییم از بین رفتن). فرض کنید در یک سیستم مدیریت رویداد، ما یک رویداد را ثبت و پابلیش کردیم. سپس افراد علاقمند در آن رویداد ثبتنام کرده باشند.
اگر بر روی event اول زوم کنیم، payload همراه event چیزی شبیه تصویر زیر است.
رویداد با همین اطلاعات بر روی سایت و سایر شبکههای اجتماعی پابلیش شده است. ماژول اطلاع رسانی، بر اساس این رویداد، به افرادی که در رویداد ثبتنام کردهاند ایمیلی حاوی اطلاعات این رویداد است. پیامکی که برای شرکتکنندگان ارسال میگردد نیز شامل اطلاعات موجود در این event است. حال فرض کنید بصورت دستی این event را تغییر دهیم. به عنوان مثال نام رویداد را به Painting تغییر دهیم. به راحتی میتوانید تصور کنید که چه اتفاقی خواهد افتاد. اطلاعات رویداد بر روی سایت هنوز با نام DDD and ES موجود میباشد. به هیچکدام از شرکتکنندگان نیز اطلاع رسانی تغییر رویداد ارسال نخواهد شد. دلیل این امر این است که event مربوط آن را تغییر دادیم، قبلا پردازش شده و سایر ماژولهای سیستم با تغییر دستی آن توسط ما خبردار نخواهند شد.
Auditability
Immutable بودن eventها و پایبند بودن به این immutability به ما یک دنبالهی شفاف و قابل اتکا و اطمینان از تمامی تغییرات رخداده در دامنه برنامه را میدهد. از این دنبالهی تغییرات برای موارد مختلفی از جمله دیباگ کردن سیستم، حسابرسی سیستم و … میتوان استفاده کرد. بدیهی است که در صورتی که ما این امکان و اجازه را داشته باشیم eventهای موجود در event store را ویرایش یا حذف کنیم، این اطمینان کاملا متزلزل خواهد شد.
مثلا به مثال ارائه شده در بالا میتوان اشاره کرد. شما دیگر نمیتواند مطمئن باشید که آیا رویداد رجیستر شده با مشخصاتی که در event، An event is registered وجود دارد، واقعا همان اطلاعاتی است که کاربر موقع ثبت رویداد وارد کرده است، یا اینکه این اطلاعات بعدا به هر دلیلی تغییر کرده است.
مقیاس پذیری
Immutable بودن eventها مزایای دیگری نیز میتواند برای ما به ارمغان داشته باشد. یکی از این مزیتها این است که مکانیزم ذخیره سازی eventها میتواند به سادگی یک فایل لاگ با خاصیت append-only باشد. از آنجا که مطمئن هستیم هیچ event تغییری نمیکند میتوانیم به راحتی eventها جدید را به انتهای این لاگ اضافه کنیم. این بدین معنی است که میتوانیم از سختافزارهای تخصصی نیز برای اینکار استفاده کنیم. storageها WORM مشخصا برای همچین سناریوهایی طراحی شدهاند. مزیت دیگر این است که میتوانیم اطلاعات را به راحتی cache کنیم. مشکل اساسی با cache اپدیت شدن اطلاعاتی است که cache کردیم. فرض کنیم اطلاعات ایونت رو cache کردیم. حال اگر این event توسط کاربر در دیتابیس ویرایش شود، باید cache نیز بروز رسانی شود. با immutable کردن eventها میتوانیم این چالش رو به راحتی برطرف کنیم، چون مطمئن خواهیم شد که event که cache کردهایم هیچوقت تغییر نخواهد کرد.
مقاومت در برابر خطاها
عدم قابلیت تغییر رویدادها، مقاومت بهتری در برابر خطاهای سیستم فراهم میکند. در صورت بروز خطا یا کرش سیستم، میتوان لاگ رویداد را اجرا کرد تا سیستم به وضعیت قبلی بازگردانده شود.
پایان بخش هشتم