O prelasku s Redisa na Redis-klaster

O prelasku s Redisa na Redis-klaster

Dolazeći do proizvoda koji se razvijao više od desetljeća, nije nimalo iznenađujuće pronaći zastarjele tehnologije u njemu. Ali što ako u šest mjeseci morate držati teret 10 puta veći, a troškovi padova će se povećati stotinama puta? U ovom slučaju, trebate cool Highload inženjera. Ali u nedostatku sobarice, povjerili su mi da riješim problem. U prvom dijelu članka ispričat ću vam kako smo prešli s Redisa na Redis-cluster, au drugom dijelu dat ću savjete kako započeti s korištenjem klastera i na što obratiti pozornost prilikom korištenja.

Izbor tehnologije

Zar je tako loše? odvojiti Redis (samostalni redis) u konfiguraciji od 1 glavnog i N podređenih? Zašto to nazivam zastarjelom tehnologijom?

Ne, Redis nije tako loš... Ipak, postoje neki nedostaci koji se ne mogu zanemariti.

  • Prvo, Redis ne podržava mehanizme oporavka od katastrofe nakon glavnog kvara. Kako bismo riješili ovaj problem, upotrijebili smo konfiguraciju s automatskim prijenosom VIP-ova na novog mastera, promjenom uloge jednog od slave-ova i prebacivanjem ostalih. Taj je mehanizam funkcionirao, ali se nije mogao nazvati pouzdanim rješenjem. Prvo, dogodili su se lažni alarmi, a drugo, bio je za jednokratnu upotrebu, a nakon rada bile su potrebne ručne radnje za punjenje opruge.

  • Drugo, postojanje samo jednog mastera dovelo je do problema s šardingom. Morali smo stvoriti nekoliko neovisnih klastera "1 master i N slaves", zatim ručno distribuirati baze podataka među tim strojevima i nadati se da sutra jedna od baza podataka neće toliko nabubriti da bi se morala premjestiti na zasebnu instancu.

Koje su mogućnosti?

  • Najskuplje i najbogatije rješenje je Redis-Enterprise. Ovo je rješenje u kutiji s punom tehničkom podrškom. Unatoč tome što s tehničke strane izgleda idealno, nama iz ideoloških razloga nije odgovarao.
  • Redis-klaster. Izvan kutije postoji podrška za master failover i shading. Sučelje se gotovo ne razlikuje od obične verzije. Djeluje obećavajuće, o zamkama ćemo kasnije.
  • Tarantool, Memcache, Aerospike i drugi. Svi ti alati rade gotovo istu stvar. Ali svaki ima svoje nedostatke. Odlučili smo da ne stavljamo sva jaja u jednu košaru. Za druge zadatke koristimo Memcache i Tarantool, a gledajući unaprijed, reći ću da je u našoj praksi bilo više problema s njima.

Specifičnosti korištenja

Pogledajmo koje smo probleme povijesno rješavali s Redisom i koju smo funkcionalnost koristili:

  • Predmemorija prije zahtjeva udaljenim servisima kao što je 2GIS | Golang

    GET SET MGET MSET "SELECT DB"

  • Predmemorija prije MYSQL | PHP

    GET SET MGET MSET SCAN "KLJUČ PO UZORKU" "SELECT DB"

  • Glavna pohrana za uslugu rada sa sesijama i koordinatama vozača | Golang

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

Kao što vidite, nema više matematike. U čemu je onda poteškoća? Pogledajmo svaku metodu zasebno.

način
Opis
Značajke Redis-klastera
odluka

PRIPREMI SE
Tipka za pisanje/čitanje

MGET MSET
Pisanje/čitanje više ključeva
Ključevi će biti na različitim čvorovima. Gotove biblioteke mogu izvoditi više operacija samo unutar jednog čvora
Zamijenite MGET nizom od N GET operacija

ODABERITE DB
Odaberite bazu s kojom ćemo raditi
Ne podržava više baza podataka
Stavite sve u jednu bazu podataka. Dodajte prefikse ključevima

SCAN
Pregledajte sve ključeve u bazi podataka
Budući da imamo jednu bazu podataka, prolazak kroz sve ključeve u klasteru je preskupo
Održavajte nepromjenjivost unutar jedne tipke i napravite HSCAN na ovoj tipki. Ili potpuno odbiti

GEO
Operacije s geoključem
Geoključ nije podijeljen

KLJUČ PO UZORKU
Traženje ključa po uzorku
Budući da imamo jednu bazu podataka, pretražit ćemo sve ključeve u klasteru. Preskupo
Odbijte ili zadržite nepromjenjivost, kao u slučaju SCAN-a

Redis protiv Redis-klastera

Što gubimo, a što dobivamo prelaskom na klaster?

  • Nedostaci: gubimo funkcionalnost nekoliko baza podataka.
    • Ako želimo logički nepovezane podatke pohraniti u jedan klaster, morat ćemo napraviti štake u obliku prefiksa.
    • Gubimo sve “bazne” operacije, kao što su SCAN, DBSIZE, CLEAR DB, itd.
    • Višestruke operacije postalo je mnogo teže implementirati jer može zahtijevati pristup nekoliko čvorova.
  • prednosti:
    • Tolerancija grešaka u obliku glavnog failovera.
    • Sharding na strani Redisa.
    • Prenesite podatke između čvorova atomski i bez zastoja.
    • Dodajte i redistribuirajte kapacitete i opterećenja bez zastoja.

Zaključio bih da ako ne trebate osigurati visoku razinu tolerancije na pogreške, onda se prelazak na klaster ne isplati jer to može biti netrivijalan zadatak. Ali ako u početku birate između zasebne verzije i verzije klastera, onda bi trebali izabrati klaster jer nije ništa lošija, a uz to će vas osloboditi nekih glavobolja

Priprema za pokret

Počnimo sa zahtjevima za selidbu:

  • Trebao bi biti besprijekoran. Potpuno zaustavljanje usluge na 5 minuta nam ne odgovara.
  • Treba biti što sigurniji i postupniji. Želim imati malo kontrole nad situacijom. Ne želimo odbaciti sve odjednom i moliti se za gumb za vraćanje.
  • Minimalni gubitak podataka prilikom premještanja. Shvaćamo da će biti vrlo teško premještati se atomski, pa dopuštamo određenu desinkronizaciju između podataka u običnom i klasteriranom Redisu.

Održavanje klastera

Neposredno prije selidbe treba razmisliti možemo li podržati klaster:

  • Karte. Koristimo Prometheus i Grafanu za grafički prikaz opterećenja CPU-a, korištenja memorije, broja klijenata, broja GET, SET, AUTH operacija itd.
  • Stručnost. Zamislite da ćete sutra imati ogroman klaster pod svojom odgovornošću. Ako se pokvari, nitko osim vas ne može ga popraviti. Ako počne usporavati, svi će potrčati prema vama. Ako trebate dodati resurse ili preraspodijeliti opterećenje, javite se. Kako ne biste posijedjeli s 25 godina, preporučljivo je predvidjeti te slučajeve i unaprijed provjeriti kako će se tehnologija ponašati pod određenim radnjama. Razgovarajmo o tome detaljnije u odjeljku "Stručnost".
  • Praćenje i upozorenja. Kada se klaster pokvari, želite biti prvi koji će saznati za to. Ovdje smo se ograničili na obavijest da svi čvorovi vraćaju iste informacije o stanju klastera (da, događa se drugačije). A drugi problemi mogu se brže uočiti upozorenjima Redisovih korisničkih usluga.

prijelaz

Kako ćemo se kretati:

  • Prije svega, morate pripremiti biblioteku za rad s klasterom. Kao osnovu za Go verziju uzeli smo go-redis i malo ga promijenili kako bi nam odgovaralo. Implementirali smo Multi-methode kroz cjevovode, a također smo malo ispravili pravila za ponavljanje zahtjeva. PHP verzija je imala više problema, ali smo se na kraju odlučili za php-redis. Nedavno su uveli podršku za klastere i po našem mišljenju izgleda dobro.
  • Zatim trebate implementirati sam klaster. To se radi doslovno u dvije naredbe na temelju konfiguracijske datoteke. O postavci ćemo detaljnije govoriti u nastavku.
  • Za postupno kretanje koristimo suhi način. Budući da imamo dvije verzije biblioteke s istim sučeljem (jedna za običnu verziju, druga za klaster), ne košta ništa napraviti omotač koji će raditi s zasebnom verzijom i paralelno duplicirati sve zahtjeve prema klasteru, usporedite odgovore i zapišite nedosljednosti u zapisnike (u našem slučaju u NewRelic). Stoga, čak i ako se verzija klastera pokvari tijekom uvođenja, to neće utjecati na našu proizvodnju.
  • Nakon što smo izbacili klaster u suhom načinu rada, možemo mirno pogledati grafikon odstupanja odgovora. Ako se stopa pogreške polako, ali sigurno kreće prema nekoj maloj konstanti, onda je sve u redu. Zašto još uvijek postoje odstupanja? Budući da se snimanje u zasebnoj verziji događa malo ranije nego u klasteru, a zbog mikrozastoja podaci se mogu razlikovati. Sve što preostaje je pogledati zapisnike odstupanja, i ako se svi objasne neatomičnim zapisom, onda možemo ići dalje.
  • Sada možete promijeniti suhi način rada u suprotnom smjeru. Iz klastera ćemo pisati i čitati te ga duplicirati u zasebnu verziju. Za što? Tijekom sljedećeg tjedna želio bih promatrati rad klastera. Ako se iznenada ispostavi da postoje problemi pri vršnom opterećenju ili nešto nismo uzeli u obzir, uvijek imamo hitno vraćanje na stari kod i trenutne podatke zahvaljujući suhom načinu rada.
  • Sve što ostaje je onemogućiti suhi način rada i rastaviti zasebnu verziju.

Stručnost

Prvo, ukratko o dizajnu klastera.

Prije svega, Redis je ključ-vrijednost trgovina. Kao ključevi koriste se proizvoljni nizovi. Kao vrijednosti mogu se koristiti brojevi, nizovi i cijele strukture. Potonjih ima jako puno, ali za razumijevanje opće strukture to nam nije važno.
Sljedeća razina apstrakcije nakon ključeva su utori (SLOTS). Svaki ključ pripada jednom od 16 utora. Unutar svakog utora može biti bilo koji broj ključeva. Dakle, svi ključevi su podijeljeni u 383 disjunktna ​​skupa.
O prelasku s Redisa na Redis-klaster

Zatim, u klasteru mora biti N glavnih čvorova. Svaki čvor se može smatrati zasebnom Redis instancom koja zna sve o drugim čvorovima unutar klastera. Svaki glavni čvor sadrži određeni broj utora. Svaki slot pripada samo jednom glavnom čvoru. Svi utori moraju biti raspoređeni između čvorova. Ako neki utori nisu dodijeljeni, tada će ključevi pohranjeni u njima biti nedostupni. Ima smisla pokrenuti svaki glavni čvor na zasebnom logičkom ili fizičkom stroju. Također je vrijedno zapamtiti da svaki čvor radi samo na jednoj jezgri, a ako želite pokrenuti više instanci Redisa na istom logičkom stroju, pobrinite se da rade na različitim jezgrama (ovo nismo isprobali, ali u teoriji bi trebalo raditi) . U biti, glavni čvorovi pružaju redovito dijeljenje, a više glavnih čvorova omogućuje pisanje i čitanje zahtjeva za skaliranje.

Nakon što su svi ključevi raspoređeni među utorima, a utori su raštrkani među glavnim čvorovima, proizvoljan broj podređenih čvorova može se dodati svakom glavnom čvoru. Unutar svake takve nadređeno-podređene veze radit će normalna replikacija. Podređeni uređaji su potrebni za skaliranje zahtjeva za čitanje i za nadogradnju u slučaju greške glavnog.
O prelasku s Redisa na Redis-klaster

Sada razgovarajmo o operacijama koje bi bilo bolje moći izvesti.

Sustavu ćemo pristupiti preko Redis-CLI. Budući da Redis nema jednu ulaznu točku, možete izvršiti sljedeće operacije na bilo kojem od čvorova. U svakoj točki posebno skrećem pozornost na mogućnost izvođenja operacije pod opterećenjem.

  • Prva i najvažnija stvar koju trebamo je rad čvorova klastera. Vraća stanje klastera, prikazuje popis čvorova, njihove uloge, raspodjelu utora itd. Više informacija može se dobiti pomoću informacija o klasteru i utora za klaster.
  • Bilo bi lijepo imati mogućnost dodavanja i uklanjanja čvorova. U tu svrhu postoje operacije susreta klastera i operacije zaboravljanja klastera. Imajte na umu da se zaboravljanje klastera mora primijeniti na SVAKI čvor, i master i replike. A susret klastera treba pozvati samo na jednom čvoru. Ova razlika može biti zabrinjavajuća, pa je najbolje da naučite o njoj prije nego što počnete sa svojim klasterom. Dodavanje čvora obavlja se sigurno u borbi i ni na koji način ne utječe na rad klastera (što je i logično). Ako namjeravate ukloniti čvor iz klastera, trebali biste provjeriti da na njemu nema preostalih utora (inače riskirate gubitak pristupa svim ključevima na ovom čvoru). Također, nemojte brisati master koji ima slave, inače će se izvršiti nepotrebno glasanje za novog mastera. Ako čvorovi više nemaju utore, onda je to mali problem, ali zašto su nam potrebni dodatni izbori ako prvo možemo izbrisati robove.
  • Ako trebate nasilno zamijeniti glavne i podređene položaje, tada će poslužiti naredba za nadogradnju klastera. Kada ga pozivate u bitku, morate shvatiti da gospodar neće biti dostupan tijekom operacije. Tipično se promjena događa za manje od jedne sekunde, ali nije atomska. Možete očekivati ​​da će neki zahtjevi masteru za to vrijeme biti uspješni.
  • Prije uklanjanja čvora iz klastera, na njemu ne smije ostati nijedan utor. Bolje ih je redistribuirati pomoću naredbe cluster reshard. Utori će se prenijeti s jednog mastera na drugi. Cijela operacija može potrajati nekoliko minuta, ovisi o količini podataka koji se prenose, ali je proces prijenosa siguran i ni na koji način ne utječe na rad klastera. Tako se svi podaci mogu prenijeti s jednog čvora na drugi izravno pod opterećenjem i bez brige o njihovoj dostupnosti. Međutim, postoje i suptilnosti. Prvo, prijenos podataka povezan je s određenim opterećenjem čvorova primatelja i pošiljatelja. Ako je primateljski čvor već jako opterećen na procesoru, tada ga ne biste trebali opteretiti primanjem novih podataka. Drugo, čim ne ostane niti jedan slot na masteru koji šalje, svi njegovi podređeni će odmah otići na master na koji su ti slotovi prebačeni. A problem je što će svi ti robovi htjeti sinkronizirati podatke odjednom. I bit ćete sretni ako je sinkronizacija djelomična, a ne potpuna. Uzmite to u obzir i kombinirajte operacije prijenosa utora i onesposobljavanja/prijenosa slave. Ili se nadajte da imate dovoljnu marginu sigurnosti.
  • Što učiniti ako tijekom prijenosa ustanovite da ste negdje izgubili svoje utore? Nadam se da ovaj problem neće utjecati na vas, ali ako se dogodi, postoji operacija popravka klastera. U najmanju ruku, ona će razbacati utore po čvorovima nasumičnim redoslijedom. Preporučujem da provjerite njegov rad tako da prvo uklonite čvor s distribuiranim utorima iz klastera. Budući da su podaci u nedodijeljenim mjestima već nedostupni, prekasno je brinuti se o problemima s dostupnošću tih mjesta. Zauzvrat, operacija neće utjecati na distribuirane utore.
  • Još jedna korisna operacija je monitor. Omogućuje vam da u stvarnom vremenu vidite cijeli popis zahtjeva koji idu prema čvoru. Štoviše, možete ga grep i saznati postoji li potreban promet.

Također je vrijedno spomenuti master failover postupak. Ukratko, postoji i, po mom mišljenju, odlično radi. Međutim, nemojte misliti da ako odspojite kabel za napajanje na stroju s glavnim čvorom, Redis će se odmah prebaciti i klijenti neće primijetiti gubitak. U mojoj praksi, prebacivanje se događa za nekoliko sekundi. Tijekom tog vremena neki će podaci biti nedostupni: otkrivena je nedostupnost nadređenog, čvorovi glasaju za novog, zamijenjeni su podređeni, podaci se sinkroniziraju. Najbolji način da se sami uvjerite da shema funkcionira je provođenje lokalnih vježbi. Podignite klaster na prijenosnom računalu, dajte mu minimalno opterećenje, simulirajte pad (na primjer, blokiranjem portova) i procijenite brzinu prebacivanja. Po mom mišljenju, tek nakon igranja na ovaj način dan ili dva možete biti sigurni u rad tehnologije. Pa, ili se nadamo da softver koji koristi pola interneta vjerojatno radi.

Konfiguracija

Često je konfiguracija prva stvar koju trebate za početak rada s alatom. A kada sve radi, ne želite ni dirati konfiguraciju. Potreban je napor da se natjerate da se vratite na postavke i pažljivo ih prođete. Koliko se sjećam, imali smo najmanje dva ozbiljna kvara zbog nepažnje prema konfiguraciji. Obratite posebnu pozornost na sljedeće točke:

  • timeout 0
    Vrijeme nakon kojeg se neaktivne veze zatvaraju (u sekundama). 0 - ne zatvaraj
    Nije svaka naša knjižnica mogla ispravno zatvoriti veze. Isključivanjem ove postavke riskiramo da dosegnemo ograničenje broja klijenata. S druge strane, ako postoji takav problem, automatski prekid izgubljene veze će ga maskirati, a mi možda nećemo primijetiti. Osim toga, ne biste trebali omogućiti ovu postavku kada koristite postojane veze.
  • Spremi xy i samo dodatak da
    Spremanje RDB snimke.
    U nastavku ćemo detaljno raspravljati o RDB/AOF problemima.
  • stop-writes-on-bgsave-error no & slave-serve-stale-data da
    Ako je omogućeno, ako RDB snimka pokvari, glavni će prestati prihvaćati zahtjeve za promjenama. Ako se veza s masterom izgubi, slave može nastaviti odgovarati na zahtjeve (da). Ili će prestati odgovarati (ne)
    Nismo zadovoljni situacijom u kojoj se Redis pretvara u tikvu.
  • repl-ping-slave-period 5
    Nakon tog vremenskog razdoblja, počet ćemo se brinuti da se master pokvario i da je vrijeme da provedemo postupak prebacivanja u slučaju greške.
    Morat ćete ručno pronaći ravnotežu između lažno pozitivnih rezultata i pokretanja failovera. U našoj praksi to je 5 sekundi.
  • repl-backlog-size 1024mb & epl-backlog-ttl 0
    Točno toliko podataka možemo pohraniti u međuspremnik za neuspjelu repliku. Ako međuspremnik ponestane, morat ćete se potpuno sinkronizirati.
    Praksa pokazuje da je bolje postaviti višu vrijednost. Mnogo je razloga zašto replika može početi kasniti. Ako zaostaje, najvjerojatnije se vaš gospodar već bori s tim, a puna sinkronizacija bit će posljednja kap.
  • najveći broj klijenata 10000
    Maksimalan broj jednokratnih klijenata.
    Prema našem iskustvu, bolje je postaviti višu vrijednost. Redis dobro podnosi 10k veza. Samo provjerite ima li dovoljno utičnica na sustavu.
  • maxmemory-policy volatile-ttl
    Pravilo prema kojem se ključevi brišu kada se dosegne ograničenje dostupne memorije.
    Ovdje nije važno samo pravilo, već razumijevanje kako će se to dogoditi. Redis se može pohvaliti za sposobnost normalnog rada kada se dosegne ograničenje memorije.

RDB i AOF problemi

Iako Redis sam pohranjuje sve informacije u RAM, postoji i mehanizam za spremanje podataka na disk. Točnije, tri mehanizma:

  • RDB-snimak - potpuni snimak svih podataka. Postavite pomoću konfiguracije SAVE XY i glasi "Spremi punu snimku svih podataka svakih X sekundi ako se promijenilo najmanje Y tipki."
  • Datoteka samo za dodavanje - popis operacija redoslijedom kojim se izvode. Dodaje nove dolazne operacije u datoteku svakih X sekundi ili svakih Y operacija.
  • RDB i AOF su kombinacija prethodna dva.

Sve metode imaju svoje prednosti i nedostatke, neću ih sve nabrajati, samo ću skrenuti pozornost na točke koje, po mom mišljenju, nisu očite.

Prvo, spremanje RDB snimke zahtijeva pozivanje FORK-a. Ako ima puno podataka, to može zaustaviti cijeli Redis na period od nekoliko milisekundi do sekunde. Osim toga, sustav mora dodijeliti memoriju za takvu snimku, što dovodi do potrebe da se zadrži dvostruka količina RAM-a na logičkom stroju: ako je 8 GB dodijeljeno za Redis, tada bi 16 GB trebalo biti dostupno na virtualnom stroju s to.

Drugo, postoje problemi s djelomičnom sinkronizacijom. U AOF modu, kada se podređeni uređaj ponovno spoji, umjesto djelomične sinkronizacije može se izvršiti puna sinkronizacija. Zašto se to događa, nisam mogao razumjeti. Ali vrijedi zapamtiti ovo.

Ove dvije točke već nas tjeraju na razmišljanje trebaju li nam ti podaci na disku ako je sve već duplicirano od strane robova. Podaci se mogu izgubiti samo ako svi podređeni uređaji zakažu, a to je problem razine "požara u DC-u". Kao kompromis, možete predložiti spremanje podataka samo na podređene uređaje, ali u ovom slučaju morate biti sigurni da ti podređeni uređaji nikada neće postati glavni tijekom oporavka od katastrofe (za to postoji postavka prioriteta podređenih uređaja u njihovoj konfiguraciji). Za sebe, u svakom konkretnom slučaju razmišljamo je li potrebno podatke spremati na disk, a najčešće je odgovor “ne”.

Zaključak

Zaključno, nadam se da sam uspio dati opću ideju o tome kako redis-cluster radi onima koji uopće nisu čuli za njega, a također sam skrenuo pozornost na neke neočite točke onima koji su ga koristili dugo vremena.
Hvala na vašem vremenu i, kao i uvijek, komentari na temu su dobrodošli.

Izvor: www.habr.com

Dodajte komentar