GH GambleHub

CQRS و خواندن/نوشتن جدایی

CQRS چیست

CQRS (Command Query Responsibility Segregation) یک رویکرد معماری است که مدل داده و اجزای مسئول نوشتن (دستورات) و خواندن (پرس و جو) را جدا می کند.
ایده: فرآیند تغییر حالت برای معاملات و معاملات معتبر و خواندن برای پیش بینی ها و مقیاس بندی سریع و هدفمند بهینه شده است.

key> دستورات وضعیت را تغییر داده و نتیجه عملیات را باز می گرداند. درخواست ها فقط خوانده می شوند و عوارض جانبی ندارند.


چرا به آن نیاز دارید

عملکرد خواندن: پیش بینی های تحقق یافته برای سناریوهای خاص (نوارها، گزارش ها، کاتالوگ ها).
ثبات مسیر بحرانی: ضبط جدا شده از «سنگین» می پیوندد و aggregates.
آزادی انتخاب ذخیره سازی: OLTP برای نوشتن، OLAP/cache/موتورهای جستجو برای خواندن.
تکامل سریع: اضافه کردن دیدگاه های جدید بدون خطر «شکستن» معاملات.
قابلیت مشاهده و حسابرسی (به ویژه در رابطه با Sourcing رویداد): بازیابی و پخش مجدد حالت آسان تر است.


چه زمانی باید (و چه زمانی نباید)

مناسب است اگر:
  • خواندن با برش داده های مختلف و تجمع پیچیده غالب است.
  • مسیر ضبط بحرانی باید ظریف و قابل پیش بینی باشد.
  • SLO/SLA های مختلف برای خواندن و نوشتن مورد نیاز است.
  • جداسازی منطق نوشتن دامنه از نیازهای تحلیلی/جستجو مورد نیاز است.
مناسب نیست اگر:
  • دامنه ساده است، بار کم است ؛ کپی های CRUD
  • سازگاری قوی بین خواندن و نوشتن برای همه سناریوها اجباری است.
  • تیم بی تجربه است و پیچیدگی عملیاتی غیر قابل قبول است.

مفاهیم پایه

Command-Intelligence to change state ('CreateOrder', 'CapturePayment'). ناورداها رو چک کن

داده های بازیابی پرس و جو ('GetOrderById'، 'ListUserTransactions'). عوارض جانبي نداره

مدل ضبط: aggregates/invariants/معاملات ؛ ذخیره سازی - گزارش رابطه/کلید/رویداد.
مدل خواندن (طرح ریزی): جداول/شاخص ها/حافظه پنهان تحقق یافته، به صورت ناهمزمان هماهنگ شده است.
سازگاری: اغلب بین ضبط و خواندن ؛ مسیرهای بحرانی - از طریق خواندن مستقیم از مدل نوشتن.


معماری (اسکلت)

1. Write-service: دستورات را می پذیرد، متغیر ها را تأیید می کند، تغییرات (پایگاه داده یا رویدادها) را ضبط می کند.
2. Outbox/CDC: تضمین انتشار واقعیت تغییرات.
3. پردازنده های پروجکشن: گوش دادن به رویدادها/CDC و به روز رسانی مدل های خواندن.
4. Read-service: نمایش داده شده از نماهای تحقق یافته/کش ها/جستجوها را ارائه می دهد.
5. Sagas/orchestration: هماهنگ کردن فرآیندهای متقابل.
6. قابلیت مشاهده: تاخیر پیش بینی، درصد برنامه های موفق، DLQ.


طراحی یک مدل ضبط

Aggregates: مرزهای معامله روشن (به عنوان مثال، «سفارش»، «پرداخت»، «تعادل کاربر»).
ثابت: رسمی (مقدار پولی ≥ 0، منحصر به فرد، محدودیت).
دستورات با کلید idempotent می شوند (به عنوان مثال «idempotency _ key»).
معاملات در محدوده کم هستند ؛ عوارض جانبی خارجی - از طریق صندوق پستی.

مثال فرمان (Pseudo-JSON)

json
{
"command": "CapturePayment",
"payment_id": "pay_123",
"amount": 1000,
"currency": "EUR",
"idempotency_key": "k-789",
"trace_id": "t-abc"
}

طراحی مدل خواندن

شروع از پرس و جو: چه صفحه نمایش/گزارش مورد نیاز است ؟

Denormalization قابل قبول است: مدل خواندن - «حافظه پنهان بهینه شده».
پیش بینی های مختلف برای وظایف مختلف: جستجو (OpenSearch)، گزارش (ذخیره سازی ستونی)، کارت (KV/Redis).
TTL و مونتاژ مجدد: پیش بینی ها باید بتوانند از منبع (پخش رویداد/عکس های فوری) بازیابی شوند.


ثبات و UX

سازگاری نهایی: رابط کاربری می تواند داده های قدیمی را برای مدت کوتاهی نمایش دهد.
الگوهای UX: «داده ها به روز می شوند»...، UI خوش بینانه، شاخص های هماهنگ سازی، مسدود کردن اقدامات خطرناک تا تأیید.
برای عملیاتی که نیاز به ثبات قوی دارند (به عنوان مثال، نشان دادن تعادل دقیق قبل از نوشتن)، به طور مستقیم از مدل نوشتن بخوانید.


CQRS و رویداد یافتن منابع (اختیاری)

Event Sourcing (ES) رویدادها را ذخیره می کند و وضعیت کل نتیجه کانولوشن آنها است.
بسته CQRS + ES یک حسابرسی ایده آل و بازسازی آسان پیش بینی ها را فراهم می کند، اما پیچیدگی را افزایش می دهد.
جایگزین: پایگاه داده منظم OLTP + outbox/CDC → پیش بینی ها.


تکرار: Outbox و CDC

Outbox (در یک معامله): نوشتن تغییرات دامنه + نوشتن یک رویداد به outbox ؛ ناشر به تایر تحویل می دهد.
CDC: خواندن از ورود به سیستم پایگاه داده (Debezium، و غیره) → تبدیل به رویدادهای دامنه.
ضمانت: به طور پیش فرض حداقل یک بار، مصرف کنندگان و پیش بینی ها باید بی نظیر باشند.


انتخاب ذخیره سازی

نوشتن: رابطه ای (PostgreSQL/MySQL) برای معاملات ؛ KV/Document - که در آن ناورداها ساده هستند.

خواندن:
  • KV/Redis - کارت ها و خواندن کلید سریع ؛
  • جستجو (OpenSearch/Elasticsearch) - جستجو/فیلترها/جنبه ها ؛
  • ستون (ClickHouse/BigQuery) - گزارش ها ؛
  • کش در CDN - دایرکتوری های عمومی/محتوا.

الگوهای ادغام

لایه API: نقاط پایانی/خدمات جداگانه برای «دستورات» و «پرس و جو».
Idempotency: کلید عملیات در هدر/بدن ؛ ذخیره سازی کلیدهای اخیر با TTL.
Sagas/orchestration: زمانبندی، جبران، تکرار گام.
Backpressure موازی بودن پردازنده های طرح ریزی را محدود می کند.


قابل مشاهده بودن

معیارهای نوشتن: تاخیر فرمان p95/99، درصد معاملات موفق، خطاهای اعتبار سنجی.
معیارهای خواندن: درخواست های p95/99، حافظه پنهان نرخ، بار در خوشه جستجو.
تاخیر پیش بینی (زمان و پیام)، نرخ DLQ، درصد deduplication.
Tracing: 'trace _ id' از دستور → outbox → the → query projection عبور میکند.


ایمنی و انطباق

تفکیک حقوق: حوزه های مختلف/نقش برای نوشتن و خواندن ؛ اصل کمترین امتیاز

PII/PCI: حداقل در پیش بینی ها ؛ رمزگذاری در حالت استراحت/پرواز ؛ ماسک زدن

حسابرسی: ثابت تیم، بازیگر، نتیجه، 'ردیابی _ id' ؛ بایگانی WORM برای حوزه های بحرانی (پرداخت، KYC).


تست کردن

تست قرارداد: برای دستورات (خطاها، ناورداها) و نمایش داده شد (فرمت/فیلتر).
تست های پیش بینی: مجموعه ای از رویدادها/CDC را ارسال کنید و مدل خواندن نهایی را بررسی کنید.
هرج و مرج/تاخیر: تزریق تاخیر به پردازنده های طرح ریزی ؛ UX چک در تاخیر.
قابلیت پخش: پیش بینی های مجدد در غرفه از عکس های فوری/ورود به سیستم.


مهاجرت و تکامل

زمینه های جدید - افزودنی در رویداد/CDC ؛ مدل های خوانده شده بازسازی می شوند.
هنگام طراحی مجدد مدارها، دوبار نوشتن کنید. پیش بینی های قدیمی را تا زمان تعویض نگه دارید.
نسخه بندی: 'v1 '/' v2' رویدادها و نقاط پایانی، برنامه غروب آفتاب.
پرچم ویژگی: معرفی نمایش داده شد جدید/پیش بینی در امتداد قناری.


ضد الگوهای

CQRS «به خاطر مد» در خدمات CRUD ساده است.
وابستگی خواندن و نوشتن همزمان سخت (انزوا و پایداری را می کشد).
یک شاخص برای همه: مخلوط کردن پرس و جو ناهمگن به یک فروشگاه خواندن.
پیش بینی ها idempotency → تکراری و اختلاف ندارد.
پیش بینی های غیر قابل بازیابی (بدون پخش/عکس های فوری).


نمونه هایی از دامنه ها

پرداخت (خدمات آنلاین)

نوشتن: «مجاز»، «ضبط»، «بازپرداخت» در پایگاه داده معامله ؛ صندوق پرداخت را منتشر می کند. '.

خواندن:
  • Redis «کارت پرداخت» برای UI ؛
  • ClickHouse برای گزارش ؛
  • OpenSearch برای جستجوی معاملات
  • مسیر بحرانی: مجوز ≤ 800 ms p95 ؛ خواندن سازگاری برای UI - نهایی (تا 2-3 ثانیه).

KYC ها

نوشتن: دستورات برای شروع/به روز رسانی وضعیت ؛ ذخیره سازی PII در یک پایگاه داده امن

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

ترازنامه (iGaming/Finance)

نوشتن: 'UserBalance' مجموع با افزایش اتمی/کاهش ؛ کلیدهای بی نظیر برای جراحی.
خوانده شده: کش برای «تعادل سریع» ؛ برای نوشتن کردن - خواندن مستقیم از نوشتن (قوام سخت).
حماسه: سپرده ها/نتیجه گیری ها با حوادث هماهنگ می شوند، در صورت شکست - جبران خسارت.


چک لیست پیاده سازی

  • aggregates و invariants از مدل نوشتن برجسته شده است.
  • پرس و جوهای کلیدی تعریف شده و پیش بینی ها برای آنها طراحی شده است.
  • Outbox/CDC و پردازنده های طرح ریزی idemotent پیکربندی شده اند.
  • یک برنامه snapshot/replay وجود دارد.
  • SLO: تاخیر فرمان، تاخیر طرح ریزی، در دسترس بودن خواندن/نوشتن به طور جداگانه.
  • حقوق دسترسی جداگانه و رمزگذاری داده ها اجرا شده است.
  • DLQ هشدار/تاخیر/deduplication شکست.
  • تست ها: قراردادها، پیش بینی ها، هرج و مرج، پخش مجدد.

سوالات متداول

آیا تامین منابع رویداد برای CQRS اجباری است ؟

نه، اينطور نيست شما می توانید بر روی یک پایگاه داده به طور منظم + outbox/CDC ساخت.

چگونه با desynchronization مقابله کنیم ؟

به صراحت UX را طراحی کنید، تاخیر طرح را اندازه گیری کنید، عملیات بحرانی را از نوشتن بخوانید.

آیا می توان هر دو نوشتن و خواندن را در همان سرویس حفظ کرد ؟

بله، جدایی فیزیکی اختیاری است ؛ تقسیم منطقی مسئولیت ها اجباری است.

معاملات بین aggregate ها چطور ؟

از طریق sagas و حوادث ؛ در صورت امکان از معاملات توزیع شده اجتناب کنید.


نتیجه گیری

CQRS دست ها را باز می کند: یک مسیر نوشتن نازک و قابل اعتماد با یکنواختی روشن و خواندن سریع و هدفمند از پیش بینی های تحقق یافته. این امر بهره وری را افزایش می دهد، تکامل را ساده تر می کند و سیستم را در برابر استرس مقاوم تر می کند - اگر سازگاری، مشاهده پذیری و مهاجرت منظم باشد.

Contact

با ما در تماس باشید

برای هرگونه سؤال یا نیاز به پشتیبانی با ما ارتباط بگیرید.ما همیشه آماده کمک هستیم!

شروع یکپارچه‌سازی

ایمیل — اجباری است. تلگرام یا واتساپ — اختیاری.

نام شما اختیاری
ایمیل اختیاری
موضوع اختیاری
پیام اختیاری
Telegram اختیاری
@
اگر تلگرام را وارد کنید — علاوه بر ایمیل، در تلگرام هم پاسخ می‌دهیم.
WhatsApp اختیاری
فرمت: کد کشور و شماره (برای مثال، +98XXXXXXXXXX).

با فشردن این دکمه، با پردازش داده‌های خود موافقت می‌کنید.