Saga-mönster för distribuerade transaktioner

Azure

Designmönstret Saga är ett sätt att hantera datakonsekvens mellan mikrotjänster i distribuerade transaktionsscenarier. En saga är en sekvens med transaktioner som uppdaterar varje tjänst och publicerar ett meddelande eller en händelse för att utlösa nästa transaktionssteg. Om ett steg misslyckas kör sagan kompenserande transaktioner som motverkar föregående transaktioner.

Kontext och problem

En transaktion är en enda enhet med logik eller arbete, som ibland består av flera åtgärder. I en transaktion är en händelse en tillståndsändring som sker i en entitet, och ett kommando kapslar in all information som behövs för att utföra en åtgärd eller utlösa en senare händelse.

Transaktionerna måste vara atomära, konsekventa, isolerade och hållbara (ACID). Transaktioner inom en enda tjänst är ACID, men datakonsekvens mellan tjänster kräver en strategi för transaktionshantering mellan tjänster.

I arkitekturer med flera tjänster:

  • Atomicitet är en odelbar och oemotståndlig uppsättning åtgärder som måste utföras eller inte.
  • Konsekvens innebär att transaktionen endast hämtar data från ett giltigt tillstånd till ett annat giltigt tillstånd.
  • Isolering garanterar att samtidiga transaktioner ger samma datatillstånd som sekventiellt utförda transaktioner skulle ha genererat.
  • Hållbarhet säkerställer att bekräftade transaktioner fortsätter att genomföras även vid systemfel eller strömavbrott.

En databas-per-mikrotjänstmodell ger många fördelar för mikrotjänstarkitekturer. Genom att kapsla in domändata kan varje tjänst använda sin bästa datalagertyp och schema, skala sitt eget datalager efter behov och isoleras från andra tjänsters fel. Att säkerställa datakonsekvens mellan tjänstspecifika databaser innebär dock utmaningar.

Distribuerade transaktioner som 2PC-protokollet (two-phase commit) kräver att alla deltagare i en transaktion checkar in eller återställer innan transaktionen kan fortsätta. Vissa deltagarimplementeringar, till exempel NoSQL-databaser och asynkron meddelandekö, stöder dock inte den här modellen.

En annan begränsning för distribuerade transaktioner är synkronisering och tillgänglighet för kommunikation mellan processer (IPC ). IPC som tillhandahålls av operativsystemet kan separata processer dela data. För att distribuerade transaktioner ska kunna checkas in måste alla deltagande tjänster vara tillgängliga, vilket kan minska den övergripande systemtillgängligheten. Arkitekturimplementeringar med IPC eller transaktionsbegränsningar är kandidater för Saga-mönstret.

Lösning

Saga-mönstret ger transaktionshantering med hjälp av en sekvens med lokala transaktioner. En lokal transaktion är den atomära arbetsinsats som utförs av en sagadeltagare. Varje lokal transaktion uppdaterar databasen och publicerar ett meddelande eller en händelse för att utlösa nästa lokala transaktion i sagan. Om en lokal transaktion misslyckas kör sagan en serie kompenserande transaktioner som ångrar de ändringar som gjordes av de föregående lokala transaktionerna.

Översikt över Saga.

I Saga-mönster:

  • Kompenserbara transaktioner är transaktioner som potentiellt kan ångras genom bearbetning av en annan transaktion med motsatt effekt.
  • En pivottransaktion är go/no-go-punkten i en saga. Om pivottransaktionen checkas in körs sagan tills den är klar. En pivottransaktion kan vara en transaktion som varken är kompenserbar eller återförsöksbar, eller så kan det vara den sista kompenserbara transaktionen eller den första återförsöksbara transaktionen i sagan.
  • Återförsöksbara transaktioner är transaktioner som följer pivottransaktionen och som garanterat lyckas.

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

Koreografi

Koreografi är ett sätt att samordna sagor där deltagarna utbyter evenemang utan en central kontrollpunkt. Med koreografi publicerar varje lokal transaktion domänhändelser som utlöser lokala transaktioner i andra tjänster.

Översikt över koreografi

Fördelar

  • Bra för enkla arbetsflöden som kräver få deltagare och inte behöver någon samordningslogik.
  • Kräver inte ytterligare tjänstimplementering och underhåll.
  • Introducerar inte en enskild felpunkt, eftersom ansvarsområdena fördelas mellan sagadeltagarna.

Nackdelar

  • Arbetsflödet kan bli förvirrande när du lägger till nya steg, eftersom det är svårt att spåra vilka saga-deltagare som lyssnar på vilka kommandon.
  • Det finns en risk för cykliskt beroende mellan Saga-deltagare eftersom de måste konsumera varandras kommandon.
  • Integreringstestning är svårt eftersom alla tjänster måste köras för att simulera en transaktion.

Orkestrering

Orkestrering är ett sätt att samordna sagor där en centraliserad kontrollant talar om för saga-deltagarna vilka lokala transaktioner som ska utföras. Saga orchestrator hanterar alla transaktioner och talar om för deltagarna vilken åtgärd som ska utföras baserat på händelser. Orkestreraren kör saga-begäranden, lagrar och tolkar tillstånden för varje uppgift och hanterar felåterställning med kompenserande transaktioner.

Översikt över orkestrering

Fördelar

  • Bra för komplexa arbetsflöden som involverar många deltagare eller nya deltagare som lagts till över tid.
  • Lämplig när det finns kontroll över varje deltagare i processen och kontroll över flödet av aktiviteter.
  • Introducerar inte cykliska beroenden, eftersom orkestreraren ensidigt är beroende av sagadeltagarna.
  • Saga-deltagare behöver inte känna till kommandon för andra deltagare. Tydlig uppdelning av problem förenklar affärslogik.

Nackdelar

  • Ytterligare designkomplexitet kräver en implementering av en samordningslogik.
  • Det finns ytterligare en felpunkt eftersom orkestreraren hanterar det fullständiga arbetsflödet.

Problem och överväganden

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

  • Saga-mönstret kan till en början vara en utmaning, eftersom det kräver ett nytt sätt att tänka på hur du ska samordna en transaktion och upprätthålla datakonsekvens för en affärsprocess som omfattar flera mikrotjänster.
  • Saga-mönstret är särskilt svårt att felsöka och komplexiteten växer när deltagarna ökar.
  • Data kan inte återställas eftersom saga-deltagare checkar in ändringar i sina lokala databaser.
  • Implementeringen måste kunna hantera en uppsättning potentiella tillfälliga fel och ge idempotens för att minska biverkningar och säkerställa datakonsekvens. Idempotens innebär att samma åtgärd kan upprepas flera gånger utan att det ursprungliga resultatet ändras. Mer information finns i vägledningen för att säkerställa idempotens när meddelanden bearbetas och uppdateras tillsammans.
  • Det är bäst att implementera observerbarhet för att övervaka och spåra saga-arbetsflödet.
  • Bristen på isolering av deltagardata medför hållbarhetsutmaningar. Saga-implementeringen måste innehålla motåtgärder för att minska avvikelser.

Följande avvikelser kan inträffa utan lämpliga mått:

  • Förlorade uppdateringar, när en saga skriver utan att läsa ändringar som gjorts av en annan saga.
  • Smutsiga läsningar, när en transaktion eller en saga läser uppdateringar gjorda av en saga som ännu inte har slutfört dessa uppdateringar.
  • Fuzzy/icke-läsbara läsningar, när olika saga-steg läser olika data eftersom en datauppdatering sker mellan läsningarna.

Föreslagna motåtgärder för att minska eller förhindra avvikelser är:

  • Semantiklås, ett lås på programnivå där en sagas kompenserbara transaktion använder en semafor för att indikera att en uppdatering pågår.
  • Kommutativa uppdateringar som kan köras i valfri ordning och ger samma resultat.
  • Pessimistisk vy: Det är möjligt för en saga att läsa felaktiga data, medan en annan saga kör en kompenserbar transaktion för att återställa åtgärden. Pessimistisk vy ordnar om sagan så att underliggande data uppdateras i en transaktion som kan försökas igen, vilket eliminerar risken för en felaktig läsning.
  • Omläsningsvärdet verifierar att data är oförändrade och uppdaterar sedan posten. Om posten har ändrats avbryts stegen och sagan kan startas om.
  • En versionsfil registrerar åtgärderna på en post när de tas emot och kör dem sedan i rätt ordning.
  • Efter värde används varje begärans affärsrisk för att dynamiskt välja samtidighetsmekanismen. Lågriskbegäranden gynnar sagor, medan begäranden med hög risk gynnar distribuerade transaktioner.

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 hos tidigare deltagare.
  • Cykliska beroenden.

Exempel

Orkestreringsbaserad Saga på Serverless är en saga-implementeringsreferens med orkestreringsmetoden som simulerar ett pengaöverföringsscenario med lyckade och misslyckade arbetsflöden.

Nästa steg

  • Distribuerad data
  • Richardson, Chris. 2018: Mönster för mikrotjänster. Manning Publikationer.

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

  • Koreografin har varje komponent i systemet som 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 ångrar arbete som utförts av en serie steg och definierar så småningom 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 modellen för slutlig konsekvens.
  • Med återförsök kan 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 åtgärden igen. Återförsök kan förbättra programmets stabilitet.
  • Kretsbrytaren hanterar fel som tar varierande tid att återställa från, vid anslutning till en fjärrtjänst eller resurs. Kretsbrytaren kan förbättra ett programs stabilitet och återhämtning.
  • Övervakning av hälsoslutpunkter implementerar funktionskontroller 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.