Sagas și tranzacții distribuite
O saga este o tranzacție de afaceri pe termen lung defalcată într-o secvență de pași locali în diferite servicii/depozite. Fiecare pas are o acțiune compensatoare care dă înapoi efectul de pas în eșecul parțial. Spre deosebire de 2PC/3PC, sagas nu dețin încuietori globale și sunt potrivite pentru microservicii, multi-regiuni și sarcini mari, în cazul în care o eventuală consistență este acceptabilă.
1) Când să alegeți saga (și când nu)
Fit:- Procese de afaceri lungi/multiple (comandă → plată → rezervă → livrare).
- Diferite domenii și depozite în cazul în care nu există nici o tranzacție comună.
- Aveți nevoie de disponibilitate ridicată și de extindere.
- Atomicitatea ACID solid este critică (de exemplu, transferul de cantități mari în același registru).
- Nu există compensabilitate clară (nu puteți „rezerva” sau anula efectul).
- Restricțiile legale/de reglementare necesită o izolare strictă și un invariant „instant”.
2) Modele Sagas
1. Saga Orchestrator-Coordonatorul central gestionează pașii și compensațiile.
Pro: flux explicit, controlul erorilor, telemetrie simplificată.
Contra: punct de centralizare, risc de „grăsime” coordonator.
2. Coregrafie (Coregrafie): niciun centru - pașii sunt inițiați de evenimente („serviciul A a făcut X → serviciul B reacționează”).
Pro: conectivitate slabă, scalare simplă.
Contra: este mai dificil de urmărit/depanat fluxul, riscul de „întindere” a regulilor.
3. TCC (Try-Confirm/Cancel) - Fiecare pas este „Încercați”, apoi confirmați sau anulați.
Pro: mai aproape de protocolul pseudo-bifazic, resurse gestionate.
Contra: mai scump în implementarea interfețelor; necesită „Încercați” timeout titular.
3) Design de pitch și compensare
Invarianți: precizați clar ce ar trebui să fie adevărat „înainte/după” pasul (de exemplu, „restul ≥ 0”).
Compensare ≠ tranzacție inversă: aceasta este o acțiune logică care anulează efectul de afaceri (rambursare, eliberare, restaurare).
Idempotence: atât pas și compensator trebuie să fie repetate în condiții de siguranță (prin "operation _ id').
Timeout: fiecare pas are un termen limită; întârziere declanșează despăgubiri.
Efecte non-retur: înregistrați-le separat (notificări, e-mail) și permiteți „cel mai bun efort”.
4) Coerență și ordine
Eventuala consecventa: utilizatorii pot vedea discrepante de timp; UX - cu „așteptați „/spinners/statuses.
Comandă după cheie - Grupați pașii de comutare prin cheie de afaceri (order_id) pentru a comanda evenimentele.
Eliminarea duplicatelor - Stocați jurnalul de procesare ("operation _ id' → status) cu TTL.
5) Transport și fiabilitate
Outbox model-Scrie evenimentul la masa outbox locale în cadrul aceleiași tranzacții, și apoi asincron publică la autobuz.
Inbox/Idempotency store: pe partea de consum - un jurnal de mesaje deja procesate.
Exact o dată în mod eficient: „outbox + consumator idempotent” oferă o practică „exact o dată”.
DLQ: pentru mesaje „otrăvitoare” cu meta-informații bogate și redrive sigure.
6) Politici de eroare, retray, backoff
Repetăm doar pași idempotenți; scrie operațiuni - cu 'Idempotency-Key'.
Backoff exponențial + jitter; limitarea încercărilor și a termenului rezumativ al saga.
Cu degradare sistemică - Întrerupător de circuit și degradare grațioasă (de exemplu, anulați partea secundară de ficțiune a saga).
Conflicte de afaceri ('409') - încercați din nou după reconciliere sau compensați și încheiați.
7) Orchestrator: Responsabilități și structură
Funcții:- Urmărirea statutului saga: „În așteptarea → funcționarea → compensarea → făcut/eșuat”.
- Paşi de planificare, termene limită, termene limită, retrageri.
- Rutarea evenimentelor și lansarea compensațiilor.
- Idempotența operațiunilor de coordonare (jurnalul de comandă).
- Observabilitate: corelarea "saga _ id' în busteni/urme/metrici.
- Tabele 'saga', 'saga _ step', 'comenzi', 'outbox'.
- Indexuri pe 'saga _ id',' business _ key ',' status ',' next _ run _ at '.
8) Coregrafie: reguli și protecție împotriva „bulgăre de zăpadă”
Contracte de evenimente: scheme și versioning (Avro/Proto/JSON Schema).
Semantică clară: „eveniment de fapt” vs „comandă”.
Oprirea lanțului: serviciul, după ce a detectat o neconcordanță, publică un eveniment 'Eșuat '/' Compensat'.
Alarme și alerte pe „bucle nesfârșite”.
9) TCC: detalii practice
Încercați: rezervă de resurse cu TTL.
Confirmați: angajați, eliberați încuietori temporare.
Anulează: rezervă rollback (fără efecte secundare).
Colectarea gunoiului: anularea automată a Try after TTL (idempotent Cancel).
Confirmați/Anulați idempotent: repetarea este sigură.
10) Exemplu (schema de cuvinte) - „Comandă cu plată și livrare”
1. CreateOrder (local) → outbox: 'OrderCreated'.
2. PaymentService: rezerva „Try” (TCC); dacă → „PaymentReserved” reușește, dacă „PaymentFailed” → eșuează.
3. InventoryService: rezervă de produse; din → „InventoryFailed”.
4. ShippingService - Creați slot de livrare (anulabil).
5. Dacă orice pas 'Eșuat' → orchestratorul începe compensațiile în ordinea inversă: 'CancelShipping' → 'ReleaseInventory' → 'PaymentCancel'.
6. Dacă totul este în regulă → "PaymentConfirm' →" OrderConfirmed ".
11) Orchestrator pseudocod
pseudo startSaga(saga_id, order_id):
steps = [ReservePayment, ReserveInventory, BookShipment, ConfirmPayment]
for step in steps:
res = execWithRetry(step, order_id)
if!res.ok:
compensateInReverse(steps_done(order_id))
return FAIL return OK
execWithRetry(step, key):
for attempt in 1..MAX:
try:
return step.run(key) # идемпотентно catch RetryableError:
sleep(backoff(attempt))
catch NonRetryableError:
return FAIL return FAIL
compensateInReverse(done_steps):
for step in reverse(done_steps):
step.compensate() # идемпотентно
12) SLO-uri de observabilitate și operaționale
Urmărire: single 'saga _ id', adnotări' pas ',' încercare ',' decizie '(run/compensate/skip).
Măsurători:- Succes/eroare de sagas (%), durata medie, p95/p99.
- Ponderea sagas compensate, motive de top pentru compensare.
- Cozi/outbox lag-uri, retrase în trepte.
- Busteni/audituri: solutii orchestrator, identificatori resurse, chei business.
13) Testarea și haosul
Injectarea erorilor în fiecare pas: timeout, '5xx', conflicte de afaceri.
Evenimente out-of-order, duplicate, picături.
Cozi lungi de latență → verificarea termenelor și compensațiilor.
Sagas de masă → verificarea WFQ/DRR și capace în cozi, absența „blocării capului de linie”.
Redrave de la DLQ în trepte și într-un întreg saga.
14) Multi-chirie, regiuni, conformitate
Etichete 'chiriaș _ id/plan/regiune' în evenimente și depozite saga.
Rezidență: datele/evenimentele nu părăsesc regiunea; sagas transregionale sunt concepute ca federații de sagas locale + evenimente de agregare.
Prioritizarea: sagele VIP transportă o greutate mai mare a cotei; izolarea lucrătorilor pe chiriaș.
15) Lista de verificare pre-vânzare
Fiecare pas are un compensator clar, ambele sunt idempotente.
- Șablon selectat: orchestrație/coregrafie/TSS; limitele de responsabilitate sunt descrise.
- Outbox/Inbox implementat, eliminarea duplicatelor prin 'operation _ id'.
- Politicile Retray: backoff cu jitter, încercați limitele și termenul general saga.
- Contractele de evenimente sunt versionate, există validarea schemei.
- DLQ și Secure Release sunt configurate.
- Telemetrie: metrici, urmărire, corelație 'saga _ id'.
- Playbook-uri operaționale: manual de anulare/forță-confirmare, deblocare „agățat” sagas.
- Haos și testele de sarcină trec, bugetul SLO/eroare definit.
16) Erori tipice
Nu există nici un compensator sau este „necurat” (are efecte secundare).
Nu există idempotență/dedup - dublează și „leagăne” de state.
„Saga în Saga” fără limite explicite - cicluri și încuietori reciproce.
Nu există termene limită → sagas „eterne” și scurgeri de resurse.
Orchestratorul stochează statul „în memorie” fără un magazin stabil.
Coregrafia fără centru de telemetrie → eşecuri „invizibile”.
UX opac: Utilizatorii nu văd stări intermediare.
17) Rețete rapide
SaaS clasice: orchestrație + outbox/inbox, backoff exponențial, DLQ, statusuri saga în UI.
Invarianți puternici ai resurselor: TCC cu rezervă TTL și GC Cancel.
Volum mare/încărcare: coregrafie eveniment + idempotență strictă și măsurători cheie.
Multi-regiune: sagas locale + agregate finale; evită încuietorile globale.
Concluzie
Sagas sunt o modalitate de a obține o consistență previzibilă în sistemele distribuite fără încuietori globale. Compensatorii clari, idempotența, livrarea fiabilă (outbox/inbox), disciplina timeout și retray, plus telemetria și cărțile de redare sunt cheia pentru a se asigura că procesele complexe de afaceri rămân stabile și lizibile cu o sarcină crescândă, un număr de servicii și geografii.