Două servere de aplicație în două regiuni, un client care scrie printr-un VPN și o întrebare pe care nimeni nu a scris-o: care componentă decide că scrierea a avut loc? Rutarea duce cererea la un proces. O graniță de tranzacție decide când modificarea devine durabilă și vizibilă. Sunt sarcini diferite făcute de sisteme diferite, iar golul dintre ele este locul unde trăiesc majoritatea erorilor de scriere în mai multe regiuni.

Începeți de la regula de business, nu de la hartă

Începeți cu o propoziție despre regula de business și nu despre geografie: care citiri și scrieri trebuie să reușească împreună și care modificări concurente trebuie să fie imposibile în acel timp. Pentru o rezervare de stoc aceasta înseamnă că verificarea stocului și rezervarea fie ambele intră în vigoare, fie niciuna, și nicio a doua comandă nu poate consuma aceeași unitate între timp.

RequirementWhat satisfies itWhat does not
All-or-nothing applicationA transaction inside one owning systemA VPN path between regions
No double spendIsolation strong enough to exclude the conflictAtomicity alone
Survive a region lossReplication the database itself documentsTwo independent databases behind one client

Exact acel rând din mijloc este cel pe care echipele îl sar. Atomicitatea fără izolare suficientă permite ca două tranzacții să se confirme corect fiecare și totuși să producă o stare pe care afacerea o consideră imposibilă, iar nicio cantitate de logică de reîncercare nu o repară după aceea.

O singură graniță autoritativă bate două servere regionale

Serverele de aplicație regionale pot rămâne unde sunt, atâta timp cât trimit operația către un serviciu care o execută în interiorul unei singure granițe de tranzacție acceptate. Nivelul aplicației devine un router de intenție; nivelul de date deține adevărul.

Țineți acea graniță scurtă și aproape de datele pe care le atinge. O tranzacție ținută deschisă în timp ce un om răspunde la un mesaj sau în timp ce un apel traversează două regiuni își petrece timpul ținând blocaje și crescând șansa ca altceva să expire în spatele ei. Acea defecțiune arată ca o problemă de bază de date și este de fapt o problemă de proiectare deghizată în așa ceva. Mutarea deciziei în nivelul de date o elimină de obicei complet.

BEGIN;
UPDATE inventory SET reserved = reserved + 1
 WHERE sku = 'A-100' AND available >= 1;
INSERT INTO reservation (sku, order_id) VALUES ('A-100', 'ord-9f');
COMMIT;

Citiți acea schiță ca pe o graniță, nu ca pe o recomandare de performanță. Ideea este că verificarea și inserarea împart o singură confirmare, așa că o comandă concurentă fie vede stocul consumat, fie nu îl vede deloc.

Ce dă și ce nu dă o bază de date replicată

O bază de date replicată poate oferi o graniță mai largă atunci când propriul model de tranzacții o susține. Spanner documentează tranzacții atomice de citire-scriere în cadrul unei singure baze de date peste tabele, cu izolare și comportament de reîncercare definite. Aceasta este o garanție pe care o citiți, o testați și pe care vă bazați în mod deliberat.

Este și o garanție care vine de la produs, nu de la rută. Un VPN între regiuni schimbă felul în care călătoresc pachetele și felul în care se manifestă defecțiunile. Nu extinde o graniță de tranzacție nici cu un rând, oricât de sănătos ar arăta tunelul. Confundarea celor două produce arhitecturi în care fiecare componentă trece propria verificare și datele tot nu sunt de acord.

Două baze de date nu devin un singur sistem

Două baze de date administrate independent nu dobândesc un manager de tranzacții comun pentru că clienții pot ajunge la ambele. Dacă afacerea are într-adevăr nevoie de un angajament atomic peste pereche, mecanismul de coordonare, participanții și procesul de recuperare trebuie toate alese și calificate în loc de presupuse.

Gândiți-vă la momentul în care un participant sau o legătură dispare după ce munca a fost pregătită. O confirmare distribuită acceptată poate lăsa o stare incertă care are nevoie de o procedură de recuperare și de o decizie umană, și nu vine cu promisiunea că fiecare regiune rămâne scriibilă prin fiecare partiție.

Dacă în schimb este acceptabilă o coordonare asincronă, spuneți-o explicit și notați stările de business intermediare împreună cu regulile de reconciliere. Un lanț de pași confirmați local cu compensare este o proiectare legitimă; pur și simplu nu este o singură tranzacție atomică sub alt nume.

Proiectați reîncercarea înainte de prima defecțiune

Un client poate pierde răspunsul după ce operația a fost confirmată, așa că apelantul nu poate trata un timeout ca pe o defecțiune. Păstrați o identitate durabilă a cererii și folosiți rezultatul serviciului sau un mecanism de idempotency înainte de a reîncerca o mutare, altfel reîncercarea devine o a doua scriere.

Apelurile inverse automate ale tranzacțiilor pot rula și de mai multe ori după un abandon reîncercabil, ceea ce le face un loc prost pentru efecte externe ireversibile. Țineți-le în afara apelului invers dacă fluxul de lucru nu definește pentru ele un protocol sigur explicit. Aceeași prudență se aplică oricărui lucru care costă bani sau trimite un mesaj. O taxare dublă este o conversație mult mai dificilă decât o linie de jurnal dublă.

Acceptarea ar trebui să reia patru scenarii: doi clienți care se întrec pentru același rând, un abandon pe care serviciul îl declară reîncercabil, o confirmare al cărei răspuns nu sosește niciodată și pierderea unei regiuni sau a legăturii dintre ele. Înregistrați rezultatul de business confirmat și stările nerezolvate lângă proiectarea rutării, ca nimeni să nu confunde rețeaua cu componenta care oferă garanția.

Articole similare