To applikationsservere i to regioner, én klient der skriver gennem en VPN, og et spørgsmål som ingen skrev ned: hvilken komponent beslutter, at skrivningen er sket? Routing bringer anmodningen til en proces. En transaktionsgrænse beslutter, hvornår ændringen bliver varig og synlig. Det er forskellige opgaver udført af forskellige systemer, og kløften mellem dem er der, hvor de fleste fejl i skrivninger på tværs af regioner bor.

Begynd med forretningsreglen, ikke med kortet

Begynd med en sætning om forretningsreglen i stedet for om geografien: hvilke læsninger og skrivninger skal lykkes sammen, og hvilke samtidige ændringer skal være umulige, mens de gør det. For en lagerreservation betyder det, at lagertjekket og reservationen enten begge træder i kraft eller ingen af dem, og ingen anden ordre må forbruge den samme enhed imellem.

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

Det er netop den midterste række, som teams springer over. Atomicitet uden tilstrækkelig isolation tillader to transaktioner hver at bekræftes korrekt og alligevel producere en tilstand, som forretningen anser for umulig, og ingen mængde genforsøgslogik reparerer det bagefter.

Én autoritativ grænse slår to regionale servere

Regionale applikationsservere kan blive, hvor de er, så længe de indsender operationen til en tjeneste, der udfører den inden for én understøttet transaktionsgrænse. Applikationslaget bliver en router for hensigt; datalaget ejer sandheden.

Hold den grænse kort og tæt på de data, den berører. En transaktion, der holdes åben, mens et menneske svarer på en prompt, eller mens et kald krydser to regioner, bruger sin tid på at holde låse og øger chancen for, at noget andet løber tør for tid bag den. Den fejl ligner et databaseproblem og er i virkeligheden et designproblem, der har klædt sig ud som et. At flytte beslutningen ned i datalaget fjerner det som regel helt.

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;

Læs den skitse som en grænse, ikke som en ydeevneanbefaling. Pointen er, at tjekket og indsættelsen deler én bekræftelse, så en samtidig ordre enten ser lageret forbrugt eller slet ikke ser det.

Hvad en replikeret database giver og ikke giver

En replikeret database kan levere en bredere grænse, når dens egen transaktionsmodel understøtter det. Spanner dokumenterer atomare læse-skrive-transaktioner inden for én database på tværs af tabeller, med defineret isolation og genforsøgsadfærd. Det er en garanti, som man læser, tester og bevidst hviler på.

Det er også en garanti, der kommer fra produktet, ikke fra ruten. En VPN mellem regioner ændrer, hvordan pakker rejser, og hvordan fejl viser sig. Den forlænger ikke en transaktionsgrænse med en enkelt række, uanset hvor sund tunnelen ser ud. At forveksle de to skaber arkitekturer, hvor hver komponent består sin egen kontrol, og dataene stadig er uenige.

To databaser bliver ikke ét system

To uafhængigt administrerede databaser får ikke en fælles transaktionsmanager, fordi klienter kan nå dem begge. Hvis forretningen virkelig har brug for atomær forpligtelse på tværs af parret, skal koordineringsmekanismen, deltagerne og genopretningsprocessen alle vælges og kvalificeres frem for antages.

Tænk på det øjeblik, hvor en deltager eller et link forsvinder, efter at arbejdet er forberedt. En understøttet distribueret bekræftelse kan efterlade en uafklaret tilstand, der kræver en genopretningsprocedure og en menneskelig beslutning, og den lover ikke, at hver region forbliver skrivbar gennem hver partition.

Hvis asynkron koordinering i stedet er acceptabel, så sig det eksplicit, og skriv de mellemliggende forretningstilstande plus afstemmelsesreglerne ned. En kæde af lokalt bekræftede trin med kompensation er et legitimt design; det er blot ikke én atomar transaktion med et andet navn.

Design genforsøget før det første nedbrud

En klient kan miste svaret, efter at operationen er bekræftet, så kalderen kan ikke behandle en timeout som en fejl. Bevar en varig anmodningsidentitet, og brug tjenestens resultat eller en idempotensmekanisme, før en ændring genforsøges, ellers bliver genforsøget en anden skrivning.

Automatiske transaktions-tilbagekald kan også køre mere end én gang efter en genforsøgbar afbrydelse, hvilket gør dem til et dårligt hjem for irreversible eksterne effekter. Hold dem uden for tilbagekaldet, medmindre arbejdsgangen definerer en eksplicit sikker protokol for dem. Samme forsigtighed gælder for alt, der koster penge eller sender en besked. En dobbeltopkrævning er en langt sværere samtale end en dobbelt loglinje.

Accept bør genafspille fire scenarier: to klienter, der kappes om samme række, en afbrydelse, som tjenesten siger kan genforsøges, en bekræftelse, hvis svar aldrig ankommer, og tabet af en region eller linket mellem dem. Registrer det bekræftede forretningsresultat og de uafklarede tilstande ved siden af routingdesignet, så ingen forveksler netværket med den komponent, der leverer garantien.

Relaterede artikler