Hvordan slutte å bekymre seg og begynne å leve uten en monolitt

Hvordan slutte å bekymre seg og begynne å leve uten en monolitt

Vi elsker alle historier. Vi liker å sitte rundt bålet og snakke om tidligere seire, kamper eller rett og slett arbeidserfaringen vår.

I dag er akkurat en slik dag. Og selv om du ikke er ved bålet akkurat nå, har vi en historie for deg. Historien om hvordan vi begynte å jobbe med lagring på Tarantool.

En gang i tiden hadde selskapet vårt et par "monolitter" og ett "tak" for alle, som disse monolittene sakte men sikkert nærmet seg, og begrenset flukten til selskapet vårt, utviklingen vår. Og det var en klar forståelse: En dag vil vi treffe dette taket hardt.

Det er nå den rådende ideologien om å skille alt og alle, fra utstyr til forretningslogikk. Som et resultat har vi for eksempel to DC-er som er praktisk talt uavhengige på nettverksnivå. Og så var alt helt annerledes.

I dag finnes det en mengde verktøy og verktøy for å gjøre endringer i form av CI/CD, K8S osv. I «monolittisk» tid trengte vi ikke så mange fremmedord. Det var nok å ganske enkelt korrigere "lagringen" i databasen.

Men tiden gikk fremover, og antallet forespørsler gikk fremover, og noen ganger ble RPS utover våre evner. Med inntredenen av CIS-landene på markedet, falt ikke belastningen på databaseprosessoren til den første monolitten under 90%, og RPS forble på nivået 2400. Og dette var ikke bare små velgere, men heftige spørsmål med en haug med sjekker og JOINs som kan kjøre nesten halvparten av dataene mot bakgrunnen av store IO.

Da fullverdige Black Friday-salg begynte å dukke opp på scenen – og Wildberries var en av de første som holdt dem i Russland – ble situasjonen fullstendig trist. Tross alt øker belastningen på slike dager tre ganger.
Å, disse "monolittiske tider"! Jeg er sikker på at du har opplevd noe lignende, og du kan fortsatt ikke forstå hvordan dette kan skje med deg.

Hva kan du gjøre - mote er iboende i teknologi. For omtrent 5 år siden måtte vi revurdere en av disse modsene i form av et eksisterende nettsted på .NET og MS SQL server, som nøye lagret all logikken til selve nettstedet. Jeg holdt det så nøye at det å sage en slik monolitt viste seg å være en lang og slett ikke lett fornøyelse.
En liten avvikelse.

Ved forskjellige arrangementer sier jeg: "Hvis du ikke så en monolitt, så vokste du ikke!" Jeg er interessert i din mening om denne saken, vennligst skriv den i kommentarene.

En lyd av torden

La oss gå tilbake til vårt "bål". For å fordele belastningen av "monolittisk" funksjonalitet, bestemte vi oss for å dele systemet inn i mikrotjenester basert på åpen kildekode-teknologi. Fordi de i det minste er billigere å skalere. Og vi hadde 100 % forståelse for at vi måtte skalere (og mye). Tross alt, allerede på den tiden var det mulig å komme inn på markedene til nabolandene, og antall registreringer, så vel som antall bestillinger, begynte å vokse enda sterkere.

Etter å ha analysert de første kandidatene for avgang fra monolitten til mikrotjenester, innså vi at 80 % av skriften i dem kommer fra back office-systemer og lesing fra front office. Først og fremst dreide dette seg om et par viktige delsystemer for oss – brukerdata og et system for å beregne endelig varekostnad basert på informasjon om ytterligere kunderabatter og kuponger.

Innrykket. Nå er det skummelt å forestille seg, men i tillegg til de ovennevnte undersystemene, ble også produktkataloger, en brukerkurv, et produktsøkesystem, et filtreringssystem for produktkataloger og ulike typer anbefalingssystemer fjernet fra monolitten vår. For driften av hver av dem er det separate klasser med snevert skreddersydde systemer, men en gang i tiden bodde de alle i ett "hus".

Vi planla umiddelbart å overføre data om kundene våre til sharded-systemet. Fjerningen av funksjonalitet for å beregne sluttkostnaden for varer krevde god skalerbarhet for lesing, fordi det skapte den største RPS-belastningen og var den vanskeligste å implementere for databasen (mye data er involvert i beregningsprosessen).

Som et resultat kom vi opp med et opplegg som passer godt med Tarantool.

På den tiden, for drift av mikrotjenester, ble ordninger for arbeid med flere datasentre på virtuelle og maskinvaremaskiner valgt. Som vist i figurene ble Tarantool-replikeringsalternativer brukt i både master-master og master-slave-modus.

Hvordan slutte å bekymre seg og begynne å leve uten en monolitt
Arkitektur. Alternativ 1. Brukertjeneste

På det nåværende tidspunkt er det 24 shards, som hver har 2 forekomster (en for hver DC), alle i master-master-modus.

På toppen av databasen er applikasjoner som får tilgang til databasereplikaer. Applikasjoner fungerer med Tarantool gjennom vårt tilpassede bibliotek, som implementerer Tarantool Go-drivergrensesnittet. Hun ser alle kopiene og kan samarbeide med mesteren om å lese og skrive. I hovedsak implementerer den replikasettmodellen, som legger til logikk for å velge replikaer, utføre nye forsøk, en strømbryter og en hastighetsgrense.

I dette tilfellet er det mulig å konfigurere replikavalgpolicyen i sammenheng med shards. For eksempel roundrobin.

Hvordan slutte å bekymre seg og begynne å leve uten en monolitt
Arkitektur. Alternativ 2. Tjeneste for å beregne den endelige varekostnaden

For noen måneder siden gikk de fleste forespørslene for å beregne den endelige kostnaden for varer til en ny tjeneste, som i prinsippet fungerer uten databaser, men for en tid siden ble alt behandlet 100% av en tjeneste med Tarantool under panseret.

Tjenestedatabasen består av 4 mastere som synkroniseringen samler inn data i, og hver av disse replikeringsmasterne distribuerer data til skrivebeskyttede replikaer. Hver master har omtrent 15 slike kopier.

Enten i den første eller den andre ordningen, hvis en DC er utilgjengelig, kan applikasjonen motta data i den andre.

Det er verdt å merke seg at replikering i Tarantool er ganske fleksibel og kan konfigureres under kjøretid. I andre systemer oppsto det vanskeligheter. For eksempel, endring av parameterne max_wal_senders og max_replication_slots i PostgreSQL krever en omstart av veiviseren, som i noen tilfeller kan føre til at forbindelsene mellom applikasjonen og DBMS brytes.

Søk og du vil finne!

Hvorfor gjorde vi det ikke "som normale mennesker", men valgte en atypisk måte? Det kommer an på hva som anses som normalt. Mange mennesker lager vanligvis en klynge fra Mongo og sprer den over tre geo-distribuerte DC-er.

På den tiden hadde vi allerede to Redis-prosjekter. Den første var en cache, og den andre var en vedvarende lagring for ikke altfor kritiske data. Det var ganske vanskelig med ham, delvis på grunn av vår skyld. Noen ganger var det ganske store volumer i nøkkelen, og fra tid til annen ble stedet uvel. Vi brukte dette systemet i master-slave-versjonen. Og det var mange tilfeller der noe skjedde med mesteren og replikeringen brøt sammen.

Det vil si at Redis er bra for statsløse oppgaver, ikke statelige. I prinsippet tillot det å løse de fleste problemer, men bare hvis de var nøkkelverdiløsninger med et par indekser. Men Redis på den tiden var ganske trist med utholdenhet og replikering. I tillegg kom det klager på ytelse.

Vi tenkte på MySQL og PostgreSQL. Men den første fanget på en eller annen måte ikke med oss, og den andre er et ganske sofistikert produkt i seg selv, og det ville være upassende å bygge enkle tjenester på det.
Vi prøvde RIAK, Cassandra, til og med en grafdatabase. Dette er alle ganske nisjeløsninger som ikke var egnet for rollen som et generelt universelt verktøy for å lage tjenester.

Til slutt slo vi oss ned på Tarantool.

Vi vendte oss til det da det var i versjon 1.6. Vi var interessert i det av symbiosen mellom nøkkelverdi og funksjonaliteten til en relasjonsdatabase. Det er sekundære indekser, transaksjoner og mellomrom, disse er som tabeller, men ikke enkelt, du kan lagre forskjellige antall kolonner i dem. Men morderfunksjonen til Tarantool var sekundære indekser kombinert med nøkkelverdi og transaksjonalitet.

Det lydhøre russisktalende fellesskapet, klare til å hjelpe i chatten, spilte også en rolle. Vi brukte dette aktivt og lever direkte i chatten. Og ikke glem anstendig vedvarende uten åpenbare tabber og feil. Hvis du ser på historien vår med Tarantool, hadde vi mye smerte og feil med replikering, men vi mistet aldri data på grunn av feilen!

Implementeringen fikk en tøff start

På den tiden var vår hovedutviklingsstabel .NET, som det ikke fantes noen kobling for Tarantool. Vi begynte umiddelbart å gjøre noe i Go. Det fungerte bra med Lua også. Hovedproblemet på den tiden var med feilsøking: i .NET er alt bra med dette, men etter det var det vanskelig å stupe inn i verden av innebygd Lua, når du ikke har noen feilsøking bortsett fra logger. I tillegg falt replikering av en eller annen grunn med jevne mellomrom, så jeg måtte fordype meg i strukturen til Tarantool-motoren. Chatten hjalp med dette, og i mindre grad dokumentasjonen, noen ganger så vi på koden. På den tiden var dokumentasjonen så som så.

Så i løpet av flere måneder klarte jeg å få hodet rundt og få anstendige resultater av å jobbe med Tarantool. Vi kompilerte referanseutviklinger i git som hjalp til med dannelsen av nye mikrotjenester. For eksempel, når en oppgave oppsto: å lage en annen mikrotjeneste, så utvikleren på kildekoden til referanseløsningen i depotet, og det tok ikke mer enn en uke å lage en ny.

Dette var spesielle tider. Vanligvis kan du gå opp til administratoren ved neste bord og spørre: "Gi meg en virtuell maskin." Omtrent tretti minutter senere var bilen allerede hos deg. Du koblet til selv, installerte alt, og trafikk ble sendt til deg.

I dag vil dette ikke lenger fungere: du må legge til overvåking og logging til tjenesten, dekke funksjonaliteten med tester, bestille en virtuell maskin eller levering til Kuber, etc. Generelt vil det være bedre på denne måten, selv om det vil ta lengre tid og være mer plagsomt.

Del og hersk. Hva er greia med Lua?

Det var et alvorlig dilemma: noen team klarte ikke å rulle ut endringer på en pålitelig måte til en tjeneste med mye logikk i Lua. Dette ble ofte ledsaget av at tjenesten ikke fungerte.

Det vil si at utviklerne forbereder en slags endring. Tarantool begynner å gjøre migreringen, men kopien er fortsatt med den gamle koden; Noen DDL eller noe annet kommer dit via replikering, og koden faller rett og slett fra hverandre fordi det ikke blir tatt hensyn til. Som et resultat ble oppdateringsprosedyren for administratorene lagt ut på A4-ark: stopp replikering, oppdater dette, slå på replikering, slå av her, oppdater der. Mareritt!

Som et resultat prøver vi nå oftest å gjøre ingenting i Lua. Bare bruk iproto (en binær protokoll for å samhandle med serveren), og det er det. Kanskje er dette mangel på kunnskap blant utviklerne, men fra dette synspunktet er systemet komplekst.

Vi følger ikke alltid blindt dette manuset. I dag har vi ikke svart-hvitt: enten er alt i Lua, eller så er alt i Go. Vi forstår allerede hvordan vi kan kombinere dem slik at vi ikke ender opp med migrasjonsproblemer senere.

Hvor er Tarantool nå?
Tarantool brukes i tjenesten for å beregne den endelige kostnaden for varer under hensyntagen til rabattkuponger, også kjent som "Promotor". Som jeg sa tidligere, går han nå av med pensjon: han blir erstattet av en ny katalogtjeneste med forhåndsberegnet priser, men for seks måneder siden ble alle beregninger gjort i Promotizer. Tidligere ble halvparten av logikken skrevet i Lua. For to år siden ble tjenesten omgjort til et lager, og logikken ble skrevet om i Go, fordi mekanikken til rabatter hadde endret seg litt og tjenesten manglet ytelse.

En av de mest kritiske tjenestene er brukerprofilen. Det vil si at alle Wildberries-brukere er lagret i Tarantool, og det er rundt 50 millioner av dem.Et system sønderdelt av bruker-ID, fordelt på flere DC-er koblet til Go-tjenester.
I følge RPS var Promoter en gang lederen, og nådde 6 tusen forespørsler. På et tidspunkt hadde vi 50-60 eksemplarer. Nå er lederen i RPS brukerprofiler, ca 12 20. Denne tjenesten bruker tilpasset sharding, delt på rekkevidde av bruker-IDer. Tjenesten betjener mer enn 4 maskiner, men dette er for mange; vi planlegger å redusere de tildelte ressursene, fordi kapasiteten på 5-XNUMX maskiner er nok til det.

Session service er vår første service på vshard og Cartridge. Å sette opp vshard og oppdatere Cartridge krevde litt innsats fra oss, men til slutt ordnet alt seg.

Tjenesten for å vise forskjellige bannere på nettsiden og i mobilapplikasjonen var en av de første som ble utgitt direkte på Tarantool. Denne tjenesten er kjent for det faktum at den er 6-7 år gammel, den er fortsatt i drift og har aldri blitt startet på nytt. Master-master replikering ble brukt. Ingenting gikk i stykker.

Det er et eksempel på bruk av Tarantool for hurtigreferansefunksjonalitet i et lagersystem for raskt å dobbeltsjekke informasjon i noen tilfeller. Vi prøvde å bruke Redis til dette, men dataene i minnet tok opp mer plass enn Tarantool.

Tjenestene til en venteliste, klientabonnementer, for tiden fasjonable historier og utsatte varer fungerer også med Tarantool. Den siste tjenesten i minnet tar opp omtrent 120 GB. Dette er den mest omfattende tjenesten av de ovennevnte.

Konklusjon

Takket være sekundære indekser kombinert med nøkkelverdi og transaksjonalitet, er Tarantool godt egnet for mikrotjenester-baserte arkitekturer. Vi møtte imidlertid problemer ved utrulling av endringer i tjenester med mye logikk i Lua - tjenestene sluttet ofte å fungere. Vi klarte ikke å overvinne dette, og over tid kom vi til forskjellige kombinasjoner av Lua og Go: vi vet hvor vi skal bruke ett språk og hvor vi skal bruke et annet.

Hva annet å lese om emnet

Kilde: www.habr.com

Legg til en kommentar