CQRS va oʻqish/yozish
CQRS nima
CQRS (Command Query Responsibility Segregation) - ma’lumotlar modeli va yozish (commands) va o’qish (queries) uchun mas’ul bo’lgan komponentlarni ajratuvchi arxitektura yondashuvi.
G’oya: holatni o’zgartirish jarayoni valid invariantlar va tranzaksiyalarga, o’qish esa tezkor, maqsadli proyeksiyalar va masshtablarga moslashtiriladi.
Bu nima uchun kerak?
O’qish unumdorligi: aniq stsenariylar (lentalar, hisobotlar, kataloglar) uchun materiallashtirilgan proyeksiyalar.
Kritik yo’lning barqarorligi: yozuv «og’ir» joinlar va agregatlardan ajratilgan.
Omborni tanlash erkinligi: Yozish uchun OLTP, oʻqish uchun OLAP/kesh/qidirish dvigatellari.
Tezlashtirilgan evolyutsiya: tranzaksiyalarni «sindirish» xavfisiz yangi tushunchalarni qo’shing.
Kuzatish va audit (ayniqsa Event Sourcing bilan birga): holatni tiklash va ortiqcha o’ynash osonroq.
Qachon qoʻllash (va boʻlmaganda)
Quyidagi hollarda mos keladi:- Turli xil maʼlumotlar kesimlari va murakkab agregatsiyali oʻqishlar ustunlik qiladi.
- Tanqidiy yozuv yo’li nozik va oldindan aytib bo’ladigan bo’lishi kerak.
- Oʻqish va yozish uchun turli SLO/SLA kerak.
- Domen mantiqini analitik/qidiruv ehtiyojlaridan ajratish talab etiladi.
- Domen oddiy, yuklamasi past; CRUD bajarmoqda.
- Oʻqish va yozish oʻrtasidagi kuchli muvofiqlik barcha ssenariylar uchun majburiydir.
- Jamoa tajribasiz, operatsion murakkablik esa qabul qilinishi mumkin emas.
Asosiy tushunchalar
Buyruq (Command): holatni oʻzgartirish niyati (’CreateOrder’,’CapturePayment’). Invariantlarni tekshiradi.
Soʻrov (Query): maʼlumot olish (’GetOrderById’,’ListUserTransactions’). Hech qanday nojo’ya ta’sirlarsiz.
Yozuv modeli: agregatlar/invariantlar/tranzaksiyalar; saqlash - relyasion/kalit-qiymat/hodisa log.
O’qish (proyeksiya) modeli: materiallashtirilgan jadvallar/indekslar/keshlar asinxron tarzda sinxronlashtiriladi.
Moslik: ko’pincha yozish va o’qish o’rtasida eventual; tanqidiy yo’llar - write modelidan to’g’ridan-to’g’ri o’qish orqali.
Arxitektura (skelet)
1. Write-servis: buyruqlarni qabul qiladi, invariantlarni tasdiqlaydi, oʻzgarishlarni qayd etadi (DB yoki hodisalar).
2. Outbox/CDC: oʻzgarishlarni kafolatlangan tarzda eʼlon qilish.
3. Proyeksiya protsessorlari :/CDC voqealarini tinglash va o’qish modellarini yangilash.
4. Read-servis: materiallashtirilgan tasavvurlar/keshlar/qidiruv queries xizmat ko’rsatadi.
5. Sage/orkestr: kross-agregat jarayonlarini muvofiqlashtiradi.
6. Kuzatish darajasi: lag proyeksiyalar, muvaffaqiyatli qo’llanishlar foizi, DLQ.
Yozuv modelini loyihalash
Agregatlar: tranzaksiyalarning aniq chegaralari (masalan,’Order’,’Payment’,’UserBalance’).
Invariantlar: rasmiylashtiring (pul summalari ≥ 0, noyoblik, limitlar).
Buyruqlar kalit boʻyicha idempotentdir (masalan,’idempotency _ key’).
Tranzaksiyalar qamrovi bo’yicha minimal; tashqi nojo’ya ta’sirlar - outbox orqali.
Jamoa namunasi (psevdo-JSON)
json
{
"command": "CapturePayment",
"payment_id": "pay_123",
"amount": 1000,
"currency": "EUR",
"idempotency_key": "k-789",
"trace_id": "t-abc"
}
Oʻqish modelini loyihalash
Qanday ekranlar/hisobotlar kerak?
Denormalizatsiyaga yo’l qo’yiladi: o’qish modeli - «optimallashtirilgan kesh».
Turli vazifalar uchun bir nechta proyeksiyalar: qidirish (OpenSearch), hisobotlar (kolonnali saqlash), kartochkalar (KV/Redis).
TTL va qayta yig’ish: proyeksiyalar manbadan tiklanishi kerak (voqealar/snapshotlar).
Muvofiqlik va UX
Eventual consistency: interfeys eski maʼlumotlarni qisqa vaqt ichida koʻrsatishi mumkin.
UX-patternlar: «ma’lumotlar yangilanmoqda»..., optimistik UI, sinxronlashtirish indikatorlari, tasdiqlangunga qadar xavfli harakatlarni blokirovka qilish.
Kuchli muvofiqlikni talab qiladigan operatsiyalar uchun (masalan, hisobdan chiqarishdan oldin aniq balansni ko’rsatish) to’g’ridan-to’g’ri write-modeldan o’qing.
CQRS va Event Sourcing (xohishiga ko’ra)
Event Sourcing (ES) hodisalarni saqlaydi, agregatning holati esa ularni oʻrash natijasidir.
CQRS + ES to’plami mukammal audit va loyihalarni oson qayta yig’ish imkonini beradi, ammo murakkablikni oshiradi.
Muqobil: oddiy OLTP-DB + outbox/CDC → proyeksiyalari.
Replikatsiya: Outbox va CDC
Outbox (bitta tranzaksiyada): domen oʻzgarishlarini yozish + hodisani outboxga yozish; jamoatchi shinaga yetkazadi.
CDC: DB (Debezium va h.k.) dan domen hodisalariga aylantirish.
Kafolatlar: andoza at-least-once, iste’molchilar va proyeksiyalar idempotent bo’lishi kerak.
Saqlovchilarni tanlash
Write: tranzaksiyalar uchun relyasion (PostgreSQL/MySQL); KV/Document - bu yerda invariantlar oddiy.
Read:- KV/Redis - kartochkalar va tezkor asosiy o’qishlar;
- Qidirish (OpenSearch/Elasticsearch) - qidirish/filtrlar/fasetlar;
- Kolonnalar (ClickHouse/BigQuery) - hisobotlar;
- CDN uchun kesh - ommaviy kataloglar/kontent.
Integratsiya patternlari
API qatlami:’commands’va’queries’uchun alohida endpointlar/xizmatlar.
Idempotentlik: sarlavha/tanadagi operatsiya kaliti; TTL bilan recent-keys saqlash.
Saga/orkestr: taym-autlar, kompensatsiyalar, qadamlarning takrorlanishi.
Backpressure: proyeksiya protsessorlarining parallelligini cheklash.
Kuzatish
write metrikasi: p95/99 latentlik buyruqlari, muvaffaqiyatli tranzaksiyalar ulushi, validatsiya xatolari.
O’qish metrikasi: p95/99 so’rovlar, hit-rate kesh, qidiruv klasteriga yuk.
Prognozlar lag’i (vaqt va xabarlar), DLQ stavkasi, deduplikatsiyalar foizi.
Treysing:’trace _ id’buyrug’i orqali o’tadi → outbox → proyeksiya → query.
Xavfsizlik va komplayens
Huquqlarni ajratish: yozish va oʻqish uchun turli scopes/rollar; eng kam imtiyozlar prinsipi.
PII/PCI: proyeksiyalarda minimallashtiring; at-rest/in-flight shifrlash; kamuflyaj qilish.
Audit: buyruq, aktyor, natija,’trace _ id’; Kritik domenlar uchun WORM arxivlari (to’lovlar, KYC).
Test oʻtkazish
Contract tests: buyruqlar (xatolar, invariantlar) va queries (formatlar/filtrlar) uchun.
Projection tests: Hodisalar/CDC seriyasini koʻrsating va yakuniy oʻqish modelini tekshiring.
Chaos/latency: proyeksiya protsessorlariga kechikishlarni injeksiya qilish; lagdagi UX tekshiruvi.
Replayability: snapshot/logdan stenddagi proyeksiyalarni qayta yig’ish.
Migratsiya va evolyutsiya
Yangi maydonlar - hodisa/CDC uchun qoʻshimcha; read-modellar qayta yig’iladi.
Sxemalarni tahrirlashda ikki marta yozish (dual-write); eski proyeksiyalarni almashtirishdan oldin saqlaymiz.
’v1 ’/’ v2’ voqealari va endpointlarini versiya qilish, Sunset-reja.
Feature flags: Yangi queries/kanareyk proyeksiyalarini kiritish.
Antipatternlar
CQRS oddiy CRUD xizmatlarida «moda uchun».
O’qishning yozuvga qattiq sinxron bog’liqligi (izolyatsiya va barqarorlikni o’ldiradi).
Hamma narsaga bitta indeks: bir xil so’rovlarni bitta read-store-ga aralashtirish.
Proyeksiyalarda idempotentlik yo’q → dubli va tafovutlar.
Qayta tiklanmaydigan proyeksiyalar (replay/snapshotlar yoʻq).
Domen namunalari
To’lovlar (onlayn-servis)
Write: «Authorize», «Capture», «Refund» tranzaksion DBda; outbox’payment’ni eʼlon qiladi.
Read:- Redis UI uchun «to’lov kartochkasi»;
- hisobotlar uchun ClickHouse;
- Tranzaksiyalarni qidirish uchun OpenSearch.
- Kritik yo’l: avtorizatsiya ≤ 800 ms p95; UI uchun o’qish muvofiqligi - eventual (2-3 s gacha).
KYC
Write: startga/yangilanishga buyruqlar; PIIni himoyalangan DBda saqlash.
O’qish: PIIsiz maqomlarning engillashtirilgan proyeksiyasi; PII zarurat bo’lganda nuqtaga tortiladi.
Xavfsizlik: maqom oʻqish va hujjatlarga kirish uchun turli xil scopes.
Balanslar (iGaming/moliya)
Write: atom inkrementlari/dekrementlari bo’lgan’UserBalance’agregati; operatsiya uchun idempotent kalitlar.
O’qish: «tezkor balans» uchun kesh; hisobdan chiqarish uchun - write (qat’iy muvofiqlik) dan to’g «ridan to’g» ri o’qish.
Saga: depozitlar/xulosalar voqealar bilan muvofiqlashtiriladi, uzilishlar - kompensatsiyalar.
Joriy etish chek-varaqasi
- Write modelining agregatlari va invariantlari ajratilgan.
- Asosiy queries aniqlandi va ular uchun loyihalashtirilgan proyeksiyalar.
- outbox/CDC va idempotent proyeksiya protsessorlari moslashtirilgan.
- Proyeksiyalarni qayta yigʻish rejasi mavjud (snapshot/replay).
- SLO: jamoalarning yashirligi, prognozlar orqasi, alohida-alohida read/write mavjudligi.
- Foydalanish huquqi ajratilgan va maʼlumotlarni shifrlash amalga oshirilgan.
- DLQ/lag/deduplikatsiya muvaffaqiyatsizliklariga alertlar.
- Testlar: kontraktlar, proyeksiyalar, xaos, gaplar.
FAQ
CQRS uchun Event Sourcing kerakmi?
Yo’q. Oddiy DB + outbox/CDC yordamida qurish mumkin.
Rassinxronizatsiya bilan qanday kurashish mumkin?
UXni aniq loyihalash, proyeksiya lag’ini o’lchash, tanqidiy operatsiyalarga write’dan o’qish berish.
Bitta xizmatda write va o’qishni saqlash mumkinmi?
Ha, jismoniy bo’linish - ixtiyoriy; javobgarlikning mantiqiy taqsimlanishi shart.
Agregatlar o’rtasidagi tranzaksiyalar haqida nima deyish mumkin?
Dostonlar va voqealar orqali; agar iloji boʻlsa, taqsimlangan bitimlardan qoching.
Jami
CQRS qo’llarni ochadi: aniq invariantlar bilan nozik, ishonchli yozish yo’li va materiallashtirilgan proyeksiyalardan tezkor, maqsadli o’qish. Bu ish unumdorligini oshiradi, evolyutsiyani soddalashtiradi va tizimni yuklarga chidamli qiladi - agar muvofiqlik, kuzatuv va migratsiyani intizomiy boshqarish.