De moderne transactiestapel

De moderne transactiestapel

De moderne transactionele stapel PlatoBlockchain-data-intelligentie. Verticaal zoeken. Ai.

Transactionele databases zijn lange tijd het meest kritieke onderdeel geweest van applicatieontwerp. Waarom? Omdat een standvastige database over het algemeen het ultieme handhavingspunt is voor correctheid in een rommelige, gedistribueerde wereld. Zonder hen zouden we te veel en te weinig betalen. We zouden passagiers kwijtraken die van het vliegveld naar huis probeerden te komen, en we zouden items in onze winkelwagentjes kwijtraken. Onze online accounts zouden verloren gaan, gedupliceerd of beschadigd raken en onbruikbaar worden. 

In feite is de transactiedatabase (meestal OLTP genoemd - een afkorting van online transactieverwerking - database) zo centraal geweest in de ontwikkeling van applicaties dat het in de loop van de tijd steeds meer applicatiefunctionaliteit in beslag nam. Microservices en andere moderne applicatie-architecturen zorgden echter voor nieuwe complexiteiten in het ontwerp van applicaties: ontwikkelaars moesten gegevens over verschillende services beheren en zorgen voor consistentie daartussen, waardoor ze gedwongen werden om intern complexe mechanismen voor gegevenssynchronisatie en -verwerking te bouwen. 

En dus zien we als branche een toenemend besef dat transactiegaranties nodig zijn buiten het traditionele model om. We zien de opkomst van systemen die sterke transactiegaranties uitbreiden buiten de database, tot in de gedistribueerde apps zelf

We hebben deze oplossingen de afgelopen jaren gevolgd. Over het algemeen streven ze ernaar om transactioneel statusbeheer mogelijk te maken in een grote gedistribueerde app, zonder schaalproblemen te creëren en tegelijkertijd een moderne programmeeromgeving te bieden. 

We vinden dat deze oplossingen grofweg in twee categorieën kunnen worden onderverdeeld. Een categorie is werkstroom orkestratie. Dit garandeert in feite dat een codeblok volledig wordt uitgevoerd, zelfs als het mislukt. Het kan dus worden gebruikt om een ​​gedistribueerde toestandsmachine deterministisch te beheren zonder gek te worden. De tweede categorie is database + werkstroom, dat het traditionele OLTP-databaseontwerp uitbreidt, waardoor willekeurige code voor hetzelfde doel kan worden uitgevoerd. 

Dit is nog een zeer ontluikend gebied en er is veel verwarring over de nomenclatuur, hoe elk hulpmiddel in de praktijk wordt gebruikt en wie ze zou moeten gebruiken. Om een ​​beter begrip te krijgen, vroegen we professionals van toonaangevende technische organisaties naar hun transactionele stack en hoe ze denken over drie sleutelconcepten voor transactionele workloads: applicatiestatus, bedrijfslogica en bedrijfsgegevens. 

Maar voordat we deze nieuwe stapels onderzoeken, volgt hier een korte semi-technische uitweiding om te helpen begrijpen hoe we hier zijn gekomen.

Transacties, garanties en moderne apps 

De zeer grove versie is deze: er is een reeks taken - transacties - die u ofwel allemaal wilt doen, ofwel geen enkele. Alles daar tussenin (het gedeeltelijk laten doen) zal eindigen in een corrupte staat. Het is moeilijk te garanderen iets in een gedistribueerd systeem, maar databases doen het goed met transacties. Daarom is de gemakkelijkste manier om met garanties in veel systemen om te gaan, gewoon de meeste dingen transacties te doen en de database ze te laten afhandelen.

Moderne apps zijn grote gedistribueerde systemen met veel gebruikers die van alles doen. Dus zelfs het consistent houden van de app-status (zoals bijhouden waar verschillende gebruikers zich in een uitcheckstroom bevinden) wordt een gedistribueerd transactieprobleem. In traditionele monolithische architecturen was het beheren van transacties met behulp van SQL met een OLTP-database enigszins effectief. Maar in de nieuwe, complexe wereld van microservices die samenwerken via API's op een hoger niveau (bijv. REST of gRPC), zijn transactiebehoeften gedistribueerd van aard geworden. 

Veel bedrijven die op weg zijn naar microservices, hebben echter niet veel gedaan om sterke transactiegaranties buiten de database uit te breiden. En dat is in de praktijk ook zo bijna altijd OK. Maar naarmate toepassingen groter worden, nemen de inconsistenties in gegevens toe, net als de resulterende fouten en niet-afgestemde fouten in bedrijfsgegevens. Wat natuurlijk enorm problematisch kan zijn. Dit dwingt applicatieontwikkelaars om te gaan met een breed scala aan faalscenario's en conflictoplossingsstrategieën, en om statusconsistentie te waarborgen door hun eigen strategieën te bedenken via verschillende architecturale patronen.

Definities

Bedrijfsgegevens (“gegevens”) verwijst naar de bedrijfskritische gegevens die traditioneel worden opgeslagen in een OLTP-database voor persistentie en verwerking (bijv. informatie over gebruikersprofielen zoals naam, adres, kredietscore, enz.).

Toepassingsstatus: verwijst naar de huidige status van het systeem; de applicatiestatus wordt bepaald door een waarde die is opgeslagen in een gegevensopslagsysteem en in welke stap de uitvoering van het programma zich bevindt in een finite state machine (bijv. de status van een bestelling, zoals 'bestelling ontvangen', 'inventaris gecontroleerd', 'krediet gecontroleerd , ""verzonden", "geretourneerd").

Bedrijfslogica verwijst naar het deel van het programma dat zich bezighoudt met hoe de applicatie werkelijk werkt of wat het doet, in plaats van uitvoeringsdetails (bijv. "Als gebruiker_inkomen > $100K & krediet_score >650 ⇒ hypotheek_goedgekeurd = WAAR").

Voor de doeleinden van deze discussie is het belangrijk om onderscheid te maken tussen toepassingsstatus en bedrijfsgegevens. Weten dat een klant bijvoorbeeld zijn creditcard heeft ingevoerd maar niet heeft uitgecheckt, is de aanvraagstatus. De gegevens van de creditcard en de artikelen in de applicatiekar zijn de zakelijke gegevens. 

De moderne transactionele stapel PlatoBlockchain-data-intelligentie. Verticaal zoeken. Ai.

In een typische stroom komt een verzoek van de front-end, wordt geverifieerd en vervolgens via een API-gateway of GraphQL naar het relevante eindpunt geleid. 

Dat enkele API-eindpunt moet nu tientallen of honderden microservices orkestreren om de zakelijke transactie aan de eindklant te leveren. Dit is waar ontwikkelaars doorgaans alles op één hoop gooien in bedrijfslogica-blobs en vervolgens een combinatie van wachtrijen, caches en met de hand gecodeerde mechanismen voor opnieuw proberen gebruiken om de gegevens naar de database te krijgen - hopelijk vastgelegd als een volledige transactie.

Naarmate de schaal van de applicatie toeneemt, neemt ook de complexiteit van het beheer van wachtrijen en caches toe, evenals het aantal scherpe randen in afstemmingslogica wanneer zich problemen voordoen. 

De opkomst van workflow-centrische en database-centrische transactionele stacks

OK, transacties zijn dus belangrijk. LAMP op een database was niet voldoende voor schaal. En een gigantische haarbal van wachtrijen en logica voor opnieuw proberen is te broos. Om hiermee om te gaan, hebben we de afgelopen jaren de opkomst van nieuwe oplossingen gezien die de transactielogica weer gezond maken. Ze kunnen grofweg worden gecategoriseerd als werkstroomgerichte benaderingen of databasegerichte benaderingen.

Tot op heden werken workflow-engines voornamelijk op de status van de applicatie in plaats van op de bedrijfsgegevens, en vereisen ze vaak enige complexiteit bij de integratie met traditionele databases. Databasegerichte benaderingen voegen applicatielogica toe naast bedrijfsgegevens, maar hebben nog niet dezelfde geavanceerde code-uitvoering als workflow-engines. 

Het onderstaande diagram geeft een ruwe schets van hoe werkstroom- en/of databasegerichte benaderingen worden gebruikt in een Javascript/Typescript-toepassing, ervan uitgaande dat beide worden gebruikt. Hoewel het tegenwoordig afzonderlijke onderdelen van deze architectuur zijn, hebben we vroege tekenen gezien van een trend waarbij databases workflowfuncties bevatten en workflows duurzame opslag beginnen te gebruiken. Deze samenvoeging van mogelijkheden geeft aan dat de lijnen tussen de twee benaderingen vervagen en minder duidelijk worden in moderne architecturen. 

De moderne transactionele stapel PlatoBlockchain-data-intelligentie. Verticaal zoeken. Ai.

Workflow-centrische benaderingen in detail 

Een workflow bestaat eenvoudigweg uit codeblokken die worden uitgevoerd op basis van gebeurtenissen, of timers, die de statusmachine van de applicatie ontwikkelen. Transactionele workflow zorgt voor code-uitvoering met sterke garanties, waardoor gedeeltelijke of onbedoelde toestanden in de applicatie worden voorkomen. Ontwikkelaars schrijven de logica en de workflow-engine verwerkt transacties, mutaties en idempotentie. Verschillende workflow-engines maken verschillende afwegingen in termen van hoeveel van de transactiedetails aan de ontwikkelaars worden getoond. 

Hieronder ziet u bijvoorbeeld een visuele weergave van een uitcheckworkflow die wordt uitgevoerd op Orkes (Conductor): 

De moderne transactionele stapel PlatoBlockchain-data-intelligentie. Verticaal zoeken. Ai.

Er zijn twee ruwe benaderingen waardoor workflow-engines grip krijgen. In één (getypeerd door Temporal.io) schrijven ontwikkelaars code met behulp van standaard back-end programmeertalen (bijv. Go of Java) en de systeem zorgt ervoor dat de code volledig wordt uitgevoerd, zelfs tijdens een storing. In dit model wordt de programma-aanroep-stack behouden, zelfs als de code wacht op voltooiing van een blokkerende oproep (bijv. lezen of schrijven). Om dit te doen, wordt de taalruntime aangepast om gedeeltelijke uitvoering van code tijdens fouten te voorkomen. Het voordeel van deze aanpak is dat ontwikkelaars in vertrouwde talen kunnen schrijven en gemakkelijk kunnen debuggen met een onderhouden call-stack. We zien deze aanpak het populairst bij back-endteams die te maken hebben met grote, geavanceerde apps. 

Het nadeel is dat het vaak veel integratiewerk en wrapper-code vereist om bruikbare en veilige interfaces aan applicatieontwikkelaars bloot te leggen. Een ander nadeel is dat het afhankelijk is van een aangepaste uitvoeringslaag in plaats van de kale taal, en er zijn randgevallen waarin de uitvoering zal verschillen van de runtime in de moedertaal. Dus hoewel ontwikkelaars talen kunnen gebruiken waarmee ze vertrouwd zijn, moeten ze nog steeds begrijpen hoe het onderliggende systeem werkt.  

De andere benadering, die populairder is bij applicatieontwikkelaars (met name Typescript/Javascript), is dat de workflow-engine dienen als een orkestrator van asynchrone functies (bijv. Ingest, Defer en Trigger). In dit model worden gebeurtenissen of functies van derden doorgestuurd naar de workflow-engine, die vervolgens logica verzendt die is geregistreerd door de applicatieprogrammeurs, die de controle moeten teruggeven zodra de noodzaak ontstaat om een ​​andere asynchrone functie te blokkeren. Het voordeel is dat dit een veel lichtere methode is om in een programma te integreren. Het forceert ook voldoende structuur in de code zodat het team dat eraan werkt deze gemakkelijker kan begrijpen. Deze benadering kan echter moeilijker te debuggen zijn zonder tooling-ondersteuning, dus debuggen is meestal platformspecifiek.

Workflow-engines zijn bijzonder krachtig omdat ze geleidelijke acceptatie door bestaande apps mogelijk maken. Ze kunnen stukje bij beetje worden toegepast op bepaalde workflows met een minimale voetafdruk. Dat gezegd hebbende, de twee grootste tekortkomingen van workflow-engines komen voort uit het feit dat ze zich niet uitstrekken tot in de database. Als gevolg hiervan is er geen enkele, bevraagbare bron van waarheid over de status van applicaties en bedrijfsgegevens. Ook is de transactionele semantiek over het algemeen anders dan de database-semantiek, waardoor applicatieontwikkelaars randvoorwaarden moeten hanteren. 

Hoewel dit tegenwoordig niet de norm is, willen we de conceptuele architecturen illustreren van hoe workflows in veel gevallen kunnen worden gebruikt als persistente datastores:

Voorbeelden van Workflow-Only Architecturen

De moderne transactionele stapel PlatoBlockchain-data-intelligentie. Verticaal zoeken. Ai.

Workflow-only architectuur: JavaScript-apps

De moderne transactionele stapel PlatoBlockchain-data-intelligentie. Verticaal zoeken. Ai.

Workflow-only architectuur: apps die gebruikmaken van microservices

Databasegerichte benaderingen in detail 

Databasegerichte benaderingen beginnen met een database, maar breiden deze uit om willekeurige code-uitvoering te ondersteunen om naast gegevensbeheer ook workflows mogelijk te maken. Ze doen dit door de programmeurs controle te geven, zodat ze expliciete beslissingen kunnen nemen over mutaties, transacties en idempotentie voor reguliere codeblokken - in wezen door de OLTP-semantiek rechtstreeks bloot te leggen. De programmeur is verantwoordelijk voor het gescheiden houden van bedrijfslogica en bedrijfsgegevens van de applicatiestatus. 

De pure databaseweergave is inderdaad dat de applicatiestatus altijd kan worden afgeleid uit bedrijfsgegevens. Dit wordt meestal gedaan door de toepassingsstatus op te slaan als een reeks transacties die bedrijfsgegevens in de database wijzigen. Het is het gemakkelijkst om dit te zien als een database die codeblokken kan uitvoeren met dezelfde sterke garanties als de hierboven beschreven workflowsystemen. 

Intern noemen we dit de toepassingslogica transactieplatform (ALTP) aanpak omdat het uiteindelijk OLTP-transacties uitbreidt naar de applicatie. Maar wat ALTP echt kenmerkt, is dat het voor greenfield-apps de noodzaak voor de app-ontwikkelaars om de back-endinfrastructuur rechtstreeks te beheren, volledig kan wegnemen.  

Vanuit de ALTP-lens begon de meest gebruikte aanpak met Firebase, dat een full-service "back-end ervaring", inclusief authenticatie, gegevensopslag, databases en meer. Firebase en recentere nieuwkomers, zoals Supabase, blijven erg populaire platforms voor greenfield-projecten. En hoewel ze de neiging hebben om trouw te blijven aan hun OLTP-roots - en dus geen ondersteuning bieden voor willekeurige code-uitvoering voor transactionele back-endfuncties - begint Supabase al ondersteuning voor workflows toe te voegen.

Echter, ALTP-aanbiedingen van de volgende generatie zoals Convex staat de uitvoering van willekeurige code toe als een transactie naast de database. Deze aanbiedingen maken het mogelijk om volledig transactionele code te schrijven in een normale taal (bijv. Javascript/Typescript), waarbij een enkel codeblok gegevens kan lezen, schrijven en muteren - zowel applicatiestatus als bedrijfsgegevens. In zekere zin geeft het ontwikkelaars een enkele doorzoekbare bron van waarheid en biedt het workflow-primitieven zoals abonnementen. 

ALTP lost het probleem op dat workflow-engines hebben bij het ontkoppelen van de database, maar als gevolg daarvan moeten de gebruikers vertrouwen op hun database-aanbod in plaats van op een standaard OLTP om van de voordelen te profiteren. Als gevolg hiervan zien we dat teams ALTP vooral gebruiken voor greenfield-apps, in plaats van het te integreren in bestaande, complexe backends.

De moderne transactionele stapel PlatoBlockchain-data-intelligentie. Verticaal zoeken. Ai.

Het bovenstaande diagram is een amalgaam van de vele operators die we hebben gesproken. Sommigen zullen gewoon een workflow-engine gebruiken. Sommigen zullen gewoon een database-centrische benadering gebruiken. Maar velen zullen beide gebruiken, vooral wanneer ze net beginnen met het adopteren van workflows. Gebruikers van workflow-engines zijn tegenwoordig meestal back-endteams die zich bezighouden met grote, complexe applicaties, hoewel we ook hebben gezien dat veel full-stack teams deze hebben overgenomen. Back-end-as-a-service-oplossingen zijn over het algemeen applicatieontwikkelaarvriendelijker en worden vaker gebruikt wanneer de app de technologieselectie aanstuurt. 

De convergentie

Het wordt duidelijk dat workflowgerichte benaderingen en databasegerichte benaderingen op ramkoers liggen. De belangrijkste reden hiervoor is dat, hoewel de status van de applicatie en de database logisch gescheiden zijn, ze van elkaar afhankelijk zijn, en een systeem dat niet beide dekt, is complex om goed te krijgen en te debuggen.  

Neem als voorbeeld een workflow-engine die wordt gebruikt om de statusmachine te volgen voor het afrekenproces van een gebruiker, en die gebruiker voegt een item toe aan een winkelwagentje. Doorgaans zorgen workflow-engines ervoor dat een codestap wordt uitgevoerd, zelfs in het geval van een storing. Er kunnen echter gevallen zijn waarin de engine een bepaalde stap opnieuw moet uitvoeren tijdens een storing, omdat het niet helemaal zeker is of de stap volledig is voltooid. Als die stap het schrijven van bedrijfsgegevens naar een traditionele database inhoudt (in dit geval het item in de winkelwagen) en de database niet op de hoogte is van de dubbele nieuwe poging, zal het eindigen met een dubbele invoer. 

Er zijn twee manieren om hiermee om te gaan. Eén manier is om het probleem naar de toepassingsontwikkelaar te sturen, die een nonce van het werkstroomsysteem zal gebruiken om ervoor te zorgen dat er slechts één item wordt geschreven. Maar dat veronderstelt dat de ontwikkelaar idempotentie begrijpt, wat notoir lastig is om goed te krijgen, en dit maakt veel van de magie van het hebben van een workflowsysteem overbodig. De andere manier is om de workflow-engine te koppelen aan een database die op de hoogte is van de transactionele semantiek van de workflow. Dit is nog niet helemaal gebeurd, maar het is niet moeilijk te geloven dat het zal gebeuren. 

Aan de andere kant realiseren databasegerichte benaderingen zich dat algemene workflow erg nuttig is voor applicatieontwikkelaars. En dus beginnen we databases (zoals Convex) te zien - die traditionele databasefuncties ondersteunen zoals query's, mutaties, indexen, enz. - functionaliteit implementeren zoals planning en abonnementen. Hierdoor kunnen ze worden gebruikt als workflow-engines. Dat wil zeggen, ze maken de uitvoering van willekeurige codeblokken met sterke garanties mogelijk. 

Zoals Ian Livingstone (die feedback gaf op dit stuk) het verwoordde: "Het is de klassieker 'Breng je de applicatielogica naar de database, of de database naar de applicatielogica?' weer aan het spelen … dit keer veroorzaakt door het opbreken van de monoliet. Na tientallen jaren die tweedeling te hebben gehad, is het duidelijk dat beide modellen op korte termijn zullen blijven bestaan. Het is veel minder duidelijk dat dit op de lange termijn het geval zal blijven. 

Speciale dank aan 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) voor het beoordelen van dit bericht en het geven van feedback. Daarnaast willen we Benjamin Hindman (Reboot), Fredrik Björk (Grafbase), Glauber Costa (Chiselstrike), Guillaume Salles (Liveblocks), Maxim Fateev (Temporal), Steven Fabre (Liveblocks) en Viren Baraiya (Orkes) bedanken voor hun hulp bij het onderzoek.

* * *

De standpunten die hier naar voren worden gebracht, zijn die van het individuele personeel van AH Capital Management, LLC (“a16z”) dat wordt geciteerd en zijn niet de standpunten van a16z of haar gelieerde ondernemingen. Bepaalde informatie in dit document is verkregen uit externe bronnen, waaronder van portefeuillebedrijven van fondsen die worden beheerd door a16z. Hoewel ontleend aan bronnen die betrouwbaar worden geacht, heeft a16z dergelijke informatie niet onafhankelijk geverifieerd en doet het geen uitspraken over de blijvende nauwkeurigheid van de informatie of de geschiktheid ervan voor een bepaalde situatie. Bovendien kan deze inhoud advertenties van derden bevatten; a16z heeft dergelijke advertenties niet beoordeeld en keurt de daarin opgenomen advertentie-inhoud niet goed.

Deze inhoud is uitsluitend bedoeld voor informatieve doeleinden en mag niet worden beschouwd als juridisch, zakelijk, investerings- of belastingadvies. U dient hierover uw eigen adviseurs te raadplegen. Verwijzingen naar effecten of digitale activa zijn alleen voor illustratieve doeleinden en vormen geen beleggingsaanbeveling of aanbod om beleggingsadviesdiensten te verlenen. Bovendien is deze inhoud niet gericht op of bedoeld voor gebruik door beleggers of potentiële beleggers, en mag er in geen geval op worden vertrouwd bij het nemen van een beslissing om te beleggen in een fonds dat wordt beheerd door a16z. (Een aanbod om te beleggen in een a16z-fonds wordt alleen gedaan door middel van het onderhandse plaatsingsmemorandum, de inschrijvingsovereenkomst en andere relevante documentatie van een dergelijk fonds en moet in hun geheel worden gelezen.) Alle genoemde beleggingen of portefeuillebedrijven waarnaar wordt verwezen, of beschreven zijn niet representatief voor alle investeringen in voertuigen die door a16z worden beheerd, en er kan geen garantie worden gegeven dat de investeringen winstgevend zullen zijn of dat andere investeringen die in de toekomst worden gedaan vergelijkbare kenmerken of resultaten zullen hebben. Een lijst van investeringen die zijn gedaan door fondsen die worden beheerd door Andreessen Horowitz (met uitzondering van investeringen waarvoor de uitgevende instelling geen toestemming heeft gegeven aan a16z om openbaar te maken, evenals onaangekondigde investeringen in openbaar verhandelde digitale activa) is beschikbaar op https://a16z.com/investments /.

De grafieken en grafieken die hierin worden verstrekt, zijn uitsluitend bedoeld voor informatieve doeleinden en er mag niet op worden vertrouwd bij het nemen van een investeringsbeslissing. In het verleden behaalde resultaten zijn geen indicatie voor toekomstige resultaten. De inhoud spreekt alleen vanaf de aangegeven datum. Alle projecties, schattingen, voorspellingen, doelstellingen, vooruitzichten en/of meningen die in deze materialen worden uitgedrukt, kunnen zonder voorafgaande kennisgeving worden gewijzigd en kunnen verschillen of in strijd zijn met meningen van anderen. Zie https://a16z.com/disclosures voor aanvullende belangrijke informatie.

Tijdstempel:

Meer van Andreessen Horowitz