Sådan stopper du med at bekymre dig og begynder at leve uden en monolit

Sådan stopper du med at bekymre dig og begynder at leve uden en monolit

Vi elsker alle historier. Vi kan godt lide at sidde rundt om bålet og tale om vores tidligere sejre, kampe eller blot vores arbejdserfaring.

I dag er netop sådan en dag. Og selvom du ikke er ved bålet lige nu, har vi en historie til dig. Historien om, hvordan vi begyndte at arbejde med opbevaring på Tarantool.

Engang havde vores virksomhed et par "monolitter" og et "loft" for alle, hvortil disse monolitter langsomt men sikkert nærmede sig, hvilket begrænsede vores virksomheds flugt, vores udvikling. Og der var en klar forståelse: En dag vil vi ramme dette loft hårdt.

Det er nu den fremherskende ideologi om at adskille alt og alle, fra udstyr til forretningslogik. Som følge heraf har vi f.eks. to DC'er, der er praktisk talt uafhængige på netværksniveau. Og så var alting helt anderledes.

I dag findes der en masse værktøjer og værktøjer til at lave ændringer i form af CI/CD, K8S mv. I den "monolitiske" tid havde vi ikke brug for så mange fremmedord. Det var nok blot at rette "lagringen" i databasen.

Men tiden gik fremad, og antallet af anmodninger gik fremad samtidig med, at nogle gange skyder RPS ud over vores muligheder. Med SNG-landenes indtræden på markedet faldt belastningen på databaseprocessoren til den første monolit ikke under 90%, og RPS forblev på niveauet 2400. Og disse var ikke kun små vælgere, men heftige forespørgsler med en en masse checks og JOINs, der kunne køre næsten halvdelen af ​​dataene på baggrund af store IO.

Da fuldgyldige Black Friday-salg begyndte at dukke op på scenen - og Wildberries var en af ​​de første til at holde dem i Rusland - blev situationen fuldstændig trist. Trods alt stiger belastningen på sådanne dage tre gange.
Åh, disse "monolitiske tider"! Jeg er sikker på, at du har oplevet noget lignende, og du kan stadig ikke forstå, hvordan dette kunne ske for dig.

Hvad kan du gøre - mode er iboende i teknologi. For omkring 5 år siden måtte vi genoverveje en af ​​disse mods i form af et eksisterende websted på .NET og MS SQL-server, som omhyggeligt opbevarede al logikken i selve webstedet. Jeg holdt det så omhyggeligt, at det at save sådan en monolit viste sig at være en lang og slet ikke let fornøjelse.
En lille udgravning.

Ved forskellige begivenheder siger jeg: "Hvis du ikke så en monolit, så voksede du ikke!" Jeg er interesseret i din mening om denne sag, skriv den i kommentarerne.

En Lyd af Torden

Lad os vende tilbage til vores "bål". For at fordele belastningen af ​​"monolitisk" funktionalitet besluttede vi at opdele systemet i mikrotjenester baseret på opensource-teknologier. Fordi de som minimum er billigere at skalere. Og vi havde 100 % forståelse for, at vi skulle skalere (og meget). Trods alt var det allerede på det tidspunkt muligt at komme ind på markederne i nabolandene, og antallet af registreringer såvel som antallet af ordrer begyndte at vokse endnu stærkere.

Efter at have analyseret de første kandidater til afgang fra monolitten til mikrotjenester, indså vi, at 80 % af skriften i dem kommer fra back office-systemer og læsning fra front office. Først og fremmest drejede det sig om et par vigtige delsystemer for os - brugerdata og et system til beregning af den endelige varepris baseret på information om yderligere kunderabatter og kuponer.

Indrykket. Nu er det skræmmende at forestille sig, men ud over de ovennævnte undersystemer blev produktkataloger, en brugerindkøbsvogn, et produktsøgningssystem, et filtreringssystem til produktkataloger og forskellige former for anbefalingssystemer også fjernet fra vores monolit. Til driften af ​​hver af dem er der separate klasser af snævert skræddersyede systemer, men engang boede de alle i ét "hus".

Vi planlagde straks at overføre data om vores kunder til det sønderdelte system. Fjernelsen af ​​funktionalitet til beregning af de endelige vareomkostninger krævede god skalerbarhed til læsning, fordi det skabte den største RPS-belastning og var den sværeste at implementere for databasen (en masse data er involveret i beregningsprocessen).

Som et resultat kom vi med en ordning, der passer godt til Tarantool.

På det tidspunkt, til driften af ​​mikrotjenester, blev ordninger til at arbejde med flere datacentre på virtuelle og hardware-maskiner valgt. Som vist i figurerne blev Tarantool-replikeringsmuligheder anvendt i både master-master- og master-slave-tilstande.

Sådan stopper du med at bekymre dig og begynder at leve uden en monolit
Arkitektur. Mulighed 1. Brugerservice

På nuværende tidspunkt er der 24 shards, som hver har 2 instanser (en for hver DC), alle i master-master mode.

Oven på databasen er applikationer, der tilgår databasereplikaer. Applikationer fungerer med Tarantool gennem vores brugerdefinerede bibliotek, som implementerer Tarantool Go-drivergrænsefladen. Hun ser alle replikaerne og kan arbejde sammen med mesteren om at læse og skrive. I det væsentlige implementerer den replikasætmodellen, som tilføjer logik til at vælge replikaer, udføre genforsøg, en strømafbryder og en hastighedsgrænse.

I dette tilfælde er det muligt at konfigurere replikaudvælgelsespolitikken i forbindelse med shards. For eksempel roundrobin.

Sådan stopper du med at bekymre dig og begynder at leve uden en monolit
Arkitektur. Mulighed 2. Service til beregning af de endelige vareomkostninger

For et par måneder siden gik de fleste anmodninger om beregning af de endelige vareomkostninger til en ny tjeneste, som i princippet fungerer uden databaser, men for nogen tid siden blev alt behandlet 100% af en service med Tarantool under hætten.

Tjenestedatabasen består af 4 mastere, hvori synkroniseringen indsamler data, og hver af disse replikeringsmastere distribuerer data til skrivebeskyttede replikaer. Hver master har cirka 15 sådanne replikaer.

Enten i den første eller den anden ordning, hvis en DC ikke er tilgængelig, kan applikationen modtage data i den anden.

Det er værd at bemærke, at replikering i Tarantool er ret fleksibel og kan konfigureres under kørsel. I andre systemer opstod der vanskeligheder. Ændring af parametrene max_wal_senders og max_replication_slots i PostgreSQL kræver for eksempel en genstart af guiden, hvilket i nogle tilfælde kan føre til afbrydelse af forbindelser mellem applikationen og DBMS.

Søg og du vil finde!

Hvorfor gjorde vi det ikke "som normale mennesker", men valgte en atypisk måde? Det afhænger af, hvad der anses for normalt. Mange laver generelt en klynge fra Mongo og spreder den over tre geo-distribuerede DC'er.

På det tidspunkt havde vi allerede to Redis-projekter. Den første var en cache, og den anden var en vedvarende lagring til ikke alt for kritiske data. Det var ret svært med ham, delvist på grund af vores skyld. Nogle gange var der ret store mængder i nøglen, og fra tid til anden blev stedet utilpas. Vi brugte dette system i master-slave-versionen. Og der var mange tilfælde, hvor der skete noget med mesteren, og replikeringen brød sammen.

Det vil sige, at Redis er god til statsløse opgaver, ikke statelige. I princippet tillod det at løse de fleste problemer, men kun hvis de var nøgleværdiløsninger med et par indekser. Men Redis var på det tidspunkt ret trist med vedholdenhed og replikation. Derudover var der klager over præstationer.

Vi tænkte på MySQL og PostgreSQL. Men den første fangede på en eller anden måde ikke os, og den anden er et ret sofistikeret produkt i sig selv, og det ville være upassende at bygge simple tjenester på det.
Vi prøvede RIAK, Cassandra, endda en grafdatabase. Disse er alle temmelig nicheløsninger, der ikke var egnede til rollen som et generelt universelt værktøj til at skabe tjenester.

I sidste ende slog vi os ned på Tarantool.

Vi vendte os til det, da det var i version 1.6. Vi var interesserede i det af symbiosen mellem nøgleværdi og funktionaliteten af ​​en relationel database. Der er sekundære indekser, transaktioner og mellemrum, disse er som tabeller, men ikke enkle, du kan gemme forskellige antal kolonner i dem. Men den dræbende funktion ved Tarantool var sekundære indekser kombineret med nøgleværdi og transaktionalitet.

Det lydhøre russisktalende samfund, klar til at hjælpe i chatten, spillede også en rolle. Vi brugte dette aktivt og lever direkte i chatten. Og glem ikke om anstændigt vedholdende uden åbenlyse bommerter og fejl. Hvis du ser på vores historie med Tarantool, havde vi mange smerter og fejl med replikering, men vi mistede aldrig data på grund af dets skyld!

Implementeringen fik en hård start

På det tidspunkt var vores vigtigste udviklingsstak .NET, som der ikke var nogen forbindelse til Tarantool. Vi begyndte straks at lave noget i Go. Det fungerede også godt med Lua. Hovedproblemet på det tidspunkt var med fejlfinding: i .NET er alt fantastisk med dette, men efter det var det svært at kaste sig ud i en verden af ​​indlejret Lua, når du ikke har nogen fejlfinding undtagen logfiler. Derudover faldt replikering af en eller anden grund periodisk fra hinanden, så jeg var nødt til at dykke ned i strukturen af ​​Tarantool-motoren. Chatten hjalp med dette, og i mindre grad dokumentationen, nogle gange så vi på koden. På det tidspunkt var dokumentationen halvdårlig.

Så i løbet af flere måneder lykkedes det mig at få hovedet rundt og få anstændige resultater af at arbejde med Tarantool. Vi kompilerede referenceudviklinger i git, der hjalp med dannelsen af ​​nye mikrotjenester. For eksempel, da en opgave opstod: at oprette en anden mikrotjeneste, så udvikleren på kildekoden til referenceløsningen i depotet, og det tog ikke mere end en uge at oprette en ny.

Det var specielle tider. Konventionelt kunne du så gå op til administratoren ved det næste bord og spørge: "Giv mig en virtuel maskine." Cirka tredive minutter senere var bilen allerede hos dig. Du tilsluttede dig selv, installerede alt, og trafik blev sendt til dig.

I dag fungerer dette ikke længere: du skal tilføje overvågning og logning til tjenesten, dække funktionaliteten med test, bestille en virtuel maskine eller levering til Kuber osv. Generelt vil det være bedre på denne måde, selvom det vil tage længere tid og være mere besværligt.

Del og hersk. Hvad er der med Lua?

Der var et alvorligt dilemma: nogle teams var ikke i stand til pålideligt at udrulle ændringer til en tjeneste med en masse logik i Lua. Dette var ofte ledsaget af, at tjenesten ikke fungerede.

Det vil sige, at udviklerne forbereder en form for forandring. Tarantool begynder at udføre migreringen, men replikaen er stadig med den gamle kode; Noget DDL eller noget andet ankommer der via replikering, og koden falder simpelthen fra hinanden, fordi der ikke tages hensyn til den. Som et resultat blev opdateringsproceduren for administratorerne lagt på A4-ark: stop replikering, opdater dette, slå replikering til, sluk her, opdater der. Mareridt!

Som et resultat forsøger vi nu oftest ikke at gøre noget i Lua. Bare brug iproto (en binær protokol til at interagere med serveren), og det er det. Måske er dette mangel på viden blandt udviklerne, men set fra dette synspunkt er systemet komplekst.

Vi følger ikke altid blindt dette manuskript. I dag har vi ikke sort/hvid: enten er alt i Lua, eller også er alt i Go. Vi forstår allerede, hvordan vi kan kombinere dem, så vi ikke ender med migreringsproblemer senere.

Hvor er Tarantool nu?
Tarantool bruges i tjenesten til at beregne de endelige omkostninger for varer under hensyntagen til rabatkuponer, også kendt som "Promotor". Som jeg sagde tidligere, går han nu på pension: han bliver erstattet af en ny katalogtjeneste med forudberegnet priser, men for seks måneder siden blev alle beregninger foretaget i Promotizer. Tidligere var halvdelen af ​​dens logik skrevet i Lua. For to år siden blev tjenesten omdannet til en lagerfacilitet, og logikken blev omskrevet i Go, fordi rabatmekanismerne havde ændret sig lidt, og tjenesten manglede ydeevne.

En af de mest kritiske tjenester er brugerprofilen. Det vil sige, at alle Wildberries-brugere er gemt i Tarantool, og dem er der omkring 50 millioner af. Et system, der er sønderdelt af bruger-id, fordelt på flere DC'er forbundet med Go-tjenester.
Ifølge RPS var Promoter engang lederen og nåede 6 tusinde anmodninger. På et tidspunkt havde vi 50-60 eksemplarer. Nu lederen i RPS er brugerprofiler, omkring 12 tusinde. Denne service bruger tilpasset sharding, divideret med rækker af bruger-id'er. Tjenesten betjener mere end 20 maskiner, men det er for mange, vi planlægger at reducere de tildelte ressourcer, fordi kapaciteten på 4-5 maskiner er nok til det.

Sessionsservice er vores første service på vshard og Cartridge. Opsætning af vshard og opdatering af Cartridge krævede en indsats fra os, men i sidste ende lykkedes alt.

Tjenesten til at vise forskellige bannere på hjemmesiden og i mobilapplikationen var en af ​​de første, der blev frigivet direkte på Tarantool. Denne tjeneste er bemærkelsesværdig for det faktum, at den er 6-7 år gammel, den er stadig i drift og er aldrig blevet genstartet. Master-master replikering blev brugt. Intet gik nogensinde i stykker.

Der er et eksempel på at bruge Tarantool til hurtig referencefunktionalitet i et lagersystem til hurtigt at dobbelttjekke information i nogle tilfælde. Vi forsøgte at bruge Redis til dette, men dataene i hukommelsen optog mere plads end Tarantool.

Tjenesterne fra en venteliste, kundeabonnementer, aktuelt fashionable historier og udskudte varer fungerer også med Tarantool. Den sidste service i hukommelsen fylder omkring 120 GB. Dette er den mest omfattende service af ovenstående.

Konklusion

Takket være sekundære indekser kombineret med nøgleværdi og transaktionsevne er Tarantool velegnet til mikrotjenester-baserede arkitekturer. Vi stødte dog på vanskeligheder ved udrulning af ændringer til tjenester med meget logik i Lua - tjenesterne holdt ofte op med at fungere. Vi var ikke i stand til at overvinde dette, og med tiden kom vi til forskellige kombinationer af Lua og Go: vi ved, hvor vi skal bruge et sprog, og hvor vi skal bruge et andet.

Hvad skal man ellers læse om emnet

Kilde: www.habr.com

Tilføj en kommentar