مرا اسکن کن!

معماری CQRS چیست

معماری CQRS چیست



در سالهای گذشته با پیشرفت های تکنولوژی کم کم تیمهای فنی به استفاده از الگوهای برنامه نویسی روز روی آورده اند و سعی میکنند از الگوهایی استفاده کنند که کارایی بهتری برای نرم افزارشان داشته باشد.

یکی از این الگوها (CQRS (Command Query Responsibility Segregation میباشد.

CQRS مخفف Command Query Responsibility Segregation هست به معنی تفکیک مسئولیت پرسش و فرمان

CQRS که اولین بار توسط آقای Greg Young مطرح گردید، از این اصل برای تعریف یک الگوی ساده استفاده می کند. پیاده سازی این الگو باعث می شود تا بسیاری از دغدغه های معماری نرم افزار (مانند انعطاف پذیری، مقیاس پذیری، تمرکز کامل بر فرآیندهای Domain و.. ) را برطرف کنید.

 

الگوی CQRS چیست ؟

 


 

مفاهیم Command and Query

کامندها دستوراتی هستند که چیزی را برنمیگردانند و هدف اصلی آنها درج ، ویرایش و حذف میباشد اما کوئری ها دستوراتی هستند که در خروجی خود دیتاست برمیگرداند و برای گرفتن اطلاعات از دیتابیس استفاده میشود.

مسیر اصلی CQRS

اصلی ترین ایده ی پشت این الگو جدا کردن command و query ها میباشد.

تمام نرم افزارهایی در تلاش برای تعامل با یک سیستم اطلاعاتی و برخورداری از سیستم ذخیره سازی با CRUD (Create,Read,Update,Delete) هستند ، به بیان ساده تر در تمامی سیستم ها مدل هایی وجود دارند که میخواهیم در آن اطلاعات جدید اضافه کنیم ، اطلاعات قبلی را بخوانیم،اطلاعات قبلی رو ویرایش کنیم و یا آنها را حذف کنیم.

یک مثال ساده

فرض کنید یک در حال طراحی یک سیستم فروشگاهی هستید.ساختار دیتابیس یک فروشگاه پر از ارتباط است؛ هر محصول میتواند گروه داشته باشد،میتواند تعداد زیادی خاصیت و صفت داشته باشد،میتواند در سبد خرید تعداد زیادی کاربر باشد و خیلی چیزهای دیگر.

در این نوع سیستم ما به دلیل ساختار رابطه ای سیستم بهترین روش برای ذخیره سازی داده استفاده از دیتابیس های رابطه ای مانند Sql Server ، MySql میباشد.

همچنین در هنگام واکشی اطلاعات به دلیل خاصیت های زیادی که هر محصول میتواند داشته باشد و بزرگ بودن آبجکت مورد نیاز بهترین راه حل استفاده از دیتابیسهای NoSqlمثل MongoDbمیباشد.

با این شرایط راه حل چیست؟؟

در چنین پروژه ای شما میباسیت از الگوی CQRS استفاده کنید.

در این سیستم فروشگاهی لایه ی Repository را به دو بخش کلی تقسیم میکنیم که یه بخش شامل Command ها و بخش دیگر شامل Query ها میباشد که تمامی متد ها را بر اساس نوع آنها جدا میکند.زمانیکه اطلاعات در دیتابیس رابطه ای درج،ویرایش یا حذف میشود یه سرویس که اصطلاحا به آن Service Bus میگویند داده های درج شده در دیتابیس رابطه ای را پردازش میکند و آبجکت پیچیده ای که زمان واکشی داده نیاز داریم را به صورت آماده در دیتابیس NoSql ذخیر میکند.در این حالت شما در زمان واکشی داده برای دریافت داده نیاز به دستورات سخت و پیچیده ندارید،همچنین سرعت واکشی داده به دلیل از پیش پردازش شدن به شدت کاهش میابد.

 

 

به صورت عام، functionality اکثر پروژه‌های نرم افزاری تجاری خلاصه میشود به مخفف معروفی به نام CRUD (Create,Read,Update,Delete) ، که object‌ها را میسازیم، آن‌ها را میخوانیم و تغییر میدهیم.

اپلیکیشن‌های طراحی شده بدین صورت، قابلیت خوانایی بالایی خواهند داشت و دیاگرام طراحی آنها چیزی شبیه به تصویر زیر میباشد

در واقع ما یک سیستمی داریم که شامل مدلی است از دیتا‌های ما و از این مدل برای کوئری گرفتن از دیتابیس استفاده میشود، که البته برای بیشتر پروژه‌های نرم افزاری، معماری درست و ترجیح داده شده‌ای هم میباشد.

زمانیکه نیاز‌های پروژه روز به روز افزورده و پیچیده‌تر میشود، مدل CRUD بصورت پیوسته از ارزشش کاسته میشود و از آن سادگی اولیه‌ی در درک و خوانایی آن دور خواهد شد.

ذات CQRS بر آن است که شما مدل‌های مختلفی را برای خواندن و نوشتن دیتا داشته باشید. الگوی آن چیزی شبیه به تصویر زیر است

چیزی که در این روش مشهود است این میباشد که برنامه نویسان باید قسمت‌های Command و Query را به صورت جداگانه طراحی نمایند.

CQRS این قابلیت را به شما میدهد که interface و Datastore و حتی بطور کامل Technology مجزایی در قسمت‌های CQ داشته باشید.

 

پیاده سازی معماری CQRS

در این معماری نرم افزار به دو بخش خواندن (Read Side) و بخش نوشتن (Write Side) تقسیم می شود. اشیاء موجود در بخش خواندن تنها مسئول خواندن و بازیابی اطلاعات از دیتابیس بوده و اشیاء موجود در بخش نوشتن، تنها مسئول اجرای Command های دریافتی می باشند. در اغلب سیستم های اطلاعاتی تعداد خواندن اطلاعات از نرم افزار بسیار بیشتر از تعداد نوشتن است. جداسازی این دو بخش شما را قادر می سازد که بر روی هر بخش به طور مستقل و جداگانه کار کنید و پیاده سازی هر کدام را بنا بر نیاز آن انجام دهید. برای مثال هنگام خواندن اطلاعات می توانید از یک پایگاه داده نرمال نشده جهت افزایش سرعت استفاده نمایید و یا نوشتن اطلاعات را در یک پایگاه داده ی NoSQL انجام دهید.
معماری CQRS یا به اصطلاح " تفکیک مسئولیت های نوشتن و خواندن (بر روی دیتابیس) " مفهوم تقسیم را در سطح معماری گسترش می دهد. اما این معماری، به عنوان یک معماری کلی برای یک سیستم نرم افزاری تعریف نمی شود.
همان طور که قبلاً به آن اشاره کردیم با جدا کردن عملیات های خواندن و نوشتن بر روی یک سیستم، می-توانیم سرعت عملکرد آن را افزایش دهیم و از اصل تفکیک نگرانی ها (Separation of Concerns principle) در سیستم های خود پشتیبانی کنیم.


در ادامه به توضیح حالات مختلف این معماری می پردازیم.

معماری CQRS با یک دیتابیس

در این معماری هر دو طرف در حال گفتگو با یک دیتابیس هستند.
از یک دیتابیس رابطه ای یا غیر رابطه ای استفاده می شود.کامندها از دامین برای تغییر وضعیت استفاده می کنند و نتیجه را از طریق لایه persistence در دیتابیس ذخیره می کنند که در php معمولا از یک ORM مثل Eloquent یاDoctrine استفاده می شود.
کوئری ها به طور مستقیم به وسیله یک لایه سبک یعنی data access، به دیتابیس وصل شده و به کمک مکانیزم هایی مثل linq یا اسکریپت های SQL یا حتی strored procedure دیتا را از دیتابیس دریافت می کنند.
این نوع CQRS که از یک دیتابیس استفاده می کند ساده ترین نوع است.

معماری CQRS به کمک دو دیتابیس

در رویکرد Two-database، ما دو پایگاه داده اختصاصی داریم ، یکی برای ذخیره اطلاعات و دیگری برای خواندن آن ها. بخش Commands برای عملیات نوشتن، پایگاه داده نوشتن را بهینه کرده و بخش Queries، پایگاه داده خواندن را برای انجام عملیات خواندن بهینه کرده است.

با هر تغییر وضعیت توسط بخش Commands ، داده های اصلاح شده بعد از نوشته شدن در دیتابیس نوشتن (Write Database) باید به دیتابیس خواندن (Read Database) فرستاده شده تا با استفاده از یک الگوی منسجم و هماهنگ در هر دو پایگاه داده ذخیره شود.
این معماری باعث بهبود عملکرد نرم افزار در قسمت جستجوهای یک نرم افزار می شود و این موضوع را می توان به عنوان یک نکته مثبت تلقی کرد زیرا کاربران یک نرم افزار معمولاً بیشتر از نوشتن، وقت خود را با خواندن داده ها می گذرانند.


معماری CQRS با استفاده از روش event-sourcing

این پیچیده ترین معماری CQRS است. روش event-sourcing (منبع یابی رویدادی) کاملاً متفاوت از ذخیره سازی داده ها نسبت به دو معماری است که قبلاً ارائه شده است.
در این حالت ما وضعیت فعلی entityها را در یک دیتابیس نرمالایز شده ذخیره نمی ‌کنیم. ما فقط تغییرات entity ها را در طول زمان ذخیره می کنیم. تاریخچه ای از تغییرات را خواهیم داشت که به آن event store می گوییم. می توانیم با مکانیزمی وضعیت فعلی هر entity را در اختیار داشته باشیم.
این روش به ما کمک بزرگی می کند تا وضعیت یک object را در گذشته به راحتی پیدا کنیم و از آن می توان به عنوان یک Logger نیز استفاده نمود چون جزء به جزء تغییراتِ وضعیت سیستم، در آن ثبت شده است. از آنجایی که دیتا به صورت سریالایز شده ذخیره می شود، بارگذاری آن نیز با سرعت بالایی انجام خواهد شد. این حالت پیچیده ترین نوع CQRS است، ولی بهینه ترین می باشد.
نکته : در این روش فقط می توانیم Eventهای جدیدی به دیتابیس خود اضافه کنیم و قادر به ویرایش و حذف Eventها نیستیم.

استفاده از این روش مزایای زیادی را به همراه دارد که برخی از آن ها عبارتند از :
- داشتن مجموعه ای از تمامی وضعیت های مختلف یک موجودیت که می تواند در پروژه هایی که اهمیت تغییر داده ها زیاد است، به کار بیاید.
- دیگر نیازی به لایه ORM برای ذخیره سازی اطلاعات نیست.
- می توانیم وضعیت هر موجودیتی را در هر برهه از زمان بازسازی کنیم. این کار برای رفع اشکال (Debugging) بسیار مفید است.
- خطایابی سیستمی که در حال کار است، با تکرار رخدادهایی که منجر به خطا شده اند، آسان می شود.
- جهت بازیابی اطلاعات می توانیم بیش از یک دیتابیس داشته باشیم .

نکته :

از آنجایی که استفاده از هر معماری در کنار نکات و مزایا، معایبی هم دارد لذا به توضیح برخی از معایب آن می¬ پردازیم :
- با وجود این جداسازی بین کوئری و کامند، پیچیدگی نرم افزار زیاد می شود.
- اگر از حالت دو دیتابیس استفاده کنیم، پیچیدگی درسمت دیتابیس بیشتر می شود.
- اگر از حالت سوم یعنی event-sourcing استفاده کنیم، هزینه و نگهداری بیشتری خواهیم داشت.

پرس و جو ها (Queries) نباید هیچ گاه تغیری در پایگاه داده بدهند.

 


نوشته شده توسط :

وحید صمدیان وحید صمدیان



یکشنبه, 13 تیر 1400

تعداد بازديد : 1095

برچسب ها : معماری نرم افزار

3.0 ستاره