الگوی معماری CQRS

الگوی معماری CQRS

CQRS Design Pattern

CQRS یکی از الگوهای مهم هنگام پرس و جو بین میکروسرویس ها است. ما می توانیم از الگوی طراحی CQRS استفاده کنیم تا از پرس و جوهای پیچیده برای خلاص شدن از شر اتصالات ناکارآمد جلوگیری کنیم. CQRS مخفف Command and Query Responsibility Segregation می باشد. اساساً این الگو عملیات خواندن و به‌روزرسانی را برای یک پایگاه داده جدا می‌کند.
 
به طور معمول، در برنامه های یکپارچه، اکثر اوقات ما 1 پایگاه داده داریم و این پایگاه داده باید هم عملیات query و هم عملیات به روز رسانی را پاسخ دهد. این بدان معناست که یک پایگاه داده هم برای پرس و جوهای پیچیده کار می کند و هم عملیات CRUD را انجام می دهد. اما اگر برنامه پیچیده تر شود، این پرس و جو و عملیات CRUD نیز غیرقابل مدیریت خواهد بود.
به عنوان مثال خواندن پایگاه داده، اگر برنامه شما نیاز به پرس و جو داشته باشد که باید بیش از 10 جدول را بپیوندد، به دلیل تأخیر در محاسبه پرس و جو، پایگاه داده قفل می شود. همچنین اگر نوشتن پایگاه داده را مثال بزنیم، هنگام انجام عملیات CRUD نیاز به اعتبارسنجی پیچیده و پردازش منطق تجاری طولانی داریم، بنابراین این امر باعث قفل شدن عملیات پایگاه داده می شود.
 
CQRS استفاده از اصول "separation of concerns" و پایگاه داده خواندن و نوشتن پایگاه داده با 2 پایگاه داده را ارائه می دهد. به این ترتیب حتی می‌توانیم از پایگاه داده‌های مختلف برای خواندن و نوشتن انواع پایگاه داده مانند استفاده از no-sql برای خواندن و استفاده از پایگاه داده رابطه‌ای برای عملیات crud استفاده کنیم.

بنابراین می توان گفت که CQRS خواندن و نوشتن را در پایگاه داده های مختلف جدا می کند، Commands داده های به روز رسانی را انجام می دهد، Queries داده های خواندن را انجام می دهد.

 
معماری پایگاه داده اینستاگرام
 اینستاگرام اساسا از دو سیستم پایگاه داده استفاده می کند، یکی پایگاه داده رابطه ای PostgreSQL و دیگری پایگاه داده غیر رابطه ای  Cassandra.
 
بنابراین این بدان معناست که اینستاگرام از پایگاه داده غیر رابطه ای Cassandra برای استوری های کاربران استفاده می کند که داده های read-incentive هستند. و استفاده از پایگاه داده رابطه ای PostgreSQL برای به روز رسانی بیوگرافی اطلاعات کاربر. 
 
حالات مختلف معماری CQRS

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

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

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

 

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

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

 

چگونه پایگاه های داده را  در رویکرد Two-database با همگام کنیم؟
وقتی پایگاه های خواندن و نوشتن را در 2 پایگاه داده مختلف جدا می کنیم، توجه اصلی این است که این دو پایگاه داده را به روشی مناسب همگام سازی کنیم.
این را می توان با استفاده از Event Driven Architecture حل کرد. Event Driven Architecture، زمانی که چیزی در پایگاه‌داده نوشتن به‌روزرسانی می‌شود، یک رویداد به‌روزرسانی را با استفاده از سیستم‌های message broker منتشر می‌کند و این امر توسط read database اجرا می‌شود و داده‌ها را مطابق آخرین تغییرات همگام‌سازی می‌کند.


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

در اینجا است که Event Sourcing pattern به کار ما می آید.

 

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

نویسنده :
مجید پورداود
  • مجید پورداود
  • مهندس نرم افزار و تحلیلگر ارشد سیستم های کامپیوتری تحت وب می باشم. از سال 1395 برنامه نویسی را شروع کردم و به زبان های php (فریم ورک laravel -codeigniter)  و زبان جاوا اسکریپت (فریم ورک express.js-nest.js)  تسلط دارم.  

ثبت دیدگاه جدید

0 دیدگاه

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *