Hvordan vi byggede kernen i Alfa-Banks investeringsforretning baseret på Tarantool

Hvordan vi byggede kernen i Alfa-Banks investeringsforretning baseret på Tarantool
Still fra filmen "Our Secret Universe: The Hidden Life of the Cell"

Investeringsvirksomheden er et af de mest komplekse områder i bankverdenen, fordi der ikke kun er lån, lån og indlån, men også værdipapirer, valutaer, råvarer, derivater og alverdens kompleksiteter i form af strukturerede produkter.

På det seneste har vi set en stigning i befolkningens økonomiske kompetencer. Flere og flere mennesker bliver involveret i handel på værdipapirmarkederne. Individuelle investeringskonti dukkede op for ikke så længe siden. De giver dig mulighed for at handle på værdipapirmarkederne og enten modtage skattefradrag eller undgå at betale skat. Og alle kunder, der kommer til os, ønsker at administrere deres portefølje og se rapportering i realtid. Desuden er denne portefølje oftest multiprodukt, det vil sige, at folk er kunder i forskellige forretningsområder.

Derudover vokser behovene hos regulatorer, både russiske og udenlandske.

For at imødekomme nuværende behov og lægge grundlaget for fremtidige opgraderinger har vi udviklet en investeringsforretningskerne baseret på Tarantool.

Nogle statistikker. Alfa-Banks investeringsvirksomhed leverer mæglertjenester til enkeltpersoner og juridiske enheder for at give mulighed for at handle på forskellige værdipapirmarkeder, depottjenester til opbevaring af værdipapirer, trust management-tjenester til enkeltpersoner med privat og stor kapital, tjenester til udstedelse af værdipapirer for andre virksomheder . Alfa-Banks investeringsvirksomhed omfatter mere end 3 tusinde kurser i sekundet, som downloades fra forskellige handelsplatforme. I løbet af arbejdsdagen afsluttes mere end 300 tusinde transaktioner på markederne på vegne af banken eller dens kunder. Op til 5 tusinde ordreudførelser pr. sekund forekommer på eksterne og interne platforme. Samtidig ønsker alle kunder, både interne og eksterne, at se deres positioner i realtid.

forhistorie

Et sted fra begyndelsen af ​​2000'erne udviklede vores investeringsområder sig selvstændigt: børshandel, mæglertjenester, valutahandel, håndkøbshandel med værdipapirer og forskellige derivater. Som et resultat er vi faldet i fælden med funktionelle brønde. Hvad er det? Hver branche har sine egne systemer, der duplikerer hinandens funktioner. Hvert system har sin egen datamodel, selvom de opererer med de samme koncepter: transaktioner, instrumenter, modparter, kurser og så videre. Og efterhånden som hvert system udviklede sig uafhængigt, opstod en mangfoldig zoologisk have af teknologier.

Derudover er systemernes kodebase allerede ret forældet, fordi nogle produkter stammer fra midten af ​​1990'erne. Og på nogle områder bremsede dette udviklingsprocessen, og der var præstationsproblemer.

Krav til ny løsning

Virksomheder har indset, at teknologisk transformation er afgørende for videre udvikling. Vi fik opgaver:

  1. Saml alle forretningsdata i en enkelt, hurtig lagring og i en enkelt datamodel.
  2. Vi må ikke miste eller ændre disse oplysninger.
  3. Det er nødvendigt at versionere dataene, fordi regulatoren til enhver tid kan bede om statistik for tidligere år.
  4. Vi skal ikke bare bringe nogle nye, moderigtige DBMS, men skabe en platform til at løse forretningsmæssige problemer.

Derudover stiller vores arkitekter deres egne betingelser:

  1. Den nye løsning skal være i enterprise-klasse, det vil sige, at den allerede skal afprøves i nogle store virksomheder.
  2. Løsningens driftstilstand bør være missionskritisk. Det betyder, at vi skal være til stede i flere datacentre samtidigt og roligt overleve udfaldet af ét datacenter.
  3. Systemet skal være vandret skalerbart. Faktum er, at alle vores nuværende systemer kun er vertikalt skalerbare, og vi rammer allerede loftet på grund af den lave vækst af hardwarekraft. Derfor er det øjeblik kommet, hvor vi skal have et horisontalt skalerbart system for at overleve.
  4. Vi fik blandt andet at vide, at løsningen skulle være billig.

Vi fulgte standardruten: Vi formulerede kravene og kontaktede indkøbsafdelingen. Derfra modtog vi en liste over virksomheder, der generelt er klar til at gøre dette for os. Vi fortalte alle om problemet, og fik en vurdering af løsningerne fra seks af dem.

I banken tager vi ikke nogens ord for det, vi kan godt lide at teste alt selv. Derfor var en obligatorisk betingelse for vores udbudskonkurrence at bestå belastningsprøver. Vi formulerede belastningstestopgaver, og tre ud af seks virksomheder har allerede sagt ja til at implementere en prototypeløsning baseret på in-memory-teknologier for egen regning for at teste den.

Jeg vil ikke fortælle dig, hvordan vi testede alt, og hvor lang tid det tog, jeg vil bare opsummere: den bedste ydeevne i belastningstests blev vist af en prototypeløsning baseret på Tarantool fra Mail.ru Groups udviklingsteam. Vi underskrev en aftale og begyndte udviklingen. Der var fire personer fra Mail.ru Group, og fra Alfa-Bank var der tre udviklere, tre systemanalytikere, en løsningsarkitekt, en produktejer og en Scrum-master.

Dernæst vil jeg fortælle dig om, hvordan vores system voksede, hvordan det udviklede sig, hvad vi gjorde, og hvorfor netop dette.

design

Det første spørgsmål, vi stillede os selv, var, hvordan vi henter data fra vores nuværende systemer. Vi besluttede, at HTTP var ganske passende for os, fordi alle nuværende systemer kommunikerer med hinanden ved at sende XML eller JSON over HTTP.

Vi bruger HTTP-serveren indbygget i Tarantool, fordi vi ikke behøver at afslutte SSL-sessioner, og dens ydeevne er nok for os.

Som jeg allerede sagde, lever alle vores systemer i forskellige datamodeller, og ved input skal vi bringe objektet til den model, vi selv beskriver. Der var brug for et sprog, der gjorde det muligt at transformere data. Vi valgte imperativ Lua. Vi kører al datakonverteringskode i en sandkasse - dette er et sikkert sted, hvorfra den kørende kode ikke går. For at gøre dette indlæser vi simpelthen den nødvendige kode, og skaber et miljø med funktioner, der ikke kan blokere eller slippe noget.

Hvordan vi byggede kernen i Alfa-Banks investeringsforretning baseret på Tarantool
Efter konvertering skal dataene kontrolleres for overensstemmelse med den model, vi opretter. Vi diskuterede i lang tid, hvad modellen skulle være, og hvilket sprog vi skulle bruge til at beskrive den. Vi valgte Apache Avro, fordi sproget er enkelt, og det har understøttelse fra Tarantool. Nye versioner af modellen og brugerdefineret kode kan sættes i drift flere gange om dagen, selv under belastning eller uden, på ethvert tidspunkt af dagen og tilpasse sig ændringer meget hurtigt.

Hvordan vi byggede kernen i Alfa-Banks investeringsforretning baseret på Tarantool
Efter verifikation skal dataene gemmes. Vi gør dette ved hjælp af vshard (vi har geo-spredning af shards).

Hvordan vi byggede kernen i Alfa-Banks investeringsforretning baseret på Tarantool
Desuden er specificiteten sådan, at de fleste systemer, der sender os data, er ligeglade med, om vi har modtaget dem eller ej. Derfor implementerede vi en reparationskø helt fra begyndelsen. Hvad er det? Hvis et objekt af en eller anden grund ikke gennemgår datatransformation eller verifikation, bekræfter vi stadig modtagelsen, men gemmer samtidig objektet i reparationskøen. Det er konsekvent og placeret i virksomhedens vigtigste datavarehus. Vi skrev straks en administratorgrænseflade til det, forskellige metrics og advarsler. Som følge heraf mister vi ikke data. Selvom noget er ændret i kilden, hvis datamodellen har ændret sig, vil vi straks opdage det og kan tilpasse os.

Hvordan vi byggede kernen i Alfa-Banks investeringsforretning baseret på Tarantool
Nu skal du lære, hvordan du henter gemte data. Vi analyserede omhyggeligt vores systemer og så, at den klassiske stak af Java og Oracle nødvendigvis indeholder en form for ORM, der konverterer data fra relationel til objekt. Så hvorfor ikke straks give objekter til systemer i form af en graf? Så vi adopterede med glæde GraphQL, som opfyldte alle vores behov. Det giver dig mulighed for at modtage data i form af grafer og kun trække det ud, du har brug for lige nu. Du kan endda versionere API'et med ret stor fleksibilitet.

Hvordan vi byggede kernen i Alfa-Banks investeringsforretning baseret på Tarantool
Næsten med det samme indså vi, at de data, vi udtog, ikke var nok. Vi har skabt funktioner, der kan knyttes til objekter i modellen - i det væsentlige beregnede felter. Det vil sige, at vi knytter en bestemt funktion til feltet, som fx beregner den gennemsnitlige tilbudspris. Og den eksterne forbruger, der efterspørger dataene, ved ikke engang, at dette er et beregnet felt.

Hvordan vi byggede kernen i Alfa-Banks investeringsforretning baseret på Tarantool
Implementeret et autentificeringssystem.

Hvordan vi byggede kernen i Alfa-Banks investeringsforretning baseret på Tarantool
Så bemærkede vi, at flere roller udkrystalliserede sig i vores beslutning. En rolle er en slags aggregator af funktioner. Typisk har roller forskellige udstyrsbrugsprofiler:

  • T-Connect: håndterer indgående forbindelser, CPU begrænset, lavt hukommelsesforbrug, tilstandsløs.
  • IB-Core: transformerer de data, den modtager via Tarantool-protokollen, det vil sige, den opererer med tabeller. Den gemmer heller ikke tilstand og er skalerbar.
  • Opbevaring: gemmer kun data, bruger ingen logik. Denne rolle implementerer de enkleste grænseflader. Skalerbar takket være vshard.

Hvordan vi byggede kernen i Alfa-Banks investeringsforretning baseret på Tarantool
Det vil sige, at vi ved hjælp af roller afkoblede forskellige dele af klyngen fra hinanden, som kan skaleres uafhængigt af hinanden.

Så vi har oprettet en asynkron registrering af transaktionsdataflow og en reparationskø med en admin-grænseflade. Optagelsen er asynkron fra et forretningsmæssigt synspunkt: Hvis vi med garanti vil skrive data til os selv, uanset hvor, så bekræfter vi det. Hvis det ikke er bekræftet, så gik noget galt, og dataene skal sendes. Dette er den asynkrone optagelse.

Test

Allerede fra starten af ​​projektet besluttede vi, at vi ville forsøge at implementere testdrevet udvikling. Vi skriver enhedstests i Lua ved hjælp af tarantool/tap-rammeværket, og integrationstest i Python ved hjælp af pytest-rammeværket. Samtidig inddrager vi både udviklere og analytikere i at skrive integrationstests.

Hvordan bruger vi testdrevet udvikling?

Hvis vi vil have en ny funktion, prøver vi først at skrive en test for den. Når vi opdager en fejl, sørger vi for først at skrive en test, og først derefter rette den. I starten er det svært at arbejde på denne måde, der er misforståelser fra medarbejdernes side, endda sabotage: "Lad os hurtigt ordne det nu, gøre noget nyt og så dække det med test." Kun dette "senere" kommer næsten aldrig.

Derfor skal du tvinge dig selv til at skrive test først og bede andre om at gøre det. Tro mig, testdrevet udvikling giver fordele selv på kort sigt. Du vil føle, at dit liv er blevet lettere. Vi føler, at 99% af koden nu er dækket af tests. Det ser ud til at være meget, men vi har ingen problemer: test kører på hver commit.

Men det, vi elsker allermest, er belastningstest; vi anser det for det vigtigste og udfører det regelmæssigt.

Jeg vil fortælle dig en lille historie om, hvordan vi udførte den første fase af belastningstest af en af ​​de første versioner. Vi installerede systemet på udviklerens bærbare computer, tændte for belastningen og fik 4 tusinde transaktioner i sekundet. Godt resultat for en bærbar computer. Vi installerede det på en virtuel indlæsningsbænk med fire servere, svagere end i produktionen. Indsat til et minimum. Vi kører det, og vi får et dårligere resultat end på en bærbar computer i én tråd. Chokindhold.

Vi var meget kede af det. Vi ser på serverbelastningen, men det viser sig, at de er inaktive.

Hvordan vi byggede kernen i Alfa-Banks investeringsforretning baseret på Tarantool
Vi ringer til udviklerne, og de forklarer os, folk, der kommer fra Javas verden, at Tarantool er single-threaded. Det kan kun bruges effektivt af én processorkerne under belastning. Derefter implementerede vi det maksimalt mulige antal Tarantool-instanser på hver server, tændte for belastningen og modtog allerede 14,5 tusinde transaktioner i sekundet.

Hvordan vi byggede kernen i Alfa-Banks investeringsforretning baseret på Tarantool
Lad mig forklare igen. På grund af opdelingen i roller, der bruger ressourcer forskelligt, belastede vores roller med ansvar for behandling af forbindelser og datatransformation kun processoren og strengt proportional med belastningen.

Hvordan vi byggede kernen i Alfa-Banks investeringsforretning baseret på Tarantool
Hvordan vi byggede kernen i Alfa-Banks investeringsforretning baseret på Tarantool
I dette tilfælde blev hukommelsen kun brugt til at behandle indgående forbindelser og midlertidige objekter.

Hvordan vi byggede kernen i Alfa-Banks investeringsforretning baseret på Tarantool
Tværtimod, på lagerservere steg processorbelastningen, men meget langsommere end på servere, der behandler forbindelser.

Hvordan vi byggede kernen i Alfa-Banks investeringsforretning baseret på Tarantool
Og hukommelsesforbruget voksede i direkte forhold til mængden af ​​indlæst data.

Hvordan vi byggede kernen i Alfa-Banks investeringsforretning baseret på Tarantool

Services

For at udvikle vores nye produkt specifikt som en applikationsplatform, skabte vi en komponent til at implementere tjenester og biblioteker på den.

Tjenester er ikke bare små stykker kode, der opererer på nogle felter. De kan være ret store og komplekse strukturer, der er en del af en klynge, kontrollerer referencedata, kører forretningslogik og returnerer svar. Vi eksporterer også serviceskemaet til GraphQL, og forbrugeren får et universelt adgangspunkt til dataene, med introspektion på tværs af hele modellen. Det er meget behageligt.

Da tjenester indeholder mange flere funktioner, besluttede vi, at der skulle være biblioteker, hvor vi vil flytte hyppigt brugt kode. Vi føjede dem til det sikre miljø, efter at have kontrolleret, at det ikke går i stykker for os. Og nu kan vi tildele yderligere miljøer til funktioner i form af biblioteker.

Vi ønskede ikke kun at have en platform til opbevaring, men også til computere. Og da vi allerede havde en masse replikaer og skår, implementerede vi en slags distribueret databehandling og kaldte det kortreducering, fordi det viste sig at ligne den originale kortreduktion.

Gamle systemer

Ikke alle vores ældre systemer kan kalde os over HTTP og bruge GraphQL, selvom de understøtter protokollen. Derfor skabte vi en mekanisme, der gør det muligt at replikere data ind i disse systemer.

Hvordan vi byggede kernen i Alfa-Banks investeringsforretning baseret på Tarantool
Hvis noget ændrer sig for os, udløses unikke triggere i Storage-rollen, og beskeden med ændringerne ender i behandlingskøen. Det sendes til et eksternt system ved hjælp af en separat replikatorrolle. Denne rolle gemmer ikke tilstand.

Nye forbedringer

Som du husker, lavede vi fra et forretningsmæssigt synspunkt asynkron optagelse. Men så indså de, at det ikke ville være nok, for der er en klasse af systemer, der straks skal modtage et svar om status for operationen. Så vi udvidede vores GraphQL og tilføjede mutationer. De passer organisk ind i det eksisterende paradigme med at arbejde med data. For os er dette et enkelt punkt for både læsning og skrivning for en anden klasse af systemer.

Hvordan vi byggede kernen i Alfa-Banks investeringsforretning baseret på Tarantool
Vi indså også, at tjenester alene ikke ville være nok for os, fordi der er ret tunge rapporter, der skal bygges en gang om dagen, om ugen, om måneden. Dette kan tage lang tid, og rapporter kan endda blokere Tarantools begivenhedsløkke. Derfor oprettede vi separate roller: skemalægger og løber. Løbere opbevarer ikke tilstand. De kører tunge opgaver, som vi ikke kan beregne i farten. Og skemalæggerrollen overvåger startplanen for disse opgaver, som er beskrevet i konfigurationen. Selve opgaverne gemmes samme sted som virksomhedsdata. Når det rigtige tidspunkt kommer, tager planlæggeren opgaven, giver den til en eller anden løber, som tæller den og gemmer resultatet.

Hvordan vi byggede kernen i Alfa-Banks investeringsforretning baseret på Tarantool
Ikke alle opgaver skal køres efter en tidsplan. Nogle rapporter skal læses efter behov. Så snart dette krav kommer, oprettes en opgave i sandkassen og sendes til løberen til udførelse. Efter nogen tid modtager brugeren et asynkront svar om, at alt er beregnet, og rapporten er klar.

Hvordan vi byggede kernen i Alfa-Banks investeringsforretning baseret på Tarantool
Til at begynde med fulgte vi paradigmet med at gemme alle data, versionere dem og ikke slette dem. Men i livet skal du fra tid til anden stadig slette noget, for det meste nogle rå eller mellemliggende oplysninger. Baseret på udløbsdato har vi oprettet en mekanisme til at rense lageret fra forældede data.

Hvordan vi byggede kernen i Alfa-Banks investeringsforretning baseret på Tarantool
Vi forstår også, at der før eller siden opstår en situation, hvor der ikke vil være plads nok til at gemme data i hukommelsen, men ikke desto mindre skal dataene gemmes. Til disse formål vil vi snart lave disklagring.

Hvordan vi byggede kernen i Alfa-Banks investeringsforretning baseret på Tarantool

Konklusion

Vi startede med opgaven med at indlæse data i en enkelt model og brugte tre måneder på at udvikle den. Vi havde seks dataforsyningssystemer. Hele transformationskoden til en enkelt model er omkring 30 tusind linjer i Lua. Og det meste af arbejdet er stadig forude. Nogle gange mangler der motivation fra nabohold, og der er mange omstændigheder, der komplicerer arbejdet. Hvis du nogensinde står over for en lignende opgave, så gange den tid, der forekommer normal for dig for dens implementering, med tre eller endda fire.

Husk også, at eksisterende problemer i forretningsprocesser ikke kan løses ved hjælp af et nyt DBMS, selv et meget produktivt. Hvad jeg mener? I starten af ​​vores projekt skabte vi det indtryk blandt kunderne, at nu vil vi bringe en ny hurtig database, og vi vil leve! Processerne vil gå hurtigere, alt vil være godt. Faktisk løser teknologi ikke de problemer, som forretningsprocesser har, fordi forretningsprocesser er mennesker. Og du skal arbejde med mennesker, ikke teknologi.

Testdrevet udvikling kan være smertefuldt og tidskrævende i de tidlige stadier. Men den positive effekt af det vil være mærkbar selv på kort sigt, når du ikke behøver at gøre noget for at udføre regressionstest.

Det er ekstremt vigtigt at udføre belastningstest på alle udviklingsstadier. Jo før du bemærker en fejl i arkitekturen, jo lettere bliver det at rette op på det, hvilket vil spare dig for en masse tid i fremtiden.

Der er ikke noget galt med Lua. Alle kan lære at skrive i det: Java-udvikler, JavaScript-udvikler, Python-udvikler, front-end eller back-end. Selv vores analytikere skriver om det.

Når vi taler om, at vi ikke har SQL, skræmmer det folk. “Hvordan får man data uden SQL? Er det muligt? Sikkert. I et OLTP-klassesystem er SQL ikke nødvendigt. Der er et alternativ i form af en form for sprog, der straks vender tilbage til en dokumentorienteret visning. For eksempel GraphQL. Og der er et alternativ i form af distribueret computing.

Hvis du forstår, at du bliver nødt til at skalere, så design din løsning på Tarantool på en sådan måde, at den kan køre parallelt på snesevis af Tarantool-forekomster. Hvis du ikke gør dette, bliver det vanskeligt og smertefuldt senere, da Tarantool kun effektivt kan bruge én processorkerne.

Kilde: www.habr.com

Tilføj en kommentar