Redigera

Dela via


Saga-mönster för distribuerade transaktioner

Azure

Designmönstret Saga hjälper till att upprätthålla datakonsekvens i distribuerade system genom att samordna transaktioner mellan flera tjänster. En saga är en sekvens med lokala transaktioner där varje tjänst utför sin åtgärd och initierar nästa steg genom händelser eller meddelanden. Om ett steg i sekvensen misslyckas kör sagan kompenserande transaktioner för att ångra de slutförda stegen, vilket behåller datakonsekvensen.

Kontext och problem

En transaktion representerar en arbetsenhet som kan innehålla flera åtgärder. I en transaktion refererar en händelse till en tillståndsändring som påverkar en entitet. Ett -kommando kapslar in all information som behövs för att utföra en åtgärd eller utlösa en efterföljande händelse.

Transaktioner måste följa principerna om atomitet, konsekvens, isolering och hållbarhet (ACID).

  • Atomicity: Alla åtgärder lyckas eller ingen gör det.
  • Konsekvens: Data övergår från ett giltigt tillstånd till ett annat.
  • Isolation: Samtidiga transaktioner ger samma resultat som sekventiella.
  • Hållbarhet: När ändringarna har checkats in kvarstår de även vid fel.

I en enda tjänst följer transaktioner ACID-principer eftersom de fungerar i en enda databas. Det är dock mer komplext att uppnå ACID-efterlevnad för flera tjänster.

Utmaningar i mikrotjänstarkitekturer

Mikrotjänstarkitekturer tilldelar vanligtvis en dedikerad databas till varje mikrotjänst, som erbjuder flera fördelar:

  • Varje tjänst kapslar in sina egna data.
  • Varje tjänst kan använda den lämpligaste databastekniken och schemat för sina specifika behov.
  • Oberoende skalning av databaser för varje tjänst.
  • Fel i en tjänst är isolerade från andra.

Trots dessa fördelar komplicerar den här arkitekturen datakonsekvens mellan tjänster. Traditionella databasgarantier som ACID gäller inte direkt för flera oberoende hanterade datalager. På grund av dessa begränsningar är arkitekturer som förlitar sig på interprocesskommunikation (IPC) eller traditionella transaktionsmodeller, som tvåfas incheckningsprotokoll (2PC), ofta bättre lämpade för Saga-mönstret.

Lösning

Saga-mönstret hanterar transaktioner genom att dela upp dem i en sekvens med lokala transaktioner (se bild 1).

diagram som visar en sagaöversikt.
Bild 1. En saga med tre tjänster.

Varje lokal transaktion:

  1. Slutför sitt arbete atomiskt inom en enda tjänst.
  2. Uppdaterar tjänstens databas.
  3. Initierar nästa transaktion via en händelse eller ett meddelande.
  4. Om en lokal transaktion misslyckas kör sagan en serie kompenserande transaktioner för att återställa de ändringar som gjorts av de föregående lokala transaktionerna.

Viktiga begrepp i Saga-mönstret

  • Compensable-transaktioner: Transaktioner som andra transaktioner kan ångra eller kompensera för med motsatt effekt. Om ett steg i sagan misslyckas ångrar kompenserande transaktioner de ändringar som de kompenserbara transaktionerna har gjort.

  • Pivottransaktion: Pivottransaktionen fungerar som "punkt utan retur" i sagan. När pivottransaktionen har slutförts är kompenserbara transaktioner (som kan ångras) inte längre relevanta. Alla efterföljande åtgärder måste slutföras för att systemet ska uppnå ett konsekvent slutligt tillstånd. En pivottransaktion kan delas in i olika roller beroende på flödet i sagan:

    • Oåterkalleligt (ej inkompatibelt): Det går inte att ångra eller försöka igen.

    • gräns mellan reversibel och bekräftad: Det kan vara den sista ogjorda (kompenserbara) transaktionen, eller så kan det vara den första återförsöksbara åtgärden i sagan.

  • Återförsöksbara transaktioner: Dessa transaktioner följer pivottransaktionen. Återförsöksbara transaktioner är idempotent och ser till att sagan kan nå sitt slutliga tillstånd, även om tillfälliga fel inträffar. Det garanterar att sagan uppnår ett konsekvent tillstånd så småningom.

Saga-implementeringsmetoder

Det finns två vanliga metoder för sagaimplementering, koreografi och orkestrering. Varje metod har en egen uppsättning utmaningar och tekniker för att samordna arbetsflödet.

Koreografi

I koreografi utbyter tjänster händelser utan en centraliserad kontrollant. Med koreografi publicerar varje lokal transaktion domänhändelser som utlöser lokala transaktioner i andra tjänster (se bild 2).

diagram som visar en saga med koreografi.
Bild 2. En saga som använder koreografi.

Fördelar med koreografi nackdelar med koreografi
Bra för enkla arbetsflöden med få tjänster och behöver ingen samordningslogik. Arbetsflödet kan bli förvirrande när du lägger till nya steg. Det är svårt att spåra vilka sagadeltagare som lyssnar på vilka kommandon.
Ingen annan tjänst krävs för samordning. Det finns en risk för cykliskt beroende mellan sagadeltagare eftersom de måste använda varandras kommandon.
Introducerar inte en enda felpunkt, eftersom ansvarsområdena fördelas över sagadeltagarna. Integreringstestning är svårt eftersom alla tjänster måste köras för att simulera en transaktion.

Orkestrering

I orkestrering hanterar en centraliserad styrenhet (orchestrator) alla transaktioner och talar om för deltagarna vilken åtgärd som ska utföras baserat på händelser. Orchestrator kör saga-begäranden, lagrar och tolkar tillstånden för varje uppgift och hanterar återställning av fel med kompenserande transaktioner (se bild 3).

diagram som visar en saga med orkestrering.
Bild 3. En saga som använder orkestrering.

Fördelar med orkestrering Orkestreringsdrag
Passar bättre för komplexa arbetsflöden eller när du lägger till nya tjänster. Annan designkomplexitet kräver en implementering av en samordningslogik.
Undviker cykliska beroenden eftersom orkestratorn hanterar flödet. Introducerar en felpunkt eftersom orkestratorn hanterar det fullständiga arbetsflödet.
Tydlig ansvarsfördelning förenklar tjänstlogik.

Problem och överväganden

Tänk på följande när du implementerar Saga-mönstret:

  • Förändring i designtänkandet: Att implementera Saga-mönstret kräver ett annat tänkesätt, med fokus på att samordna transaktioner och säkerställa datakonsekvens mellan flera mikrotjänster.

  • Komplexiteten i felsökningssagor: Felsökningssagor kan vara komplext, särskilt när antalet deltagande tjänster växer.

  • Oåterkalleliga lokala databasändringar: Data kan inte återställas eftersom saga-deltagare checkar in ändringar i sina respektive databaser.

  • Hantering av tillfälliga fel och idempotens: Systemet måste hantera tillfälliga fel effektivt och säkerställa idempotens, där upprepande av samma åtgärd inte ändrar resultatet. Mer information finns i Idempotent meddelandebearbetning.

  • Behovet av att övervaka och spåra sagor: Övervakning och spårning av arbetsflödet i en saga är avgörande för att upprätthålla driftstillsyn.

  • Begränsningar för kompenserande transaktioner: Kompenserande transaktioner kanske inte alltid lyckas, vilket potentiellt lämnar systemet i ett inkonsekvent tillstånd.

Potentiella dataavvikelser i sagor

Dataavvikelser är inkonsekvenser som kan uppstå när sagas körs över flera tjänster. Eftersom varje tjänst hanterar sina egna data (deltagardata) finns det ingen inbyggd isolering mellan tjänster. Den här konfigurationen kan leda till datainkonsekvenser eller hållbarhetsproblem, till exempel delvis tillämpade uppdateringar eller konflikter mellan tjänster. Vanliga problem är:

  • Förlorade uppdateringar: När en saga ändrar data utan att överväga ändringar som gjorts av en annan saga leder det till överskrivna eller saknade uppdateringar.

  • Dirty läser: När en saga eller transaktion läser data som en annan saga har ändrat men ännu inte slutförts.

  • Fuzzy (icke-lösningsbar) läser: När olika steg i en saga läser inkonsekventa data eftersom uppdateringar sker mellan läsningarna.

Strategier för att hantera dataavvikelser

För att minska eller förhindra dessa avvikelser bör du överväga dessa motåtgärder:

  • Semantic Lock: Använd lås på programnivå där en sagas kompenserbara transaktion använder en semafor för att indikera att en uppdatering pågår.

  • Commutative updates: Design updates so they can be applied in any order while still producing the same result, reducing conflicts between sagas.

  • pessimistisk vy: Ordna om sekvensen i sagan så att datauppdateringar sker i återförsöksbara transaktioner för att eliminera smutsiga läsningar. I annat fall kan en saga läsa felaktiga data (ogenomförda ändringar) medan en annan saga samtidigt kör en kompenserbar transaktion för att återställa uppdateringarna.

  • Läsa om värden: Verifiera att data förblir oförändrade innan du gör uppdateringar. Om data ändras avbryter du det aktuella steget och startar om sagan efter behov.

  • Versionsfiler: Underhålla en logg över alla åtgärder på en post och se till att de körs i rätt ordning för att förhindra konflikter.

  • Riskbaserad samtidighet (efter värde): Välj dynamiskt lämplig samtidighetsmekanism baserat på den potentiella affärsrisken. Använd till exempel sagor för lågriskuppdateringar och distribuerade transaktioner för högrisktransaktioner.

När du ska använda det här mönstret

Använd Saga-mönstret när du behöver:

  • Säkerställ datakonsekvens i ett distribuerat system utan nära koppling.
  • Återställ eller kompensera om någon av åtgärderna i sekvensen misslyckas.

Saga-mönstret är mindre lämpligt för:

  • Nära kopplade transaktioner.
  • Kompenserande transaktioner som inträffar i tidigare deltagare.
  • Cykliska beroenden.

Nästa steg

  • distribuerade data
  • Richardson, Chris. 2018: Microservices Patterns. Bemanningspublikationer.

Följande mönster kan också vara användbara när du implementerar det här mönstret:

  • Choreography har varje komponent i systemet deltar i beslutsprocessen om arbetsflödet för en affärstransaktion, i stället för att förlita sig på en central kontrollpunkt.
  • kompenserande transaktioner ångra arbete som utförs av en serie steg och slutligen definiera en konsekvent åtgärd om ett eller flera steg misslyckas. Molnbaserade program som implementerar komplexa affärsprocesser och arbetsflöden följer ofta den här eventuell konsekvensmodell.
  • Försök igen låter ett program hantera tillfälliga fel när det försöker ansluta till en tjänst eller nätverksresurs genom att transparent försöka utföra den misslyckade åtgärden igen. Ett nytt försök kan förbättra programmets stabilitet.
  • Kretsbrytare hanterar fel som tar en varierande tid att återställa från när du ansluter till en fjärrtjänst eller resurs. Kretsbrytaren kan förbättra ett programs stabilitet och återhämtning.
  • Hälsoslutpunktsövervakning implementerar funktionella kontroller i ett program som externa verktyg kan komma åt via exponerade slutpunkter med jämna mellanrum. Övervakning av hälsoslutpunkter kan hjälpa dig att kontrollera att program och tjänster fungerar korrekt.