GH GambleHub

CQRS i oddzielenie odczytu/zapisu

Co to jest CQRS

CQRS (Command Query Responsibility Segregation) to podejście architektoniczne, które oddziela model danych od komponentów odpowiedzialnych za pisanie (polecenia) i czytanie (zapytania).
Pomysł: proces zmiany stanu jest zoptymalizowany pod kątem ważnych niezmienników i transakcji oraz czytania w celu szybkich, ukierunkowanych projekcji i skalowania.

klucz> Polecenia zmieniają stan i zwracają wynik operacji. Wnioski są tylko czytać i nie mają skutków ubocznych.


Dlaczego tego potrzebujesz?

Odczytaj wydajność: zmaterializowane projekcje dla konkretnych scenariuszy (taśmy, raporty, katalogi).
Stabilność ścieżki krytycznej: nagrywanie odizolowane od „ciężkich” połączeń i agregatów.
Wybór swobody przechowywania: OLTP do pisania, OLAP/cache/wyszukiwarki do czytania.
Przyspieszona ewolucja: Dodaj nowe poglądy bez ryzyka „łamania” transakcji.
Obserwowalność i audyt (zwłaszcza w połączeniu z Event Sourcing): łatwiej jest odzyskać i odtworzyć stan.


Kiedy stosować (a kiedy nie)

Nadaje się, jeśli:
  • Przeważają odczyty o różnych plasterkach danych i złożonej agregacji.
  • Krytyczna ścieżka zapisu musi być subtelna i przewidywalna.
  • Do czytania i pisania potrzebne są różne SLO/SLA.
  • Wymagana jest izolacja logiki zapisu domeny od potrzeb analitycznych/wyszukiwania.
Nie nadaje się, jeżeli:
  • Domena jest prosta, obciążenie jest niskie; CRUD sobie radzi.
  • Silna spójność pomiędzy czytaniem a pisaniem jest obowiązkowa dla wszystkich scenariuszy.
  • Zespół jest niedoświadczony, a złożoność operacyjna jest nie do przyjęcia.

Podstawowe pojęcia

Command-Intends zmieni stan ('Order', 'CapturePayment'). Sprawdzamy niezmiennie.
Query-Retrieves dane ('Na ById',' Transakcje z listy '). Żadnych skutków ubocznych.
Model zapisu: agregaty/niezmienne/transakcje; przechowywanie - relacyjny/wartość klucza/dziennik zdarzeń.
Model odczytu (projekcji): zmaterializowane tabele/indeksy/pamięć podręczna, synchronizowane asynchronicznie.
Spójność: Często eventual między nagrywaniem i czytaniem; ścieżki krytyczne - poprzez bezpośredni odczyt z modelu pisma.


Architektura (szkielet)

1. Usługa odpisu: akceptuje polecenia, waliduje niezmienne, przechwytuje zmiany (bazy danych lub zdarzeń).
2. Outbox/CDC: gwarantowana publikacja faktu zmian.
3. Procesory projekcji: Słuchaj zdarzeń/CDC i aktualizuj modele odczytu.
4. Usługa odczytu: obsługuje zapytania z zmaterializowanych widoków/buforów/wyszukiwań.
5. Sagi/orkiestra: współrzędne procesów krzyżowych.
6. Obserwowalność: opóźnienie projekcji, odsetek udanych aplikacji, DLQ.


Projektowanie modelu nagraniowego

Agregaty: jasne granice transakcji (na przykład „Zamówienie”, „Płatność”, „Saldo”).
Niezmienne: formalizować (kwoty pieniężne ≥ 0, wyjątkowość, limity).
Polecenia są idempotentne przez klucz (na przykład 'idempotence _ key').
Zakres transakcji jest minimalny; zewnętrzne skutki uboczne - poprzez skrzynkę zewnętrzną.

Przykład polecenia (Pseudo-JSON)

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

Projektowanie modelu czytania

Zacznij od zapytań: jakie ekrany/raporty są potrzebne?
Dopuszczalna jest denormalizacja: model odczytu - „zoptymalizowany pamięć podręczna”.
Kilka projekcji dla różnych zadań: wyszukiwanie (OpenSearch), raporty (pamięć kolumnowa), karty (KV/Redis).
TTL i reasekuracja: projekcje muszą być w stanie odzyskać ze źródła (powtórka zdarzenia/migawki).


Spójność i UX

Ewentualna spójność: interfejs może wyświetlać stare dane przez krótki czas.
Wzory UX: „dane są aktualizowane”..., optymistyczne interfejsy użytkownika, wskaźniki synchronizacji, blokowanie niebezpiecznych działań do czasu potwierdzenia.
W przypadku operacji wymagających silnej konsystencji (na przykład pokazujących dokładne saldo przed odpisem) należy odczytać bezpośrednio z modelu zapisu.


CQRS i Event Sourcing (opcjonalnie)

Event Sourcing (ES) przechowuje wydarzenia, a stan agregatu jest wynikiem ich konwolekcji.
Pakiet CQRS + ES zapewnia idealny audyt i łatwą ponowną ocenę projekcji, ale zwiększa złożoność.
Alternatywa: regularna baza danych OLTP + outbox/CDC → projekcje.


Replikacja: Outbox i CDC

Outbox (w jednej transakcji): zapisywanie zmian domeny + zapisywanie zdarzenia do skrzynki outbox; wydawca dostarcza do opony.
CDC: odczyt z dziennika bazy danych (Debezium itp.) → przekształcenie w zdarzenia domeny.
Gwarancje: domyślnie przynajmniej raz, konsumenci i prognozy muszą być idempotentne.


Wybór składowania

Napisz: relacyjne (PostgreSQL/MySQL) dla transakcji; KV/Dokument - gdzie niezmienne są proste.

Przeczytaj:
  • KV/Redis - karty i szybkie odczyty kluczy;
  • Wyszukiwanie (OpenSearch/Elasticsearch) - wyszukiwanie/filtry/fasony;
  • Kolumna (ClickHouse/Query) - raporty;
  • Cache na CDN - publiczne katalogi/treści.

Wzorce integracji

Warstwa API: oddzielne punkty końcowe/usługi dla „poleceń” i „zapytań”.
Idempotencja: klucz operacji w nagłówku/ciele; przechowywanie ostatnich klawiszy z TTL.
Sagi/orkiestra: timeouts, kompensacje, powtarzalność kroków.
Backpressure-Limity paralelizmu procesorów projekcyjnych.


Obserwowalność

Napisz metryki: p95/99 opóźnienia poleceń, procent udanych transakcji, błędy walidacyjne.
Odczytaj mierniki: żądania p95/99, pamięć podręczna, obciążenie w klastrze wyszukiwania.
Opóźnienie projekcji (czas i komunikaty), szybkość DLQ, procent deduplikacji.
Śledzenie: 'trace _ id' przechodzi przez polecenie → outbox → rzut zapytania.


Bezpieczeństwo i zgodność

Oddzielenie praw: różne zakresy/role pisania i czytania; zasada najmniejszego przywileju.
PII/PCI: zminimalizować w projekcjach; szyfrowanie podczas odpoczynku/lotu; Maskowanie.
Audyt: Zespół Fix, aktor, wynik, 'trace _ id'; Archiwa WORM dla domen krytycznych (płatności, KYC).


Badania

Testy kontraktowe: dla poleceń (błędy, niezmienne) i zapytań (formaty/filtry).
Testy projekcyjne: złożyć serię zdarzeń/CDC i sprawdzić końcowy model odczytu.
Chaos/opóźnienie: wtryskiwanie opóźnienia do procesorów projekcyjnych; Sprawdź UX w opóźnieniu.
Powtarzalność: reasembling projections on the stand from snapshots/log.


Migracja i ewolucja

Nowe pola - dodatek w przypadku/CDC; modeli odczytu są odbudowane.
Podwójne zapisywanie podczas przeprojektowywania obwodów; trzymać stare projekcje do przełączania.
Wersioning: 'v1 '/' v2' zdarzenia i punkty końcowe, Sunset-plan.
Flagi funkcji: wprowadzenie nowych zapytań/projekcji wzdłuż kanarka.


Anty-wzory

CQRS „dla dobra mody” w prostych usługach CRUD.
Twarda synchroniczna zależność od odczytu-zapisu (zabija izolację i trwałość).
Jeden indeks dla wszystkich: mieszanie niejednorodnych zapytań w jednym czytelni.
Projekcje nie mają idempotencji → duplikaty i rozbieżności.
Niezdatne do odzyskania projekcje (brak powtórki/migawki).


Przykłady domen

Płatności (usługa online)

Napisz: „Autoryzuj”, „Przechwytywanie”, „Zwrot” w bazie danych transakcji; outbox publikuje płatność. '.

Przeczytaj:
  • Redis „karta płatnicza” dla interfejsu użytkownika;
  • ClickHouse do raportowania;
  • OpenSearch do wyszukiwania transakcji.
  • Ścieżka krytyczna: autoryzacja ≤ 800 ms p95; spójność odczytu dla interfejsu użytkownika - ewentualna (do 2-3 s).

KYC

Napisz: polecenia do uruchomienia/aktualizacji stanu; Przechowywanie PII w bezpiecznej bazie danych.
Czytaj: lekka projekcja statusów bez PII; W razie potrzeby PII jest zaostrzony punktowo.
Bezpieczeństwo: różne zakresy stanu odczytu i dostępu do dokumentów.

Bilans (iGaming/Finance)

Napisz: Agregat „اBalance” z przyrostami/spadkami atomowymi; Idempotentne klucze do operacji.
Przeczytaj: pamięć podręczna do „szybkiej równowagi”; do odpisu - bezpośredni odczyt z zapisu (ścisła konsystencja).
Saga: depozyty/wnioski są koordynowane przez wydarzenia, w przypadku awarii - rekompensaty.


Lista kontrolna wdrażania

  • Podkreślono agregaty i niezmienne wartości modelu pisma.
  • Zdefiniowano kluczowe zapytania i zaprojektowano dla nich projekcje.
  • Procesory projekcji Outbox/CDC i idempotent są konfigurowane.
  • Istnieje plan migawki/powtórki.
  • SLO: opóźnienie polecenia, opóźnienie projekcji, dostępność odczytu/zapisu oddzielnie.
  • Wdrożono oddzielone prawa dostępu i szyfrowanie danych.
  • Alerty DLQ/lag/awarie deduplicacji.
  • Testy: Kontrakty, Projekcje, Chaos, Powtórka.

NAJCZĘŚCIEJ ZADAWANE PYTANIA

Czy Event Sourcing jest obowiązkowe dla CQRS?
Nie, nie jest. Możesz budować na regularnej bazie danych + outbox/CDC.

Jak radzić sobie z desynchronizacją?
Wyraźnie projektowanie UX, pomiar opóźnienia projekcji, niech krytyczne operacje czytać z zapisu.

Czy można zachować zarówno pisanie, jak i czytanie w tej samej usłudze?
Tak, fizyczna separacja jest opcjonalna; logiczny podział obowiązków jest obowiązkowy.

A co z transakcjami między agregatami?
Poprzez sagi i wydarzenia; W miarę możliwości unikaj transakcji rozproszonych.


Wynik

CQRS unties ręce: cienka, niezawodna ścieżka pisania z wyraźnymi niezmiennikami i szybko, ukierunkowane odczytuje z zmaterializowanych projekcji. Zwiększa to wydajność, upraszcza ewolucję i sprawia, że system jest bardziej odporny na stres - jeśli konsekwencja, obserwacja i migracja są zdyscyplinowane.

Contact

Skontaktuj się z nami

Napisz do nas w każdej sprawie — pytania, wsparcie, konsultacje.Zawsze jesteśmy gotowi pomóc!

Rozpocznij integrację

Email jest wymagany. Telegram lub WhatsApp są opcjonalne.

Twoje imię opcjonalne
Email opcjonalne
Temat opcjonalne
Wiadomość opcjonalne
Telegram opcjonalne
@
Jeśli podasz Telegram — odpowiemy także tam, oprócz emaila.
WhatsApp opcjonalne
Format: kod kraju i numer (np. +48XXXXXXXXX).

Klikając przycisk, wyrażasz zgodę na przetwarzanie swoich danych.