Den moderne transaksjonsstakken

Den moderne transaksjonsstakken

The Modern Transactional Stack PlatoBlockchain Data Intelligence. Vertical Search. Ai.

Transaksjonsdatabaser har lenge vært den mest kritiske komponenten i applikasjonsdesign. Hvorfor? Fordi en stabil database generelt er det ultimate håndhevelsespunktet for korrekthet i en rotete, distribuert verden. Uten dem ville vi betalt for mye og for lite. Vi ville miste ryttere som prøvde å komme seg hjem fra flyplassen, og vi ville miste varer i handlekurvene våre. Våre nettkontoer vil gå tapt, dupliseres eller ødelegges og bli ubrukelige. 

Faktisk har transaksjonsdatabasen (vanligvis kalt OLTP – forkortelse for online transaksjonsbehandling – database) vært så sentral i applikasjonsutviklingen at den over tid forbrukte mer og mer applikasjonsfunksjonalitet. Mikrotjenester og andre moderne applikasjonsarkitekturer introduserte imidlertid nye kompleksiteter i applikasjonsdesign: Utviklere trengte å administrere data på tvers av forskjellige tjenester og sikre konsistens mellom dem, noe som tvang dem til å bygge komplekse datasynkroniserings- og prosesseringsmekanismer internt. 

Og så, som bransje, ser vi en økende bevissthet om at transaksjonsgarantier er nødvendig utenfor den tradisjonelle modellen. Vi ser fremveksten av systemer som utvider sterke transaksjonsgarantier utover databasen, inn i selve de distribuerte appene

Vi har sporet disse løsningene de siste årene. Generelt streber de etter å tillate transaksjonsstyring av staten i en stor distribuert app, uten å skape skaleringsutfordringer og samtidig tilby et moderne programmeringsmiljø. 

Vi finner disse løsningene grovt sett deles inn i to kategorier. En kategori er arbeidsflyt orkestrering. Dette garanterer i utgangspunktet at en blokk med kode vil kjøre til fullføring, selv i møte med feil. Så den kan brukes med det formål å administrere en distribuert tilstandsmaskin deterministisk uten å bli forvirret. Den andre kategorien er database + arbeidsflyt, som utvider tradisjonell OLTP-databasedesign, som tillater utførelse av vilkårlig kode for samme formål. 

Dette er fortsatt et veldig begynnende område, og det er mye forvirring rundt nomenklatur, hvordan hvert verktøy brukes i praksis, og hvem som skal bruke dem. For å hjelpe til med å få en bedre forståelse spurte vi praktikere fra ledende ingeniørorganisasjoner om deres transaksjonsstabel og hvordan de tenker på tre nøkkelkonsepter for transaksjonelle arbeidsbelastninger: applikasjonstilstand, forretningslogikk og forretningsdata. 

Før vi undersøker disse nye stablene, men her er en rask semi-teknisk digresjon for å hjelpe deg med å forstå hvordan vi kom hit.

Transaksjoner, garantier og moderne apper 

Den svært grove versjonen er denne: Det er et sett med oppgaver - transaksjoner - som du enten vil gjøre alt eller ingen av. Alt i mellom (hvis det delvis er gjort) vil ende i en korrupt tilstand. Det er vanskelig å garantere hva som helst i et distribuert system, men databaser gjør det bra med transaksjoner. Derfor er den enkleste måten å håndtere garantier på i mange systemer å bare gjøre det meste transaksjoner og la databasen håndtere dem.

Moderne apper er store distribuerte systemer med mange brukere som gjør mange ting. Så selv å holde apptilstanden konsistent (som sporing av hvor forskjellige brukere er i en utsjekkingsflyt) blir til et distribuert transaksjonsproblem. I tradisjonelle monolittiske arkitekturer var det noe effektivt å administrere transaksjoner ved hjelp av SQL med en OLTP-database. Men i den nye, komplekse verdenen av mikrotjenester som samhandler gjennom API-er på høyere nivå (f.eks. REST eller gRPC), har transaksjonsbehov blitt distribuert i naturen. 

Imidlertid har mange selskaper som går på reisen til mikrotjenester ikke gjort mye for å utvide sterke transaksjonsgarantier utover databasen. Og i praksis er det det nesten alltid OK. Men etter hvert som applikasjonene skaleres, vokser inkonsekvenser i data, og det samme gjør den resulterende buggien og uavstemte feil i forretningsdata. Noe som selvfølgelig kan være enormt problematisk. Dette tvinger applikasjonsutviklere til å håndtere en lang rekke feilscenarier og konfliktløsningsstrategier, og sikre statens konsistens ved å komme opp med sine egne strategier gjennom forskjellige arkitektoniske mønstre.

definisjoner

Forretningsdata («data») refererer til forretningskritiske data som tradisjonelt er lagret i en OLTP-database for utholdenhet og behandling (f.eks. brukerprofilinformasjon som navn, adresse, kredittscore, etc.).

Søknadstilstand refererer til den nåværende tilstanden til systemet; applikasjonstilstanden bestemmes av en verdi som er lagret i et datalagringssystem og hvilket trinn programmets kjøring er på i en finite state-maskin (f.eks. tilstanden til en ordre, slik som "ordre mottatt", "beholdning sjekket", "kredittsjekket ," "sendt", "returnert").

Forretningslogikk refererer til den delen av programmet som omhandler hvordan applikasjonen faktisk fungerer eller hva den gjør, i stedet for utførelsesdetaljer (f.eks. "Hvis brukerinntekt > $100 650 & kredittscore >XNUMX ⇒ boliglån_godkjent = TRUE").

For formålet med denne diskusjonen er det viktig å skille applikasjonsstatus og forretningsdata. For eksempel er søknadsstatus å vite at en kunde har oppgitt kredittkortet sitt, men ikke har sjekket ut. Dataene for kredittkortet og varene i applikasjonsvognen er forretningsdataene. 

The Modern Transactional Stack PlatoBlockchain Data Intelligence. Vertical Search. Ai.

I en typisk flyt kommer en forespørsel fra front-end, blir autentisert, og blir deretter rutet via en API-gateway eller GraphQL til det relevante endepunktet. 

Det eneste API-endepunktet må nå orkestrere titalls eller hundrevis av mikrotjenester for å levere forretningstransaksjonen til sluttkunden. Det er her utviklere vanligvis klumper alt inn i forretningslogikkblokker, og bruker deretter en kombinasjon av køer, cacher og håndkodede prøvemekanismer for å få dataene til databasen – forhåpentligvis forpliktet som en full transaksjon.

Ettersom omfanget av applikasjonen øker, øker også kompleksiteten ved å administrere køer og cacher, samt antallet skarpe kanter i avstemmingslogikken når problemer oppstår. 

Fremveksten av arbeidsflytsentriske og databasesentriske transaksjonsstabler

OK, så transaksjoner er viktige. LAMP på en database var ikke tilstrekkelig for skala. Og en gigantisk hårball av køer og logikk på nytt forsøk er for skjør. For å håndtere dette har vi de siste årene sett fremveksten av nye løsninger som bringer fornuft tilbake til transaksjonslogikk. De kan grovt kategoriseres som enten arbeidsflytsentriske tilnærminger eller databasesentriske tilnærminger.

Til dags dato jobber arbeidsflytmotorer primært på applikasjonstilstand i stedet for forretningsdata, og krever ofte noe kompleksitet når de integreres med tradisjonelle databaser. Databasesentriske tilnærminger legger til applikasjonslogikk sammen med forretningsdata, men har ennå ikke samme sofistikerte kodeutførelse som arbeidsflytmotorer. 

Diagrammet nedenfor gir en grov skisse av hvordan arbeidsflyt- og/eller databasesentriske tilnærminger brukes i en Javascript/Typescript-applikasjon, forutsatt at begge er i bruk. Selv om de er distinkte deler av denne arkitekturen i dag, har vi sett tidlige tegn på en trend der databaser inkorporerer arbeidsflytfunksjoner og arbeidsflyter begynner å ta i bruk holdbar lagring. Denne sammenslåingen av evner indikerer at linjene mellom de to tilnærmingene visker ut og blir mindre distinkte i moderne arkitekturer. 

The Modern Transactional Stack PlatoBlockchain Data Intelligence. Vertical Search. Ai.

Arbeidsflytsentriske tilnærminger i detalj 

En arbeidsflyt er ganske enkelt blokker med kode som kjøres basert på hendelser, eller tidtakere, som utvikler applikasjonstilstandsmaskinen. Transaksjonsarbeidsflyt sikrer kodeutførelse med sterke garantier, og forhindrer delvise eller utilsiktede tilstander i applikasjonen. Utviklere skriver logikken, og arbeidsflytmotoren håndterer transaksjoner, mutasjoner og idempotens. Ulike arbeidsflytmotorer gjør forskjellige avveininger når det gjelder hvor mye av transaksjonsdetaljene som er utsatt for utviklerne. 

Som et eksempel, nedenfor er en visuell representasjon av en utsjekkingsarbeidsflyt som kjører på Orkes (Conductor): 

The Modern Transactional Stack PlatoBlockchain Data Intelligence. Vertical Search. Ai.

Det finnes to grove tilnærminger som arbeidsflytmotorer får trekkraft. I ett (typisert av Temporal.io), skriver utviklere kode ved å bruke standard back-end programmeringsspråk (f.eks. Go eller Java) og systemet vil sikre at koden kjører til fullføring, selv under en fiasko. I denne modellen opprettholdes programanropsstakken selv om koden venter på at et blokkerende anrop skal fullføres (f.eks. lese eller skrive). For å gjøre dette, endres språkkjøringstiden for å forhindre delvis kodekjøring under feil. Fordelen med denne tilnærmingen er at utviklere kan skrive på kjente språk og enkelt feilsøke med en vedlikeholdt anropsstabel. Vi ser denne tilnærmingen mest populær blant back-end-team som arbeider med store, sofistikerte apper. 

Ulempen er at det ofte krever mye integreringsarbeid og innpakningskode for å eksponere nyttige og sikre grensesnitt for applikasjonsutviklere. En annen ulempe er at den er avhengig av et tilpasset utførelseslag i stedet for det blotte språket, og det er edge-tilfeller der utførelsen vil avvike fra kjøretiden på morsmålet. Så selv om utviklere kan bruke språk de er kjent med, må de fortsatt forstå hvordan det underliggende systemet fungerer.  

Den andre tilnærmingen, som er mer populær blant applikasjonsutviklere (spesielt Typescript/Javascript), er at arbeidsflytmotoren skal tjene som en orkestrator av asynkrone funksjoner (f.eks. Inngest, Defer og Trigger). I denne modellen blir tredjepartshendelser eller -funksjoner dirigert til arbeidsflytmotoren, som deretter sender logikk registrert av applikasjonsprogrammererne, som må gi tilbake kontrollen når behovet for å blokkere på en annen asynkronfunksjon oppstår. Fordelen er at dette er en langt lettere metode for integrering i et program. Det tvinger også nok struktur på koden til at teamet som jobber med den lettere kan forstå den. Imidlertid kan denne tilnærmingen være vanskeligere å feilsøke uten verktøystøtte, så feilsøking har en tendens til å være plattformspesifikk.

Arbeidsflytmotorer er spesielt kraftige ved at de tillater gradvis adopsjon av eksisterende apper. De kan brukes stykkevis på visse arbeidsflyter med minimalt fotavtrykk. Når det er sagt, kommer de to største manglene til arbeidsflytmotorer fra det faktum at de ikke strekker seg inn i databasen. Som et resultat er det ikke en enkelt, spørrebar kilde til sannhet på tvers av applikasjonstilstand og forretningsdata. Dessuten er transaksjonssemantikken generelt forskjellig fra databasesemantikken, og krever at applikasjonsutviklere håndterer kantforhold. 

Selv om det ikke er normen i dag, ønsker vi å illustrere de konseptuelle arkitekturene for hvordan arbeidsflyter i mange tilfeller kan brukes som vedvarende datalagre:

Eksempler på kun arbeidsflyt-arkitekturer

The Modern Transactional Stack PlatoBlockchain Data Intelligence. Vertical Search. Ai.

Arkitektur kun for arbeidsflyt: JavaScript-apper

The Modern Transactional Stack PlatoBlockchain Data Intelligence. Vertical Search. Ai.

Arkitektur kun for arbeidsflyt: apper som bruker mikrotjenester

Databasesentriske tilnærminger i detalj 

Databasesentriske tilnærminger starter med en database, men utvider den til å støtte vilkårlig kodekjøring for å tillate arbeidsflyter ved siden av databehandling. De gjør dette ved å gi kontroll til programmererne slik at de kan ta eksplisitte beslutninger om mutasjoner, transaksjoner og idempotens for vanlige kodeblokker - hovedsakelig ved å eksponere OLTP-semantikk direkte. Programmereren er ansvarlig for å holde forretningslogikk og forretningsdata atskilt fra applikasjonstilstand. 

Faktisk er det rene databasesynet at applikasjonstilstand alltid kan utledes fra forretningsdata. Dette gjøres vanligvis ved å lagre applikasjonstilstand som et sett med transaksjoner som endrer forretningsdata i databasen. Det er lettest å tenke på dette som en database som kan kjøre kodeblokker med de samme sterke garantiene som arbeidsflytsystemene beskrevet ovenfor. 

Internt kaller vi dette applikasjonslogikk-transaksjonsplattform (ALTP) tilnærming fordi den til syvende og sist utvider OLTP-transaksjoner inn i applikasjonen. Men det som virkelig kjennetegner ALTP er at for greenfield-apper kan det helt unngå behovet for apputviklerne til å administrere back-end-infrastrukturen direkte.  

Fra ALTP-objektivet startet den mest brukte tilnærmingen med Firebase, som tilbyr en full-service "back-end opplevelse," inkludert auth, datalager, databaser og mer. Firebase og nyere aktører, som Supabase, er fortsatt svært populære plattformer for greenfield-prosjekter. Og selv om de har en tendens til å være trofaste til OLTP-røtter – og derfor ikke støtter vilkårlig kodekjøring for transaksjonelle back-end-funksjoner – begynner Supabase allerede å legge til støtte for arbeidsflyter.

Imidlertid neste generasjons ALTP-tilbud som Convex tillater kjøring av vilkårlig kode som en transaksjon ved siden av databasen. Disse tilbudene gjør det mulig å skrive fullstendig transaksjonskompatibel kode på et normalt språk (f.eks. Javascript/Typescript), der en enkelt kodeblokk kan lese, skrive og mutere data – både applikasjonstilstand og forretningsdata. På en måte gir det utviklere en enkelt spørrebar kilde til sannhet, og gir arbeidsflytprimitiver som abonnementer. 

ALTP løser problemet arbeidsflytmotorer har med å være frakoblet fra databasen, men krever som et resultat at brukerne stoler på databasetilbudet deres i stedet for en standard OLTP for å få fordelene. Som et resultat ser vi først og fremst at team tar i bruk ALTP for greenfield-apper, i stedet for å integrere det i eksisterende, komplekse backends.

The Modern Transactional Stack PlatoBlockchain Data Intelligence. Vertical Search. Ai.

Diagrammet ovenfor er en blanding av de mange operatørene vi snakket med. Noen vil bare bruke en arbeidsflytmotor. Noen vil bare bruke en databasesentrisk tilnærming. Men mange vil bruke begge deler - spesielt når de akkurat begynner å ta i bruk arbeidsflyter. Brukere av arbeidsflytmotorer i dag har en tendens til å være back-end-team som arbeider med store, komplekse applikasjoner, selv om vi også har sett mange fullstack-team som tar dem i bruk. Back-end-as-a-service-løsninger har en tendens til å være mer applikasjonsutviklervennlige og brukes oftere når appen driver teknologivalg. 

Konvergensen

Det begynner å bli klart at arbeidsflytsentriske tilnærminger og databasesentriske tilnærminger er på kollisjonskurs. Den primære grunnen til dette er at selv om applikasjonstilstand og databasetilstand er logisk forskjellige, er de avhengige av hverandre, og et system som ikke dekker begge deler er komplisert å rette opp og feilsøke.  

Som et eksempel kan du vurdere en arbeidsflytmotor som brukes til å spore tilstandsmaskinen for en brukers betalingsprosess, og den brukeren legger til en vare i en handlekurv. Vanligvis sørger arbeidsflytmotorer for at et kodetrinn vil kjøre selv i tilfelle feil. Det kan imidlertid være tilfeller der motoren må kjøre et gitt trinn på nytt under en feil fordi den ikke er helt sikker på om trinnet ble fullstendig fullført. Hvis dette trinnet innebærer å skrive forretningsdata til en tradisjonell database (i dette tilfellet varen i handlekurven) og databasen ikke er klar over det duplikatforsøket, vil det ende opp med en duplikatoppføring. 

Det er to måter å håndtere dette på. En måte er å sende problemet til applikasjonsutvikleren, som vil bruke en nonce levert av arbeidsflytsystemet for å sikre at bare ett element skrives. Men det forutsetter at utvikleren forstår idempotens, som er notorisk vanskelig å få til, og dette unngår mye av magien ved å ha et arbeidsflytsystem. Den andre måten er å knytte arbeidsflytmotoren til en database som er klar over transaksjonssemantikken for arbeidsflyten. Dette har ikke helt skjedd ennå, men det er ikke vanskelig å tro at det vil skje. 

På den annen side innser databasesentriske tilnærminger at generell arbeidsflyt er veldig nyttig for applikasjonsutviklere. Så vi begynner å se databaser (som Convex) – som støtter tradisjonelle databasefunksjoner som spørringer, mutasjoner, indekser osv. – implementere funksjonalitet som planlegging og abonnementer. Disse gjør at de kan brukes som arbeidsflytmotorer. Det vil si at de tillater kjøring av vilkårlige kodeblokker med sterke garantier. 

Som Ian Livingstone (som ga tilbakemelding på dette stykket) sa det, "Det er den klassiske "Bringer du applikasjonslogikken til databasen, eller databasen til applikasjonslogikken?" spiller ut igjen … denne gangen forårsaket av å bryte opp monolitten.» Etter å ha hatt den dikotomien i flere tiår, er det klart at begge modellene vil vedvare på kort sikt. Det er langt mindre klart at det vil forbli tilfellet i det lange løp. 

Spesiell takk til Charly Poly (Defer), Dan Farrelly (Inngest), David Khourshid (Stately), Ian Livingstone (Cape Security), Enes Akar (Upstash), James Cowling (Convex), Jamie Turner (Convex), Paul Copplestone (Supabase) ), Sam Lambert (PlanetScale), Tony Holdstock-Brown (Inngest), Matt Aitken (Trigger) for å ha gjennomgått dette innlegget og gitt tilbakemelding. I tillegg, takk til Benjamin Hindman (Reboot), Fredrik Björk (Grafbase), Glauber Costa (Chiselstrike), Guillaume Salles (Liveblocks), Maxim Fateev (Temporal), Steven Fabre (Liveblocks) og Viren Baraiya (Orkes) for å hjelpe oss med forskningen.

* * *

Synspunktene som uttrykkes her er de fra individuelle AH Capital Management, LLC (“a16z”) personell som er sitert og er ikke synspunktene til a16z eller dets tilknyttede selskaper. Visse opplysninger her er innhentet fra tredjepartskilder, inkludert fra porteføljeselskaper av fond forvaltet av a16z. Selv om a16z er hentet fra kilder som antas å være pålitelige, har ikke a16z uavhengig verifisert slik informasjon og gir ingen representasjoner om den varige nøyaktigheten til informasjonen eller dens hensiktsmessighet for en gitt situasjon. I tillegg kan dette innholdet inkludere tredjepartsannonser; aXNUMXz har ikke vurdert slike annonser og støtter ikke noe reklameinnhold som finnes deri.

Dette innholdet er kun gitt for informasjonsformål, og bør ikke stoles på som juridisk, forretningsmessig, investerings- eller skatterådgivning. Du bør rådføre deg med dine egne rådgivere om disse sakene. Referanser til verdipapirer eller digitale eiendeler er kun for illustrasjonsformål, og utgjør ikke en investeringsanbefaling eller tilbud om å tilby investeringsrådgivningstjenester. Videre er dette innholdet ikke rettet mot eller ment for bruk av noen investorer eller potensielle investorer, og kan ikke under noen omstendigheter stoles på når du tar en beslutning om å investere i et fond som forvaltes av a16z. (Et tilbud om å investere i et a16z-fond vil kun gis av det private emisjonsmemorandumet, tegningsavtalen og annen relevant dokumentasjon for et slikt fond og bør leses i sin helhet.) Eventuelle investeringer eller porteføljeselskaper nevnt, referert til, eller beskrevet er ikke representative for alle investeringer i kjøretøy forvaltet av a16z, og det kan ikke gis noen garanti for at investeringene vil være lønnsomme eller at andre investeringer som gjøres i fremtiden vil ha lignende egenskaper eller resultater. En liste over investeringer foretatt av fond forvaltet av Andreessen Horowitz (unntatt investeringer som utstederen ikke har gitt tillatelse til at a16z kan offentliggjøre så vel som uanmeldte investeringer i børsnoterte digitale eiendeler) er tilgjengelig på https://a16z.com/investments /.

Diagrammer og grafer gitt i er kun for informasjonsformål og bør ikke stoles på når du tar investeringsbeslutninger. Tidligere resultater er ikke en indikasjon på fremtidige resultater. Innholdet taler kun fra den angitte datoen. Eventuelle anslag, estimater, prognoser, mål, prospekter og/eller meninger uttrykt i dette materialet kan endres uten varsel og kan avvike eller være i strid med meninger uttrykt av andre. Vennligst se https://a16z.com/disclosures for ytterligere viktig informasjon.

Tidstempel:

Mer fra Andreessen Horowitz