Replicarea și eventuala coerență
Replicarea și eventuala coerență
1) De ce eventuala consecventa
Atunci când sistemul este distribuit pe zone/regiuni, înregistrarea sincronă peste tot oferă latență ridicată și disponibilitate scăzută în cazul defecțiunilor de rețea. Eventuala coerență (CE) permite o dezaliniere temporară a replicilor de dragul:- întârziere redusă de înregistrare (recepție locală)
- o mai bună disponibilitate în timpul partițiilor de rețea,
- scalare orizontală.
Sarcina cheie este controlată consistența laxă: utilizatorul vede date „destul de proaspete”, invarianții de domeniu sunt păstrați, conflictele sunt detectate și rezolvate în mod previzibil.
2) Modele de consistență - ceea ce promitem clientului
Strong: Lectura vede imediat ultima intrare.
Bounded stale/read-not-older-than (RNOT): citit nu mai vechi decât marca (LSN/version/time).
Cauzal: Se menține o relație „cauzală” (A-B).
Read-Your-Writs: Un client vede înregistrările sale recente.
Monotonic Reads: Fiecare citire următoare nu este „laminate înapoi”.
Sesiune: un set de garanții într-o singură sesiune.
Eventual: dacă nu există intrări noi, toate replicile converg.
Practică: Combinați sesiunea + RNOT pe căi critice și Eventual pe storefronturi/cache-uri.
3) Replicare: mecanică și anti-entropie
Sincron (cvorum/RAFT): înregistrarea este considerată reușită după confirmarea de către nodurile N; RPO minim, peste p99.
Asincron: liderul se angajează local, distribuie jurnalul mai târziu; latență scăzută, RPO> 0.
Fizic (WAL/binlog): rapid, omogen.
Logic/CDC: fluxul schimbării nivelului rândului/evenimentului, rutarea flexibilă, filtre.
Anti-entropie: reconciliere și reparații periodice (copaci Merkle, comparație hash, re-sincronizare de fundal).
4) Identificatorii versiunii și ordinele de cauzalitate
Versiuni monotone: increment/LSN/epocă; simplu, dar nu codifica paralelismul.
Lampă de timp: ordine parțială prin ceas logic.
Ceas vectorial: fixează ramuri paralele și vă permite să detectați actualizări contradictorii (concurente).
Hibrid/TrueTime/Clock-SI: „Nu înainte de T” logică pentru ordinea globală.
Recomandare: pentru CRDT/actualizări contradictorii - ceas vectorial; pentru „nu mai vechi” - LSN/GTID.
5) Conflicte: Descoperire și rezolvare
Situații tipice: înregistrarea de la două regiuni la același obiect.
Strategii:1. Last-Write-Wins (LWW) pe oră/timbru logic - simplu, dar poate „pierde” actualizări.
2. Funcții de îmbinare după logica domeniului:- se adaugă câmpuri (G-Counter/PN-Counter),
- seturile sunt combinate cu „add-wins/remove-wins”,
- sume/solduri - numai prin intermediul jurnalelor de tranzacții, nu printr-un simplu LWW.
- 3. CRDT (tipuri convergente): G-Counter, OR-Set, LWW-Register, RGA pentru liste.
- 4. Transformări operaționale (rareori pentru baze de date, mai des pentru editori).
- 5. Rezolvarea manuală: conflict în „inbox”, utilizatorul selectează versiunea corectă.
Regula: Invarianții de domenii dictează strategia. Pentru bani/solduri - evitați LWW; Utilizați tranzacții/evenimente compensate.
6) Garanții de înregistrare și idempotență
Tastele Idempotent pe comenzi (plată, retragere, creare) → încercarea din nou este sigură.
Inbox și outbox deduplication by idempotence key/serial number.
Exact-o dată este de neatins fără spații puternice; practică cel puțin o dată + idempotență.
Outbox/Inbox pattern: scrierea în baza de date și publicarea evenimentului este atomică (tranzacție locală), procesele destinatarului prin cheie de idempotență.
7) Nu există citiri X mai vechi (RNOT)
Tehnicieni:- Poarta LSN/GTID: clientul transmite versiunea minimă (din răspunsul de scriere), routerul/proxy trimite la replica care a prins cu LSN ≥ X, în caz contrar - la lider.
- Limită de timp: „nu mai vechi de 2 secunde” - un SLA simplu fără versiuni.
- Pinning sesiune: după înregistrarea N secunde, citim doar liderul (Read-Your-Writs).
8) Schimbarea fluxurilor și negocierea memoriei cache
CDC → event bus (Kafka/Pulsar) → consumatori (cache-uri, indici, vitrine).
Cache disability: topics' invalidate: {ns}: {id} '; procesare idempotentă.
Reconstrui/Backfill: Dacă nu se sincronizează, reasamblați proiecțiile din jurnalul de evenimente.
9) Sagas și compensații (tranzacții inter-servicii)
În CE, operațiunile de lungă durată sunt împărțite în etape cu acțiuni compensatorii:- Orchestrație: Coordonatorul numește pașii și compensațiile lor.
- Coregrafia: pașii reacționează la evenimente și publică singuri următoarele.
Invarianți (exemplu): „echilibru ≥ 0” - verificați la pas limite + compensare pentru abatere.
10) Multi-regiune și partiții de rețea
Local-write, async-replice: scrie la regiunea locală + livra la alte (CE).
Geo-scrimă: datele sunt „lipite” de regiune (latență scăzută, mai puține conflicte).
Baze de date cvorum (Raft) pentru date CP; cache/storefronts - AP/CE.
Planul Split-creier: dacă comunicarea este pierdută, regiunile continuă să funcționeze în limitele domeniului (scriu garduri, cote), apoi se reconciliază.
11) Observabilitate și SLO
Măsurători:- Lag replica: timp/LSN-distanță/offset (p50/p95/p99).
- Staleness: Procentul de răspunsuri care sunt deasupra pragului (de exemplu,> 2s sau LSN
- Rata conflictelor: rata conflictelor și fuziunea cu succes.
- Timpul de convergență: timpul de convergență al replicilor după vârf.
- Reconcilierea restanțelor: volumul/timpul loturilor rămase.
- RPO/RTO pe categorii de date (CP/AP).
- Lag> țintă, creșterea conflictelor, ferestre „lungi” de infezabilitate.
12) Proiectarea schemei de date CE
Versiune explicită/vector în fiecare intrare (coloane "versiune", "vc').
Adăugați jurnale numai pentru invarianți critici (solduri, acumulări).
Identificatori de evenimente (fulg de zăpadă/ULID) pentru comandă și eliminare a duplicatelor.
Câmpuri comutative (contoare, seturi) → candidați CRDT.
Design API: PUT cu if-match/etag, PATCH cu condiție prealabilă.
13) Modele de stocare și citire
Citiți modelul/CQRS: scrierea la „sursă”, citirea din proiecții (poate rămâne în spatele afișajului → „actualizat”...).
Trasee Stale-OK (catalog/bandă) vs Stricte (portofel/limite).
Steaguri lipicioase/învechite în cerere (antetul „x-read-consistence”).
14) Lista de verificare a implementării (0-45 zile)
0-10 zile
Categorizați datele: CP-critic (bani, comenzi) vs EU/steel-OK (cataloage, indici de căutare).
Definirea SLO-urilor Steele (de ex. "nu mai vechi de 2s'), lag-uri țintă.
Activați versionarea obiectelor și tastele de idempotență în API.
11-25 zile
Implementarea CDC și outbox/inbox, rute de handicap cache.
Adăugați RNOT (poarta LSN) și fixarea sesiunii pentru a scrie căi critice.
Implementați cel puțin o strategie de îmbinare (LWW/CRDT/domain) și jurnalul de conflict.
26-45 zile
Automatizați rapoartele anti-entropie (reconciliere/reparare) și styling.
Petreceți ziua jocului: separarea rețelei, creșterea conflictelor, recuperarea.
Vizualizați pe tablouri de bord: decalaj, staleness, rata de conflict, convergență.
15) Anti-modele
Blind LWW pentru invarianți critici (pierderi de bani/puncte).
Lipsa idempotenței → duplicate ale operațiunilor în timpul recalificărilor.
Modelul „puternic” pe ansamblu → cozi p99 excesive și fragilitate în caz de eșecuri.
Nu RNOT/Session garantează → UX „clipește”, utilizatorii „nu văd” modificările lor.
Cache-ul ascuns și alinierea greșită a sursei (fără CDC/dizabilitate).
Lipsa unui instrument de reconciliere/anti-entropie - divergențe de date „de secole”.
16) Valorile maturității
Replica lag p95 ≤ obiectiv (de exemplu, ≤ 500 ms într-o regiune, ≤ 2 s inter-regiuni).
Staleness SLO este efectuat ≥ 99% din cererile de pe rutele „stricte”.
Succes în rezolvarea conflictelor ≥ 99. 9%, timp mediu de rezoluție ≤ 1 min.
Timpul de convergență după vârfuri - minute, nu ore.
100% din tranzacțiile cu „bani” sunt acoperite de chei de idempotență și outbox/inbox.
17) Rețete (fragmente)
If-Match/ETag (HTTP)
PUT /profile/42
If-Match: "v17"
Body: { "email": "new@example.com" }
Dacă versiunea s-a schimbat - '412 Precondiție eșuată' → clientul rezolvă conflictul.
Interogare „nu mai vechi de LSN” (pseudo)
x-min-lsn: 16/B373F8D8
Routerul alege o replică cu 'replay _ lsn ≥ x-min-lsn', altfel este liderul.
CRDT G-Counter (idee)
Fiecare regiune își păstrează propriul contor; Total - suma tuturor componentelor Replicarea - Operarea este comutativă.
18) Concluzie
O eventuală consecvență nu este un compromis al calității, ci un contract conștient: undeva plătim prospețime de dragul vitezei și disponibilității, dar protejăm invarianții critici cu strategii și instrumente de domeniu. Introduceți versiunile, idempotența, garanțiile RNOT/Session, CDC și anti-entropia, măsurați decalajul/staleness/conflictele - iar sistemul distribuit va fi rapid, stabil și previzibil convergent chiar și sub erori și sarcini de vârf.