O prelasku iz Redis-a u Redis-cluster

O prelasku iz Redis-a u Redis-cluster

S obzirom na proizvod koji se razvijao više od jedne decenije, uopće nije iznenađujuće pronaći zastarjele tehnologije u njemu. Ali šta ako za šest mjeseci morate zadržati opterećenje 10 puta veće, a cijena padova će se povećati stotinama puta? U ovom slučaju, potreban vam je cool Highload Engineer. Ali u nedostatku sobarice, povjerili su mi rješavanje problema. U prvom dijelu članka ću vam reći kako smo prešli sa Redis-a na Redis-cluster, a u drugom dijelu ću vam dati savjete kako početi koristiti klaster i na šta obratiti pažnju prilikom korištenja.

Izbor tehnologije

Je li to tako loše? odvojeni Redis (samostalni redis) u konfiguraciji od 1 master i N slave? Zašto to nazivam zastarjelom tehnologijom?

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

  • Prvo, Redis ne podržava mehanizme oporavka od katastrofe nakon glavnog kvara. Da bismo riješili ovaj problem, koristili smo konfiguraciju sa automatskim prijenosom VIP-a na novog mastera, promjenom uloge jednog od slave-ova i prebacivanjem ostalih. Ovaj mehanizam je funkcionirao, ali se ne može nazvati pouzdanim rješenjem. Prvo, dogodili su se lažni alarmi, a drugo, bio je jednokratan, a nakon operacije su bile potrebne ručne radnje za punjenje opruge.

  • Drugo, postojanje samo jednog mastera dovelo je do problema shardinga. Morali smo kreirati nekoliko nezavisnih klastera „1 master i N slave-ova“, zatim ručno distribuirati baze podataka između ovih mašina i nadati se da sutra jedna od baza podataka neće toliko nabubriti da će morati da bude premještena u zasebnu instancu.

Koje su mogućnosti?

  • Najskuplje i najbogatije rješenje je Redis-Enterprise. Ovo je upakirano rješenje s punom tehničkom podrškom. Unatoč činjenici da sa tehničke strane izgleda idealno, iz ideoloških razloga nam nije odgovarao.
  • Redis-klaster. Izvan kutije postoji podrška za master failover i sharding. Interfejs se gotovo ne razlikuje od obične verzije. Izgleda obećavajuće, o zamkama ćemo kasnije.
  • Tarantool, Memcache, Aerospike i drugi. Svi ovi alati rade otprilike istu stvar. Ali svaki ima svoje nedostatke. Odlučili smo da ne stavljamo sva jaja u jednu korpu. 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čnost upotrebe

Hajde da pogledamo koje smo probleme kroz istoriju rešavali sa Redisom i koju smo funkcionalnost koristili:

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

    PODEŠITE MGET MSET "SELECT DB"

  • Cache prije MYSQL | PHP

    PODEŠITE MGET MSET SKENIRAJTE "KLJUČ PO UBRAZCU" "IZABIR DB"

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

    POSTAVI MGET MSET "IZABIR DB" "DODAJ GEO KLJUČ" "UZI GEO KLJUČ" SKENIRAJ

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

Metoda
Opis
Karakteristike Redis-klastera
odluka

POSTAVI SE
Ključ 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 s cjevovodom N GET operacija

SELECT 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
Prođite kroz sve ključeve u bazi podataka
Pošto imamo jednu bazu podataka, prolazak kroz sve ključeve u klasteru je preskup
Održavajte invarijantu unutar jednog ključa i izvršite HSCAN na ovom ključu. Ili potpuno odbiti

GEO
Operacije sa geoključem
Geoključ nije podijeljen

KLJUČ PO UZORU
Traženje ključa po uzorku
Pošto imamo jednu bazu podataka, pretraživat ćemo sve ključeve u klasteru. Preskupo
Odbijte ili održavajte invarijantu, kao u slučaju SCAN-a

Redis vs Redis-cluster

Šta gubimo, a šta dobijamo prelaskom na klaster?

  • Nedostaci: gubimo funkcionalnost nekoliko baza podataka.
    • Ako želimo pohraniti logički nepovezane podatke 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 su postale mnogo teže implementirati jer može zahtijevati pristup nekoliko čvorova.
  • Prednosti:
    • Tolerancija grešaka u obliku master failover.
    • Sharding na Redis strani.
    • Prijenos podataka između čvorova atomski i bez zastoja.
    • Dodajte i preraspodijelite kapacitet i opterećenja bez zastoja.

Zaključio bih da ako ne morate osigurati visok nivo tolerancije grešaka, 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 klaster verzije, onda biste trebali odabrati klaster, jer nije ništa lošiji i, osim toga, oslobodit će vas neke od glavobolja

Priprema za selidbu

Počnimo sa zahtjevima za selidbu:

  • Trebalo bi da bude besprekorno. Potpuno zaustavljanje usluge na 5 minuta nam ne odgovara.
  • Trebalo bi da bude što sigurnije i postepeno. Želim da imam kontrolu nad situacijom. Ne želimo da bacimo sve odjednom i da se molimo preko dugmeta za vraćanje nazad.
  • Minimalni gubitak podataka prilikom kretanja. Razumijemo da će biti vrlo teško atomski premjestiti, tako da dozvoljavamo određenu desinhronizaciju između podataka u redovnom i grupisanom Redis-u.

Održavanje klastera

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

  • Charts. Koristimo Prometheus i Grafanu za grafikon opterećenja CPU-a, upotrebe 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, niko osim vas ne može to popraviti. Ako počne da usporava, svi će potrčati prema vama. Ako trebate dodati resurse ili preraspodijeliti opterećenje, vratite se vama. Kako ne bi posijedili sa 25 godina, preporučljivo je predvidjeti ove 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 da prvi saznate 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). I drugi problemi se mogu brže uočiti po upozorenjima Redis klijentskih usluga.

U pokretu

Kako ćemo se kretati:

  • Prije svega, morate pripremiti biblioteku za rad s klasterom. Uzeli smo go-redis kao osnovu za Go verziju i malo ga promijenili da nam odgovara. Implementirali smo Multi-methode kroz pipeline-e, a također smo malo korigirali pravila za ponavljanje zahtjeva. PHP verzija je imala više problema, ali smo se na kraju odlučili na php-redis. Nedavno su uveli podršku za klastere i to po našem mišljenju izgleda dobro.
  • Zatim morate postaviti sam klaster. Ovo se radi doslovno u dvije naredbe na osnovu konfiguracijske datoteke. U nastavku ćemo detaljnije razgovarati o postavci.
  • Za postepeno kretanje koristimo suhi način rada. Budući da imamo dvije verzije biblioteke sa istim interfejsom (jednu za redovnu verziju, drugu za klaster), ništa ne košta kreiranje omotača koji će raditi sa zasebnom verzijom i paralelno duplirati sve zahteve prema klasteru, uporedi odgovore i upiši nepodudarnosti u dnevnike (u našem slučaju u NewRelic-u). Stoga, čak i ako se klaster verzija pokvari tokom uvođenja, naša proizvodnja neće biti pogođena.
  • Nakon što smo izbacili klaster u suhom modu, možemo mirno gledati graf neslaganja odgovora. Ako se stopa greške polako, ali sigurno kreće prema nekoj maloj konstanti, onda je sve u redu. Zašto još uvijek postoje neslaganja? Budući da se snimanje u zasebnoj verziji događa nešto ranije nego u klasteru, a zbog mikrolagovanja podaci se mogu razlikovati. Ostaje samo da pogledamo dnevnike neslaganja, i ako se svi objasne neatomarnošću zapisa, onda možemo nastaviti dalje.
  • Sada možete prebaciti suhi način rada u suprotnom smjeru. Pisaćemo i čitati iz klastera, i duplirati ga u posebnu verziju. Za što? U toku naredne sedmice želio bih da posmatram rad klastera. Ako se iznenada pokaže 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.
  • Ostaje samo onemogućiti suhi način rada i demontirati zasebnu verziju.

Stručnost

Prvo, ukratko o dizajnu klastera.

Prije svega, Redis je skladište ključ/vrijednost. Proizvoljni nizovi se koriste kao ključevi. Brojevi, nizovi i cijele strukture mogu se koristiti kao vrijednosti. Potonjih je jako puno, ali za razumijevanje opšte strukture to nam nije važno.
Sljedeći nivo apstrakcije nakon ključeva su slotovi (SLOTS). Svaki ključ pripada jednom od 16 slota. Unutar svakog slota može biti bilo koji broj ključeva. Dakle, svi ključevi su podijeljeni u 383 disjunktna ​​skupa.
O prelasku iz Redis-a u Redis-cluster

Zatim, mora postojati N glavnih čvorova u klasteru. 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 slotova. Svaki slot pripada samo jednom glavnom čvoru. Svi slotovi moraju biti raspoređeni između čvorova. Ako neki slotovi nisu dodijeljeni, tada će ključevi pohranjeni u njima biti nedostupni. Ima smisla pokrenuti svaki glavni čvor na zasebnoj logičkoj ili fizičkoj mašini. Također je vrijedno zapamtiti da svaki čvor radi samo na jednom jezgru, a ako želite pokrenuti više instanci Redis-a na istoj logičkoj mašini, pobrinite se da rade na različitim jezgrama (nismo probali ovo, ali u teoriji bi trebalo funkcionirati) . U suštini, glavni čvorovi pružaju redovno dijeljenje, a više glavnih čvorova omogućava skaliranje zahtjeva za pisanje i čitanje.

Nakon što su svi ključevi raspoređeni među slotovima, a slotovi su raštrkani među glavnim čvorovima, proizvoljan broj slave čvorova može se dodati svakom glavnom čvoru. Unutar svake takve veze master-slave, normalna replikacija će raditi. Slave-ovi su potrebni za skaliranje zahtjeva za čitanje i za prelazak na grešku u slučaju kvara glavnog.
O prelasku iz Redis-a u Redis-cluster

Hajde sada da pričamo o operacijama koje bi bilo bolje moći da radimo.

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

  • Prva i najvažnija stvar koja nam je potrebna je operacija čvorova klastera. Vraća stanje klastera, prikazuje listu čvorova, njihove uloge, distribuciju slotova itd. Više informacija se može dobiti pomoću informacija o klasteru i slotova za klastere.
  • Bilo bi lijepo imati mogućnost dodavanja i uklanjanja čvorova. U tu svrhu postoje operacije sastajanja klastera i zaboravljanja klastera. Imajte na umu da se zaborav klastera mora primijeniti na SVAKI čvor, i master i replike. A sastanak klastera treba pozvati samo na jednom čvoru. Ova razlika može biti zbunjujuća, pa je najbolje naučiti o njoj prije nego što krenete uživo sa svojim klasterom. Dodavanje čvora se obavlja bezbedno u borbi i ni na koji način ne utiče na rad klastera (što je i logično). Ako želite da uklonite čvor iz klastera, treba da se uverite da na njemu ne ostane nijedan utor (inače rizikujete da izgubite pristup 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 slotove, onda je to mali problem, ali zašto su nam potrebni dodatni izbori ako prvo možemo izbrisati slave.
  • Ako trebate nasilno zamijeniti glavni i podređeni položaj, onda će naredba za nadilaženje klastera biti dovoljna. Kada ga pozovete u bitku, morate shvatiti da gospodar neće biti dostupan tokom operacije. Prebacivanje se obično dešava za manje od jedne sekunde, ali nije atomsko. Možete očekivati ​​da će neki zahtjevi prema masteru propasti tokom ovog vremena.
  • Prije uklanjanja čvora iz klastera, na njemu ne bi trebalo ostati slotova. Bolje ih je redistribuirati pomoću naredbe cluster reshard. Slotovi će se prenijeti s jednog mastera na drugi. Cijela operacija može potrajati nekoliko minuta, ovisi o količini podataka koji se prenose, ali proces prijenosa je siguran i ni na koji način ne utiče na rad klastera. Tako se svi podaci mogu prenijeti s jednog čvora na drugi direktno pod opterećenjem i bez brige o njihovoj dostupnosti. Međutim, postoje i suptilnosti. Prvo, prijenos podataka je povezan s određenim opterećenjem čvorova primatelja i pošiljatelja. Ako je čvor primatelja već jako opterećen na procesoru, onda ga ne biste trebali učitavati primanjem novih podataka. Drugo, čim ne preostane niti jedan slot na masteru koji šalje, svi njegovi slave će odmah otići do mastera na koji su ti slotovi prebačeni. A problem je u tome što će svi ovi robovi htjeti sinkronizirati podatke odjednom. I imat ćete sreće ako je to djelomična, a ne potpuna sinhronizacija. Uzmite ovo u obzir i kombinirajte operacije prijenosa slotova i onemogućavanja/prenosa slave. Ili se nadati da imate dovoljnu marginu sigurnosti.
  • Šta treba da uradite ako tokom transfera ustanovite da ste negde izgubili svoje slotove? Nadam se da vas ovaj problem neće utjecati, ali ako se dogodi, postoji operacija popravljanja klastera. U najmanju ruku, ona će raspršiti utore po čvorovima nasumičnim redoslijedom. Preporučujem da provjerite njegov rad tako što ćete prvo ukloniti čvor s distribuiranim slotovima iz klastera. Budući da su podaci u nedodijeljenim slotovima već nedostupni, prekasno je brinuti se o problemima s dostupnošću ovih slotova. Zauzvrat, operacija neće utjecati na distribuirane slotove.
  • Još jedna korisna operacija je monitor. Omogućava vam da vidite u realnom vremenu cijelu listu zahtjeva koji idu do čvora. Štaviše, možete ga uhvatiti i saznati da li postoji potreban promet.

Vrijedi spomenuti i glavnu proceduru prelaska na grešku. Ukratko, postoji i, po mom mišljenju, odlično funkcionira. Međutim, nemojte misliti da ako isključite kabel za napajanje na stroju s glavnim čvorom, Redis će se odmah prebaciti i klijenti neće primijetiti gubitak. U mojoj praksi, prebacivanje se dešava za nekoliko sekundi. Za to vrijeme, neki od podataka će biti nedostupni: otkrivena je nedostupnost mastera, čvorovi glasaju za novi, slave-ovi se mijenjaju, podaci se sinkroniziraju. Najbolji način da se uvjerite da shema funkcionira je da provodite lokalne vježbe. Podignite klaster na svom laptopu, 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-dva možete biti sigurni u rad tehnologije. Pa, ili se nadamo da softver koji koristi polovina interneta vjerovatno radi.

Konfiguracija

Često je konfiguracija prva stvar koju trebate da počnete raditi s alatom. A kada sve radi, ne želite ni dirati konfiguraciju. Potrebno je malo truda da se prisilite da se vratite na postavke i pažljivo ih prođete. U mom sećanju, imali smo najmanje dva ozbiljna kvara zbog nepažnje o konfiguraciji. Obratite posebnu pažnju na sljedeće tačke:

  • istek 0
    Vrijeme nakon kojeg se neaktivne veze zatvaraju (u sekundama). 0 - ne zatvaraj
    Nije svaka naša biblioteka mogla ispravno zatvoriti veze. Onemogućavanjem ove postavke rizikujemo da dostignemo ograničenje broja klijenata. S druge strane, ako postoji takav problem, automatski prekid izgubljenih veza će ga maskirati, a mi ga možda nećemo primijetiti. Osim toga, ne biste trebali omogućiti ovu postavku kada koristite trajne veze.
  • Sačuvajte xy & appendonly da
    Čuvanje RDB snimka.
    U nastavku ćemo detaljno raspravljati o pitanjima RDB/AOF.
  • stop-writes-on-bgsave-error ne & slave-serve-stare-data da
    Ako je omogućeno, ako se RDB snimak pokvari, master će prestati prihvaćati zahtjeve za promjenom. Ako se veza s masterom izgubi, slave može nastaviti odgovarati na zahtjeve (da). Ili će prestati da odgovara (ne)
    Nismo zadovoljni situacijom u kojoj se Redis pretvara u bundevu.
  • repl-ping-slave-period 5
    Nakon ovog vremenskog perioda, počećemo da brinemo da se master pokvario i da je vreme da izvršimo proceduru prelaska na grešku.
    Morat ćete ručno pronaći ravnotežu između lažnih pozitivnih rezultata i pokretanja prelaska na grešku. U našoj praksi to je 5 sekundi.
  • repl-backlog-size 1024mb & epl-backlog-ttl 0
    Možemo pohraniti točno toliko podataka u međuspremnik za neuspjelu repliku. Ako bafer ponestane, morat ćete u potpunosti sinhronizirati.
    Praksa sugerira da je bolje postaviti veću vrijednost. Postoji mnogo razloga zašto bi replika mogla početi da zaostaje. Ako zaostaje, onda se najvjerovatnije vaš gospodar već muči s tim, a puna sinhronizacija će biti posljednja kap.
  • maksimalnih 10000 klijenata
    Maksimalan broj jednokratnih klijenata.
    Prema našem iskustvu, bolje je postaviti veću vrijednost. Redis odlično podnosi 10k konekcija. Samo provjerite ima li dovoljno utičnica na sistemu.
  • maxmemory-policy volatile-ttl
    Pravilo po kojem se ključevi brišu kada se dostigne ograničenje raspoložive memorije.
    Ovdje nije važno samo pravilo, već razumijevanje kako će se to dogoditi. Redis se može pohvaliti zbog njegove sposobnosti da normalno radi kada se dostigne ograničenje memorije.

RDB i AOF problemi

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

  • RDB-snapshot - kompletan snimak svih podataka. Postavite pomoću konfiguracije SAVE XY i glasi "Spremi potpuni snimak svih podataka svakih X sekundi ako su promijenjeni barem Y ključevi."
  • Datoteka samo za dodavanje - lista operacija po redosljedu kojim se izvode. Dodaje nove dolazne operacije u fajl svakih X sekundi ili svake Y operacije.
  • RDB i AOF su kombinacija prethodna dva.

Sve metode imaju svoje prednosti i nedostatke, neću ih sve nabrajati, samo ću skrenuti pažnju na tačke koje, po mom mišljenju, nisu očigledne.

Prvo, spremanje RDB snimka zahtijeva pozivanje FORK-a. Ako ima puno podataka, to može objesiti cijeli Redis na period od nekoliko milisekundi do sekunde. Osim toga, sistem treba da dodijeli memoriju za takav snimak, što dovodi do potrebe da se zadrži duplo zalihe RAM-a na logičkoj mašini: ako je 8 GB dodijeljeno za Redis, onda bi 16 GB trebalo biti dostupno na virtuelnoj mašini sa to.

Drugo, postoje problemi s djelomičnom sinhronizacijom. U AOF modu, kada je slave ponovo povezan, umjesto djelomične sinhronizacije, može se izvršiti potpuna sinhronizacija. Zašto se to dešava, nisam mogao razumjeti. Ali vrijedi zapamtiti ovo.

Ove dvije točke nas već navode na razmišljanje o tome da li su nam zaista potrebni ovi podaci na disku ako je sve već duplicirano od strane slave-ova. Podaci se mogu izgubiti samo ako svi podređeni pokvare, a ovo je problem na nivou „požar u DC“. Kao kompromis, možete predložiti spremanje podataka samo na slave-ovima, ali u ovom slučaju morate biti sigurni da ovi slave nikada neće postati master tokom oporavka od katastrofe (za to postoji postavka prioriteta slave-a u njihovoj konfiguraciji). Za sebe, u svakom konkretnom slučaju razmišljamo o tome da li je potrebno pohranjivati ​​podatke na disk, a najčešće je odgovor „ne“.

zaključak

U zaključku, nadam se da sam uspio dati opću predstavu o tome kako radi redis-cluster za one koji uopće nisu čuli za njega, a također sam skrenuo pažnju na neke neočigledne točke za one koji ga koriste dugo vremena.
Hvala na izdvojenom vremenu i, kao i uvijek, komentari na temu su dobrodošli.

izvor: www.habr.com

Dodajte komentar