GH GambleHub

CQRS və oxu/yazma bölgüsü

CQRS nədir

CQRS (Command Query Responsibility Segregation) - məlumat modelini və yazma (commands) və oxumağa (queries) cavabdeh olan komponentləri ayıran memarlıq yanaşmasıdır.
Fikir: vəziyyətin dəyişdirilməsi prosesi etibarlı invariantlar və əməliyyatlar üçün optimallaşdırılır, oxu isə sürətli, məqsədli proyeksiyalar və miqyaslandırma üçün optimallaşdırılır.

💡 Komandalar vəziyyəti dəyişir və əməliyyat nəticəsini geri qaytarır. Sorğular yalnız oxuyur və heç bir yan təsiri yoxdur.

Niyə lazımdır

Oxuma performansı: konkret ssenarilər (lentlər, hesabatlar, kataloqlar) altında materiallaşdırılmış proyeksiyalar.
Kritik yolun sabitliyi: rekord «ağır» joins və aqreqatlardan təcrid olunur.
Saxlama seçimi azadlığı: Yazma üçün OLTP, oxu üçün OLAP/cache/axtarış motorları.
Sürətli təkamül: əməliyyatları «qırmaq» riski olmadan yeni təsəvvürlər əlavə edin.
Müşahidə və audit (xüsusilə Event Sourcing ilə birlikdə): vəziyyəti bərpa etmək və yenidən oynamaq daha asandır.


Nə zaman tətbiq olunur (və nə zaman deyil)

Əgər uyğun:
  • Müxtəlif məlumat kəsikləri və mürəkkəb aqreqasiya ilə oxunmalar üstünlük təşkil edir.
  • Kritik yazma yolu incə və proqnozlaşdırıla bilən olmalıdır.
  • Oxumaq və yazmaq üçün müxtəlif SLO/SLA lazımdır.
  • Qeydlərin domen məntiqinin analitik/axtarış ehtiyaclarından təcrid edilməsi tələb olunur.
Əgər uyğun deyil:
  • Domain sadə, yük azdır; CRUD öhdəsindən gəlir.
  • Bütün ssenarilər üçün oxu və yazı arasında güclü uyğunluq tələb olunur.
  • Komanda təcrübəsiz və əməliyyat çətinliyi qəbuledilməzdir.

Əsas anlayışlar

Komanda (Command): vəziyyəti dəyişdirmək niyyəti ('CreateOrder', 'CapturePayment'). İnvariantları yoxlayır.
Sorğu (Query): məlumatların alınması ('GetOrderById', 'ListUserTransactions'). Yan təsirləri yoxdur.
Qeyd modeli: aqreqatlar/invariantlar/əməliyyatlar; saxlama - relyasion/açar dəyəri/hadisə log.
Oxu modeli (proyeksiyalar): materiallaşdırılmış cədvəllər/indekslər/keş, sinxronlaşdırılmış asinxron.
Uyğunluq: tez-tez qeyd və oxu arasında eventual; kritik yollar - write modelindən birbaşa oxu vasitəsilə.


Memarlıq (skelet)

1. Write xidməti: komandaları qəbul edir, invariantları təsdiqləyir, dəyişiklikləri qeyd edir (DB və ya hadisələr).
2. Outbox/CDC: dəyişiklik faktının zəmanətli nəşri.
3. proyeksiya prosessorları: hadisələr/CDC dinləmək və read-modelləri yeniləmək.
4. Read-service: materiallaşdırılmış performans/caches/axtarış queries xidmət edir.
5. Dastanlar/orkestr: kross-aqreqat proseslərini əlaqələndirir.
6. Müşahidə: lag proyeksiyaları, uğurlu tətbiqlərin faizi, DLQ.


Qeyd modelinin dizaynı

Aqreqatlar: əməliyyatların dəqiq sərhədləri (məsələn, 'Order', 'Payment', 'UserBalance').
İnvariantlar: rəsmiləşdirin (pul məbləği ≥ 0, unikallıq, limitlər).
Komandalar açar baxımından idempotentdir (məsələn, 'idempotency _ key').
Tranzaksiyalar əhatə baxımından minimaldır; xarici yan təsirləri - outbox vasitəsilə.

Komanda nümunəsi (psevdo-JSON)

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

Oxu modelinin dizaynı

Sorğulardan başlayın: hansı ekranlara/hesabatlara ehtiyacınız var?
Denormalizasiyaya icazə verilir: read-model - «optimallaşdırılmış cache».
Müxtəlif tapşırıqlar üçün bir neçə proyeksiya: axtarış (OpenSearch), hesabatlar (sütun saxlama), kartlar (KV/Redis).
TTL və yenidən montaj: proyeksiyalar mənbədən bərpa edə bilməlidir (hadisə replica/snapshot).


Uyğunluq və UX

Eventual consistency: interfeys qısa zamanda köhnə məlumatları göstərə bilər.
UX nümunələri: «məlumatlar yenilənir»..., optimist UI, sinxronizasiya göstəriciləri, təsdiqlənmədən əvvəl təhlükəli hərəkətlərin bloklanması.
Güclü uyğunluq tələb edən əməliyyatlar üçün (məsələn, silinməzdən əvvəl dəqiq balansın göstərilməsi) birbaşa write modelindən oxuyun.


CQRS və Event Sourcing (isteğe bağlı)

Event Sourcing (ES) hadisələri saxlayır, aqreqatın vəziyyəti isə onların yığılmasının nəticəsidir.
CQRS + ES paketi mükəmməl audit və proyeksiyaların asan yenidən yığılmasını təmin edir, lakin mürəkkəbliyi artırır.
Alternativ: adi OLTP-DB + outbox/CDC → proyeksiya.


Replikasiya: Outbox və CDC

Outbox (bir əməliyyat): Domain dəyişikliklər qeyd + outbox hadisə qeyd; publisher təkər çatdırır.
CDC: DB log (Debezium və s.) → domen hadisələrinə çevrilmə.
Zəmanət: default at-least-once, istehlakçılar və proyeksiyalar idempotent olmalıdır.


Anbar seçimi

Write: əməliyyatlar üçün relyasion (PostgreSQL/MySQL); KV/Document - invariantların sadə olduğu yerlərdə.

Read:
  • KV/Redis - kartlar və sürətli açar oxunuşları;
  • Axtarış (OpenSearch/Elasticsearch) - axtarış/filtrələr/fasetlər;
  • Sütunlu (ClickHouse/BigQuery) - hesabatlar;
  • CDN önbelləyi - ictimai kataloqlar/məzmun.

İnteqrasiya nümunələri

API təbəqəsi: «commands» və «queries» üçün ayrı-ayrı endpointlər/xidmətlər.
İdempotentlik: başlıq/bədəndə əməliyyat açarı; TTL ilə recent-keys saxlamaq.
Saqi/orkestr: zaman-autlar, kompensasiyalar, addımların təkrarlanması.
Backpressure: proyeksiya prosessorlarının paralelliyinin məhdudlaşdırılması.


Müşahidə

write metrikası: p95/99 latentlik əmrləri, uğurlu əməliyyatların payı, validasiya səhvləri.
Ölçülər: p95/99 sorğular, hit-rate cache, axtarış klasterinə yük.
Lag proyeksiyaları (vaxt və mesajlar), DLQ dərəcəsi, deduplikasiya faizi.
Trace: 'trace _ id' → outbox → proyeksiya → query komandasından keçir.


Təhlükəsizlik və uyğunluq

Hüquqların ayrılması: yazmaq və oxumaq üçün müxtəlif scopes/rollar; ən kiçik imtiyazlar prinsipi.
PII/PCI: proyeksiyalarda minimum; at-rest/in-flight şifrələmə; maskalama.
Audit: komanda, aktyor, nəticə, 'trace _ id' qeyd edin; Kritik domenlər üçün WORM arxivləri (ödənişlər, KYC).


Test

Contract tests: komandalar (səhvlər, invariantlar) və queries (formatlar/filtrlər) üçün.
Projection tests: Hadisə/CDC seriyasını təqdim edin və son oxu modelini yoxlayın.
Chaos/latency: proyeksiya prosessorlarına gecikmələrin injeksiyası; UX yoxlama lag.
Replayability: snapshot/log-dan stenddə proyeksiyaların yenidən yığılması.


Miqrasiya və təkamül

Yeni sahələr - hadisədə additiv/CDC; read-modellər yenidən yığılır.
Sxemlərin yenidən dizaynında ikiqat qeyd (dual-write); köhnə proyeksiyalar keçid qədər saxlamaq.
Version: 'v1 '/' v2' hadisə və end-point, Sunset planı.
Feature flags: Kanaryada yeni queries/proyeksiyaların daxil edilməsi.


Antipatternlər

CQRS sadə CRUD xidmətlərində «moda naminə».
Sərt sinxron oxu yazıya asılılığı (izolyasiya və sabitliyi öldürür).
Hamısı üçün bir indeks: bir read-store-da müxtəlif sorğuları qarışdırın.
Proyeksiyalarda idempotentlik yoxdur → dubllar və uyğunsuzluqlar.
Bərpa olunmayan proyeksiyalar (replay/snapshot yoxdur).


Domen nümunələri

Ödənişlər (onlayn xidmət)

Write: «Authorize», «Capture», «Refund» əməliyyat DB-də; outbox 'payment.'.

Read:
  • Redis «ödəniş kartı» UI üçün;
  • Hesabatlar üçün ClickHouse;
  • Əməliyyat axtarışı üçün OpenSearch.
  • Kritik yol: avtorizasiya ≤ 800 ms p95; UI üçün oxu uyğunluğu - eventual (2-3 saniyəyə qədər).

KYC

Write: start/update status komandaları; PII qorunan DB-də saxlanılır.
Read: PII olmadan status yüngül proyeksiya; PII lazım olduqda nöqtə ilə qaldırılır.
Təhlükəsizlik: müxtəlif scopes status oxumaq və sənədlərə giriş.

Balans (iGaming/Maliyyə)

Write: 'UserBalance' atomar artımlarla/dekrementlərlə; əməliyyat üçün idempotent açarları.
Read: «sürətli balans» üçün cache; yazmaq üçün - write-dən birbaşa oxumaq (ciddi uyğunluq).
Saga: depozitlər/nəticələr hadisələrlə əlaqələndirilir, uğursuzluqlar zamanı - kompensasiyalar.


Giriş çek siyahısı

  • Write modelinin aqreqatları və invariantları vurğulanır.
  • Əsas queries müəyyən və onlar üçün layihələndirilmiş proyeksiyalar.
  • Outbox/CDC və idempotent proyeksiya prosessorları.
  • proyeksiya yenidən bir plan var (snapshot/replay).
  • SLO: komandaların gizliliyi, lag proyeksiyaları, ayrı-ayrılıqda read/write mövcudluğu.
  • Paylaşılan giriş hüquqları və şifrələmə həyata keçirilir.
  • DLQ/lag/deuplikasiya uğursuzluqları.
  • Testlər: müqavilələr, proyeksiyalar, xaos, replay.

FAQ

CQRS üçün Event Sourcing lazımdır?
Yox. Adi DB + outbox/CDC üzərində qurmaq olar.

Rassinxronizasiya ilə necə mübarizə aparmaq olar?
Açıq UX layihələndirmək, proyeksiyaların gecikməsini ölçmək, kritik əməliyyatları write-dən oxumağa vermək.

Bir xidmətdə həm write, həm də oxu saxlamaq olarmı?
Bəli, fiziki bölünmə - isteğe bağlıdır; məsuliyyətin məntiqi bölünməsi tələb olunur.

Aqreqatlar arasında əməliyyatlar haqqında nə demək olar?
Dastanlar və hadisələr vasitəsilə; mümkünsə paylanmış əməliyyatlardan çəkinin.


Yekun

CQRS əllərini açır: dəqiq invariantlarla incə, etibarlı yazma yolu və materiallaşdırılmış proyeksiyalardan sürətli, məqsədli oxunmalar. Bu, performansı artırır, təkamülü asanlaşdırır və sistemi yüklərə qarşı daha davamlı edir - uyğunluq, müşahidə və miqrasiyaları nizam-intizamla idarə edirsə.

Contact

Bizimlə əlaqə

Hər hansı sualınız və ya dəstək ehtiyacınız varsa — bizimlə əlaqə saxlayın.Həmişə köməyə hazırıq!

İnteqrasiyaya başla

Email — məcburidir. Telegram və ya WhatsApp — istəyə bağlıdır.

Adınız istəyə bağlı
Email istəyə bağlı
Mövzu istəyə bağlı
Mesaj istəyə bağlı
Telegram istəyə bağlı
@
Əgər Telegram daxil etsəniz — Email ilə yanaşı orada da cavab verəcəyik.
WhatsApp istəyə bağlı
Format: ölkə kodu + nömrə (məsələn, +994XXXXXXXXX).

Düyməyə basmaqla məlumatların işlənməsinə razılıq vermiş olursunuz.