Replikacja i ewentualna spójność
Replikacja i ewentualna spójność
1) Dlaczego ewentualna spójność
Kiedy system jest dystrybuowany przez strefy/regiony, synchroniczne nagrywanie wszędzie daje dużą opóźnienie i niską dostępność w przypadku awarii sieci. Ewentualna spójność (WE) pozwala na tymczasowe błędne uzgodnienie replik w celu:- niskie opóźnienie rejestracji (lokalny odbiór),
- lepsza dostępność podczas przegród sieciowych,
- skalowanie poziome.
Kluczowym zadaniem jest kontrolowana spójność lax: użytkownik widzi „dość świeże” dane, niezmienne domeny są zachowane, konflikty są wykrywane i rozwiązywane przewidywalnie.
2) Modele spójności - to, co obiecujemy klientowi
Silny: Czytanie natychmiast widzi ostatni wpis.
Ograniczony stale/read-not-older (RNOT): nie starszy niż znak (LSN/wersja/czas).
Przyczynowy: Utrzymywany jest związek przyczynowo-skutkowy (A-B).
Read-Your-Writes: Klient widzi swoje ostatnie nagrania.
Monotoniczne odczyty: Każde następne odczytanie nie jest „cofnięte”.
Sesja: zestaw gwarancji w jednej sesji.
Eventual: jeśli nie ma nowych wpisów, wszystkie repliki converge.
Praktyka: Połączyć sesję + RNOT na ścieżkach krytycznych i Eventual na sklepach/buforach.
3) Replikacja: mechanika i anty-entropia
Synchroniczny (kworum/RAFT): rekord jest uważany za udany po potwierdzeniu przez węzły N; minimalny RPO powyżej p99.
Asynchroniczny: lider popełnia lokalnie, dystrybuuje dziennik później; niskie opóźnienie, RPO> 0.
Fizyczne (WAL/binlog): szybkie, jednorodne.
Logiczny/CDC: przepływ zmiany poziomu wiersza/zdarzenia, elastyczny routing, filtry.
Anty-entropia: okresowe pojednanie i naprawy (drzewa Merkle, porównanie skrótów, ponowna synchronizacja tła).
4) Identyfikatory wersji i nakazy przyczynowości
Wersje monotonowe: przyrost/LSN/epoka; proste, ale nie kodować paralelizm.
Lamport timestamp: częściowe zamówienie przez zegar logiczny.
Zegar wektorowy: naprawia równoległe gałęzie i pozwala wykrywać sprzeczne aktualizacje (równoległe).
Hybrydowy Czas/Zegar-SI: „Nie przed T” logika globalnego porządku.
Zalecenie: dla CRDT/sprzecznych aktualizacji - zegar wektorowy; dla „nie starszych” - LSN/GTID.
5) Konflikty: Odkrycie i rozwiązywanie
Typowe sytuacje: nagrywanie z dwóch regionów do tego samego obiektu.
Strategie:1. Last-Write-Wins (LWW) po godzinie/logiczny znaczek - prosty, ale może „stracić” aktualizacje.
2. Scalanie funkcji według logiki domeny:- dodaje się pola licznikowe (G-Counter/PN-Counter),
- zestawy są połączone z "add-wins/remove-wins',
- kwoty/salda - tylko przez dzienniki transakcji, a nie przez zwykły LWW.
- 3. CRDT (typy konwergentów): G-Counter, OR-Set, LWW-Register, RGA dla list.
- 4. Przekształcenia operacyjne (rzadko dla baz danych, częściej dla edytorów).
- 5. Ręczne rozwiązywanie: konflikt w „skrzynce odbiorczej”, użytkownik wybiera poprawną wersję.
Zasada: Domena niezmiennie dyktuje strategię. Dla pieniędzy/sald - unikać LWW; Użyj kompensowanych transakcji/zdarzeń.
6) Zapisz gwarancje i idempotencję
Idempotentne klucze na poleceniach (płatność, wypłata, tworzenie) → ponowna próba jest bezpieczna.
Deduplikacja skrzynki odbiorczej i skrzynki odbiorczej przez klucz idempotencji/numer seryjny.
Dokładnie raz jest nieosiągalny bez silnych pomieszczeń; ćwiczyć co najmniej raz + idempotencję.
Wzorzec Outbox/Inbox: pisanie do bazy danych i publikowanie zdarzenia jest atomowe (transakcja lokalna), procesy odbiorcy przez idempotence-key.
7) Brak starszych odczytów X (RNOT)
Technicy:- Bramka LSN/GTID: klient przekazuje minimalną wersję (z odpowiedzi na pisanie), router/proxy wysyła do repliki, która złapała LSN ≥ X, w przeciwnym razie - do lidera.
- Czas: „nie starszy niż 2 sekundy” - prosty SLA bez wersji.
- Spinanie sesji: po nagraniu N sekund, czytamy tylko lidera (Read-Your-Writes).
8) Przepływy zmian i negocjacje w sprawie pamięci podręcznej
CDC → autobus imprezowy (Kafka/Pulsar) → konsumenci (bufory, indeksy, sklepy).
Niepełnosprawność pamięci podręcznej: tematy „unieważnić: {ns}: {id}”; idempotentne przetwarzanie.
Odbudowa/Zasypka: Jeśli nie jest synchronizowana, należy ponownie skonfigurować projekcje z dziennika zdarzeń.
9) Sagi i rekompensaty (transakcje międzyresortowe)
W świecie WE długotrwałe działania dzielą się na działania kompensacyjne:- Orkiestra: Koordynator wzywa kroki i ich rekompensaty.
- Choreografia: kroki reagować na wydarzenia i publikować następujące.
Niezmienne (przykład): „saldo ≥ 0” - sprawdź na granicach etapu + rekompensata za odchylenie.
10) Przegrody wielobranżowe i sieciowe
Local-write, async-replicate: napisz do lokalnego regionu + dostarcz do innego (EC).
Ogrodzenie geograficzne: dane są „przyklejane” do regionu (niskie opóźnienia, mniej konfliktów).
Kworum baz danych (tratwa) dla danych CP; bufory/sklepy - AP/EC.
Plan podziału mózgu: jeśli komunikacja zostanie utracona, regiony nadal działają w granicach domeny (pisać ogrodzenia, kwoty), a następnie godzić.
11) Obserwowalność i SLO
Metryka:- Opóźnienie repliki: czas/odległość LSN/przesunięcie (p50/p95/p99).
- Trwałość: odsetek odpowiedzi powyżej progu (na przykład> 2s lub LSN
- Wskaźnik konfliktu: wskaźnik konfliktów i udane połączenie.
- Czas konwergencji: czas konwergencji replik po szczycie.
- Pogodzić zaległości: objętość/czas opóźnień partii.
- RPO/RTO według kategorii danych (CP/AP).
- Lag> cel, wzrost konfliktów, „długie” okna braku odporności.
12) Projekt systemu danych WE
Wersja jawna/wektor w każdym wpisie (kolumny 'wersja', 'vc').
Dzienniki dla niezmienników krytycznych (salda, rozliczenia międzyokresowe).
Identyfikatory zdarzeń (płatek śniegu/ULID) do zamówienia i deduplikacji.
Pola komutacyjne (liczniki, zestawy) → Kandydaci CRDT.
Projekt API: PUT with if-match/etag, PATCH z warunkiem wstępnym.
13) Wzorce przechowywania i odczytu
Czytaj model/CQRS: pisanie do „źródła”, czytanie z projekcji (może opóźnić → wyświetlacz „zaktualizowany”...).
Ciągłe-OK trasy (katalog/taśma) vs Strict (portfel/limity).
Kleiste/Bounded-stale flagi w żądaniu (nagłówek „x-read-consistency”).
14) Lista kontrolna wdrażania (0-45 dni)
0-10 dni
Kategoria danych: CP-critical (pieniądze, zamówienia) vs EU/steel-OK (katalogi, indeksy wyszukiwania).
Zdefiniuj SLO Steele (np. "nie starsze niż 2s'), lagi docelowe.
Włącz wersję obiektu i klucze idempotencji w interfejsie API.
11-25 dni
Wdrożenie CDC i skrzynki odbiorczej/odbiorczej, trasy niepełnosprawności pamięci podręcznej.
Dodaj RNOT (brama LSN) i spinanie sesji do ścieżek zapisu krytycznych.
Wdrożenie co najmniej jednej strategii łączenia (LWW/CRDT/domena) i dziennika konfliktów.
26-45 dni
Automatyzacja raportów antyentropii (pojednanie/naprawa) i stylizacji.
Spędzić grę-day: separacja sieci, gwałtowny wzrost konfliktów, odzyskiwanie.
Wizualizacja na deskach rozdzielczych: opóźnienie, trwałość, szybkość konfliktu, konwergencja.
15) Anty-wzory
Ślepa LWW dla stałych krytyków (utrata pieniędzy/punktów).
Brak idempotencji → duplikaty operacji podczas przekwalifikowania.
„Silny” model na całość → nadmierne ogony p99 i kruchość w przypadku awarii.
Nie RNOT/Sesja gwarantuje → UX „blinks”, użytkownicy „nie widzą” ich zmian.
Ukryta pamięć podręczna i niedokładność źródła (brak CDC/niepełnosprawność).
Brak narzędzia godzenia/antyentropii - dane „przez wieki” się różnią.
16) Wskaźniki zapadalności
Replika lag p95 ≤ cel (na przykład, ≤ 500 ms w obrębie regionu, ≤ 2 s międzyregionów).
Staleness SLO wykonuje się ≥ 99% wniosków na „ścisłych” trasach.
Sukces w rozwiązywaniu konfliktów ≥ 99. 9%, średni czas rozdzielczości ≤ 1 min.
Czas konwergencji po szczytach - minuty, nie godziny.
100% transakcji „pieniężnych” jest pokrywanych przez klucze idempotencji i skrzynkę odbiorczą/skrzynkę odbiorczą.
17) Przepisy (snippets)
If-Match/ETag (HTTP)
PUT /profile/42
If-Match: "v17"
Body: { "email": "new@example.com" }
Jeśli wersja została zmieniona - '412 Preondition Failed' → klient rozwiązuje konflikt.
Zapytanie „nie starsze niż LSN” (pseudo)
x-min-lsn: 16/B373F8D8
Router wybiera replikę z 'replay _ lsn ≥ x-min-lsn', w przeciwnym razie jest liderem.
CRDT G-Counter (pomysł)
Każdy region ma swój własny licznik; Razem - suma wszystkich komponentów Replikacja - Działanie jest commutative.
18) Wniosek
Ostateczna spójność nie jest kompromisem jakości, ale świadomym kontraktem: gdzieś płacimy świeżość ze względu na szybkość i dostępność, ale chronimy krytyczne niezmienne strategie i narzędzia domeny. Wprowadź wersje, idempotencję, gwarancje RNOT/Session, CDC i anty-entropii, zmierz lag/stalness/konflikty - a system rozproszony będzie szybki, stabilny i przewidywalnie zbieżny nawet pod usterkami i obciążeniami szczytowymi.