Om at flytte fra Redis til Redis-cluster

Om at flytte fra Redis til Redis-cluster

Når man kommer til et produkt, der har været under udvikling i mere end et årti, er det slet ikke overraskende at finde forældede teknologier i det. Men hvad nu hvis du om seks måneder skal holde belastningen 10 gange højere, og omkostningerne ved fald vil stige hundredvis af gange? I dette tilfælde har du brug for en sej Highload Engineer. Men i mangel af en tjenestepige betroede de mig at løse problemet. I første del af artiklen vil jeg fortælle dig, hvordan vi flyttede fra Redis til Redis-cluster, og i anden del vil jeg give råd til, hvordan du begynder at bruge klyngen, og hvad du skal være opmærksom på, når du bruger den.

Teknologivalg

Er det så slemt? separat Redis (standalone redis) i en konfiguration af 1 master og N slaver? Hvorfor kalder jeg det forældet teknologi?

Nej, Redis er ikke så slem... Der er dog nogle mangler, som ikke kan ignoreres.

  • For det første understøtter Redis ikke disaster recovery-mekanismer efter en masterfejl. For at løse dette problem brugte vi en konfiguration med automatisk overførsel af VIP'er til en ny master, ændrede rollen som en af ​​slaverne og skiftede resten. Denne mekanisme fungerede, men den kunne ikke kaldes en pålidelig løsning. For det første opstod der falske alarmer, og for det andet var det engangs, og efter betjening var der behov for manuelle handlinger for at lade fjederen op.

  • For det andet førte kun én mester til problemet med sønderdeling. Vi var nødt til at oprette flere uafhængige klynger "1 master og N slaver", og derefter manuelt distribuere databaserne blandt disse maskiner og håbe på, at en af ​​databaserne i morgen ikke ville svulme så meget, at den skulle flyttes til en separat instans.

Hvad er mulighederne?

  • Den dyreste og rigeste løsning er Redis-Enterprise. Dette er en kasseløsning med fuld teknisk support. På trods af at det ser ideelt ud fra et teknisk synspunkt, passede det os af ideologiske grunde ikke.
  • Redis-klynge. Ud af boksen er der understøttelse af master failover og sharding. Grænsefladen adskiller sig næsten ikke fra den almindelige version. Det ser lovende ud, vi taler om faldgruberne senere.
  • Tarantool, Memcache, Aerospike og andre. Alle disse værktøjer gør stort set det samme. Men hver har sine egne mangler. Vi besluttede ikke at lægge alle vores æg i én kurv. Vi bruger Memcache og Tarantool til andre opgaver, og når vi ser fremad, vil jeg sige, at der i vores praksis var flere problemer med dem.

Specifikt brug

Lad os tage et kig på, hvilke problemer vi historisk har løst med Redis, og hvilken funktionalitet vi brugte:

  • Cache før anmodninger til fjerntjenester som 2GIS | Golang

    GET SET MGET MSET "SELECT DB"

  • Cache før MYSQL | PHP

    GET SET MGET MSET SCAN "KEY BY PATTERN" "SELECT DB"

  • Hovedlageret til tjenesten med at arbejde med sessioner og driverkoordinater | Golang

    GET SET MGET MSET "SELECT DB" "ADD GEO KEY" "GET GEO KEY" SCAN

Som du kan se, ingen højere matematik. Hvad er så vanskeligheden? Lad os se på hver metode separat.

fremgangsmåde
beskrivelse
Funktioner af Redis-cluster
beslutning

Bliv klar
Skrive/læse nøgle

MGET MSET
Skriv/læs flere nøgler
Tasterne vil være på forskellige noder. Færdiglavede biblioteker kan kun udføre multioperationer inden for én node
Erstat MGET med en pipeline af N GET-operationer

VÆLG DB
Vælg den base, vi vil arbejde med
Understøtter ikke flere databaser
Læg alt i én database. Tilføj præfikser til nøgler

SCAN
Gennemgå alle nøglerne i databasen
Da vi har én database, er det for dyrt at gennemgå alle nøglerne i klyngen
Oprethold en invariant inden for én nøgle, og lav en HSCAN på denne nøgle. Eller afslå helt

GEO
Operationer med en geonøgle
Geo-nøglen er ikke sønderdelt

NØGLE EFTER MØNSTER
Søger efter en nøgle efter mønster
Da vi har én database, vil vi søge på tværs af alle nøgler i klyngen. For dyrt
Afvis eller bibehold den invariante, som i tilfældet med SCAN

Redis vs Redis-cluster

Hvad mister vi, og hvad vinder vi, når vi skifter til en klynge?

  • Ulemper: vi mister funktionaliteten af ​​flere databaser.
    • Hvis vi vil gemme logisk ikke-relaterede data i én klynge, bliver vi nødt til at lave krykker i form af præfikser.
    • Vi mister alle "base" operationer, såsom SCAN, DBSIZE, CLEAR DB osv.
    • Multioperationer er blevet meget sværere at implementere, fordi det kan kræve adgang til flere noder.
  • Fordele:
    • Fejltolerance i form af master failover.
    • Sharding på Redis-siden.
    • Overfør data mellem noder atomært og uden nedetid.
    • Tilføj og omfordel kapacitet og belastninger uden nedetid.

Jeg vil konkludere, at hvis du ikke behøver at give et højt niveau af fejltolerance, så er det ikke værd at flytte til en klynge, fordi det kan være en ikke-triviel opgave. Men hvis du i første omgang vælger mellem en separat version og en klyngeversion, så bør du vælge en klynge, da det ikke er værre og derudover vil lindre noget af hovedpinen.

Forbereder sig på at flytte

Lad os starte med kravene til flytning:

  • Det skal være sømløst. Et fuldstændigt servicestop i 5 minutter passer os ikke.
  • Det skal være så sikkert og gradvist som muligt. Jeg vil gerne have lidt kontrol over situationen. Vi ønsker ikke at dumpe alt på én gang og bede over rollback-knappen.
  • Minimalt datatab ved flytning. Vi forstår, at det vil være meget svært at flytte atomært, så vi tillader en vis desynkronisering mellem data i almindelige og klyngede Redis.

Klyngevedligeholdelse

Lige inden flytningen bør vi tænke over, om vi kan støtte klyngen:

  • Diagrammer. Vi bruger Prometheus og Grafana til at tegne CPU-belastning, hukommelsesforbrug, antal klienter, antal GET-, SET-, AUTH-operationer osv.
  • Ekspertise. Forestil dig, at du i morgen vil have en kæmpe klynge under dit ansvar. Hvis det går i stykker, kan ingen andre end dig reparere det. Hvis han begynder at sænke farten, vil alle løbe mod dig. Hvis du har brug for at tilføje ressourcer eller omfordele belastningen, så vend tilbage til dig. For ikke at blive grå ved 25, er det tilrådeligt at sørge for disse tilfælde og kontrollere på forhånd, hvordan teknologien vil opføre sig under visse handlinger. Lad os tale mere om dette i afsnittet "Ekspertise".
  • Overvågning og alarmer. Når en klynge går i stykker, vil du gerne være den første til at vide om den. Her begrænsede vi os til en notifikation om, at alle noder returnerer den samme information om klyngens tilstand (ja, det sker forskelligt). Og andre problemer kan opdages hurtigere ved advarsler fra Redis kundeservice.

passage

Sådan flytter vi:

  • Først og fremmest skal du forberede et bibliotek til at arbejde med klyngen. Vi tog go-redis som grundlag for Go-versionen og ændrede den lidt, så den passer til os selv. Vi implementerede Multi-metoder gennem pipelines og korrigerede også lidt reglerne for gentagelse af anmodninger. PHP-versionen havde flere problemer, men vi slog os til sidst fast på php-redis. De introducerede for nylig klyngestøtte, og det ser godt ud efter vores mening.
  • Dernæst skal du implementere selve klyngen. Dette gøres bogstaveligt talt i to kommandoer baseret på konfigurationsfilen. Vi vil diskutere indstillingen mere detaljeret nedenfor.
  • Til gradvis bevægelse bruger vi tør-tilstand. Da vi har to versioner af biblioteket med samme grænseflade (den ene til den almindelige version, den anden til klyngen), koster det ikke noget at lave en wrapper, der fungerer med en separat version og parallelt duplikere alle anmodninger til klyngen, sammenligne svar og skrive uoverensstemmelser i loggene (i vores tilfælde i NewRelic). Selvom klyngeversionen går i stykker under udrulningen, vil vores produktion således ikke blive påvirket.
  • Efter at have rullet klyngen ud i tør tilstand, kan vi roligt se på grafen over svarafvigelser. Hvis fejlraten langsomt, men sikkert bevæger sig mod en eller anden lille konstant, så er alt i orden. Hvorfor er der stadig uoverensstemmelser? Fordi optagelse i en separat version sker lidt tidligere end i klyngen, og på grund af mikrolag, kan dataene divergere. Det eneste, der er tilbage, er at se på uoverensstemmelsesloggene, og hvis de alle er forklaret af postens ikke-atomicitet, så kan vi komme videre.
  • Nu kan du skifte tør-tilstand i den modsatte retning. Vi vil skrive og læse fra klyngen og duplikere den til en separat version. For hvad? I løbet af den næste uge vil jeg gerne observere klyngens arbejde. Hvis det pludselig viser sig, at der er problemer ved spidsbelastning, eller vi ikke har taget højde for noget, har vi altid en nødstilbageføring til den gamle kode og aktuelle data takket være dry-mode.
  • Det eneste, der er tilbage, er at deaktivere tør-tilstand og afmontere den separate version.

Ekspertise

Først kort om klyngedesignet.

Først og fremmest er Redis en butik med nøgleværdier. Vilkårlige strenge bruges som nøgler. Tal, strenge og hele strukturer kan bruges som værdier. Der er rigtig mange af sidstnævnte, men for at forstå den generelle struktur er dette ikke vigtigt for os.
Det næste abstraktionsniveau efter nøgler er slots (SLOTS). Hver nøgle tilhører en af ​​16 slots. Der kan være et hvilket som helst antal nøgler inde i hver slot. Således er alle nøgler opdelt i 383 usammenhængende sæt.
Om at flytte fra Redis til Redis-cluster

Dernæst skal der være N masterknudepunkter i klyngen. Hver node kan opfattes som en separat Redis-instans, der ved alt om andre noder i klyngen. Hver masterknude indeholder et antal slots. Hvert slot tilhører kun én masterknude. Alle slots skal fordeles mellem noder. Hvis nogle slots ikke er tildelt, vil nøglerne, der er gemt i dem, være utilgængelige. Det giver mening at køre hver masterknude på en separat logisk eller fysisk maskine. Det er også værd at huske på, at hver node kun kører på én kerne, og hvis du vil køre flere Redis-forekomster på den samme logiske maskine, skal du sørge for, at de kører på forskellige kerner (vi har ikke prøvet dette, men i teorien burde det fungere) . Hovedknudepunkter giver i det væsentlige regelmæssig sharding, og flere masterknuder tillader skrive- og læseanmodninger at skalere.

Efter at alle nøglerne er fordelt blandt slotsene, og slotsene er spredt blandt masterknudepunkterne, kan et vilkårligt antal slaveknudepunkter tilføjes til hver masterknude. Inden for hvert sådant master-slave-link vil normal replikering fungere. Slaver er nødvendige for at skalere læseanmodninger og til failover i tilfælde af masterfejl.
Om at flytte fra Redis til Redis-cluster

Lad os nu tale om operationer, som det ville være bedre at kunne udføre.

Vi får adgang til systemet via Redis-CLI. Da Redis ikke har et enkelt indgangspunkt, kan du udføre følgende handlinger på enhver af noderne. På hvert punkt gør jeg særskilt opmærksom på muligheden for at udføre operationen under belastning.

  • Den første og vigtigste ting, vi har brug for, er cluster nodes operation. Det returnerer klyngens tilstand, viser en liste over noder, deres roller, slotfordeling osv. Mere information kan fås ved at bruge klyngeinfo og klyngepladser.
  • Det ville være rart at kunne tilføje og fjerne noder. Til dette formål er der klyngetræf og klyngeglem-operationer. Bemærk venligst, at cluster forget skal anvendes på HVER node, både mastere og replikaer. Og cluster meet skal kun kaldes på én node. Denne forskel kan være foruroligende, så det er bedst at lære om det, før du går live med din klynge. Tilføjelse af en node sker sikkert i kamp og påvirker ikke driften af ​​klyngen på nogen måde (hvilket er logisk). Hvis du skal fjerne en node fra klyngen, skal du sikre dig, at der ikke er pladser tilbage på den (ellers risikerer du at miste adgangen til alle nøglerne på denne node). Slet heller ikke en master, der har slaver, ellers vil der blive udført en unødvendig afstemning på en ny master. Hvis noderne ikke længere har slots, så er dette et lille problem, men hvorfor har vi brug for ekstra valg, hvis vi kan slette slaverne først.
  • Hvis du har brug for at udskifte master- og slavepositioner med magt, vil klyngefailover-kommandoen duer. Når du kalder det i kamp, ​​skal du forstå, at mesteren ikke vil være tilgængelig under operationen. Skiftet sker typisk på mindre end et sekund, men er ikke atomart. Du kan forvente, at nogle anmodninger til masteren vil mislykkes i løbet af denne tid.
  • Før du fjerner en node fra klyngen, bør der ikke være plads tilbage på den. Det er bedre at omfordele dem ved at bruge kommandoen cluster reshard. Slots vil blive overført fra en master til en anden. Hele operationen kan tage flere minutter, det afhænger af mængden af ​​data, der overføres, men overførselsprocessen er sikker og påvirker ikke driften af ​​klyngen på nogen måde. Således kan alle data overføres fra en node til en anden direkte under belastning og uden at bekymre dig om deres tilgængelighed. Der er dog også finesser. For det første er dataoverførsel forbundet med en vis belastning på modtager- og afsenderknudepunkter. Hvis modtagernoden allerede er tungt belastet på processoren, så bør du ikke indlæse den med modtagelse af nye data. For det andet, så snart der ikke er et eneste slot tilbage på den afsendende master, vil alle dens slaver straks gå til masteren, hvortil disse slots blev overført. Og problemet er, at alle disse slaver vil synkronisere data på én gang. Og du vil være heldig, hvis det er delvist snarere end fuldstændig synkronisering. Tag dette i betragtning og kombiner operationerne med at overføre slots og deaktivere/overføre slaver. Eller håber, at du har en tilstrækkelig sikkerhedsmargin.
  • Hvad skal du gøre, hvis du under overførslen opdager, at du har mistet dine slots et sted? Jeg håber, at dette problem ikke påvirker dig, men hvis det gør, er der en klyngefix-operation. I det mindste vil hun sprede spalterne hen over noderne i en tilfældig rækkefølge. Jeg anbefaler at kontrollere dens funktion ved først at fjerne noden med distribuerede slots fra klyngen. Da data i ikke-allokerede slots allerede er utilgængelige, er det for sent at bekymre sig om problemer med tilgængeligheden af ​​disse slots. Til gengæld vil operationen ikke påvirke distribuerede slots.
  • En anden nyttig operation er monitor. Det giver dig mulighed for i realtid at se hele listen over anmodninger, der går til noden. Desuden kan du grep det og finde ud af, om der er den nødvendige trafik.

Det er også værd at nævne master failover-proceduren. Kort sagt, det eksisterer, og efter min mening fungerer det fantastisk. Men tro ikke, at hvis du trækker netledningen ud af en maskine med en masterknude, vil Redis straks skifte over, og klienter vil ikke bemærke tabet. I min praksis sker skiftet på få sekunder. I løbet af denne tid vil nogle af dataene være utilgængelige: Mesterens utilgængelighed registreres, noder stemmer på en ny, slaver skiftes, data synkroniseres. Den bedste måde at sikre sig, at ordningen virker, er ved at gennemføre lokale øvelser. Hæv klyngen på din bærbare computer, giv den en minimal belastning, simuler et nedbrud (for eksempel ved at blokere portene), og vurder omskiftningshastigheden. Efter min mening, kun efter at have spillet på denne måde i en dag eller to, kan du være sikker på driften af ​​teknologien. Nå, eller håber, at den software, som halvdelen af ​​internettet bruger, nok virker.

Konfiguration

Ofte er konfigurationen det første, du skal bruge for at begynde at arbejde med værktøjet. Og når alt fungerer, ønsker du ikke engang at røre ved konfigurationen. Det kræver en indsats at tvinge dig selv til at gå tilbage til indstillingerne og gennemgå dem omhyggeligt. I min hukommelse havde vi mindst to alvorlige fejl på grund af uopmærksomhed på konfigurationen. Vær særlig opmærksom på følgende punkter:

  • timeout 0
    Tid, hvorefter inaktive forbindelser lukkes (i sekunder). 0 - luk ikke
    Ikke alle vores biblioteker var i stand til at lukke forbindelser korrekt. Ved at deaktivere denne indstilling risikerer vi at ramme grænsen for antallet af klienter. På den anden side, hvis der er et sådant problem, vil automatisk afbrydelse af mistede forbindelser maskere det, og vi bemærker det muligvis ikke. Derudover bør du ikke aktivere denne indstilling, når du bruger vedvarende forbindelser.
  • Gem xy og vedlagt ja
    Gemmer et RDB-øjebliksbillede.
    Vi vil diskutere RDB/AOF-spørgsmål i detaljer nedenfor.
  • stop-skriver-på-bgsave-fejl nej & slave-serve-stale-data ja
    Hvis det er aktiveret, hvis RDB-øjebliksbilledet går i stykker, stopper masteren med at acceptere ændringsanmodninger. Hvis forbindelsen til masteren mistes, kan slaven fortsætte med at svare på anmodninger (ja). Eller holder op med at svare (nej)
    Vi er ikke tilfredse med situationen, hvor Redis bliver til et græskar.
  • repl-ping-slave-periode 5
    Efter denne periode begynder vi at bekymre os om, at masteren er brudt sammen, og det er tid til at udføre failover-proceduren.
    Du bliver nødt til manuelt at finde en balance mellem falske positiver og udløsning af en failover. I vores praksis er det 5 sekunder.
  • repl-backlog-størrelse 1024mb & epl-backlog-ttl 0
    Vi kan gemme præcis så meget data i en buffer for en mislykket replika. Hvis bufferen løber tør, bliver du nødt til at synkronisere fuldstændigt.
    Praksis tyder på, at det er bedre at sætte en højere værdi. Der er masser af grunde til, at en replika kan begynde at halte. Hvis det halter, så kæmper din mester højst sandsynligt allerede for at klare sig, og fuld synkronisering vil være dråben.
  • max klienter 10000
    Maksimalt antal engangskunder.
    Vores erfaring er, at det er bedre at sætte en højere værdi. Redis klarer 10k forbindelser fint. Bare sørg for, at der er nok stikkontakter på systemet.
  • maxmemory-policy volatile-ttl
    Den regel, hvorefter taster slettes, når den tilgængelige hukommelsesgrænse er nået.
    Det, der er vigtigt her, er ikke selve reglen, men forståelsen af, hvordan dette vil ske. Redis kan roses for sin evne til at fungere normalt, når hukommelsesgrænsen er nået.

RDB og AOF problemer

Selvom Redis selv gemmer al information i RAM, er der også en mekanisme til at gemme data på disk. Mere præcist tre mekanismer:

  • RDB-snapshot - et komplet øjebliksbillede af alle data. Indstil ved hjælp af SAVE XY-konfigurationen og læser "Gem et fuldt øjebliksbillede af alle data hvert X sekund, hvis mindst Y-tasterne er ændret."
  • Fil, der kun kan tilføjes - en liste over handlinger i den rækkefølge, de udføres. Tilføjer nye indgående operationer til filen hvert X sekund eller hver Y operation.
  • RDB og AOF er en kombination af de to foregående.

Alle metoder har deres fordele og ulemper, jeg vil ikke nævne dem alle, jeg vil blot henlede opmærksomheden på punkter, som efter min mening ikke er indlysende.

For det første kræver lagring af et RDB-øjebliksbillede, at du kalder FORK. Hvis der er mange data, kan dette hænge hele Redis i en periode på et par millisekunder til et sekund. Derudover skal systemet allokere hukommelse til et sådant øjebliksbillede, hvilket fører til behovet for at holde en dobbelt forsyning af RAM på den logiske maskine: hvis der er allokeret 8 GB til Redis, så skal 16 GB være tilgængelig på den virtuelle maskine med det.

For det andet er der problemer med delvis synkronisering. I AOF-tilstand, når slaven er tilsluttet igen, kan fuld synkronisering udføres i stedet for delvis synkronisering. Hvorfor det sker, kunne jeg ikke forstå. Men det er værd at huske dette.

Disse to punkter får os allerede til at tænke over, om vi virkelig har brug for disse data på disken, hvis alt allerede er duplikeret af slaver. Data kan kun gå tabt, hvis alle slaver fejler, og dette er et "brand i DC"-niveauproblemet. Som et kompromis kan du foreslå kun at gemme data på slaver, men i dette tilfælde skal du sikre dig, at disse slaver aldrig bliver en master under katastrofegendannelse (til dette er der en slaveprioritetsindstilling i deres konfiguration). For os selv tænker vi i hvert enkelt tilfælde på, om det er nødvendigt at gemme data på disken, og oftest er svaret "nej".

Konklusion

Afslutningsvis håber jeg, at jeg var i stand til at give en generel idé om, hvordan redis-cluster fungerer for dem, der slet ikke har hørt om det, og også henledte opmærksomheden på nogle ikke-oplagte punkter for dem, der har brugt det i lang tid.
Tak for din tid, og som altid er kommentarer til emnet velkomne.

Kilde: www.habr.com

Tilføj en kommentar