Redis Cluster: horizontalus plečiamumas

Kas yra Redis Cluster ir kodėl jis reikalingas

Kai jūsų aplikacija auga, vienas Redis serveris gali tapti kliūtimi. Duomenų kiekis didėja, užklausų srautas intensyvėja, o jūs staiga susiduriate su situacija, kai vieno serverio atmintis ir procesorius nebegali visko apdoroti. Čia ir ateina į pagalbą Redis Cluster – sprendimas, leidžiantis paskirstyti duomenis tarp kelių Redis mazgų.

Redis Cluster nėra tiesiog keletas Redis serverių, dirbančių kartu. Tai sudėtinga sistema su automatišku duomenų paskirstymu, atkūrimu po gedimų ir gebėjimu tęsti darbą net praradus dalį mazgų. Skirtingai nuo paprastos master-replica konfigūracijos, kur replica tik dubliuoja duomenis, Cluster leidžia horizontaliai plėsti ir saugojimo talpą, ir apdorojimo galią.

Pagrindinė idėja paprasta: duomenys automatiškai paskirstomi tarp kelių master mazgų, o kiekvienas master gali turėti savo replicas. Jei vienas master iškrista, jo replica automatiškai tampa nauju master. Tai reiškia, kad galite turėti ne tik didesnę talpą, bet ir aukštesnę prieinamumą.

Hash slots: kaip Redis paskirsto duomenis

Redis Cluster naudoja gana elegantišką būdą nuspręsti, kuriame mazge saugoti kiekvieną raktą. Visas raktų erdvė padalinta į 16384 hash slots (maišos lizdus). Kai įrašote raktą, Redis apskaičiuoja jo CRC16 maišą ir pritaiko modulo operaciją su 16384, taip gaudamas slot numerį.

Pavyzdžiui, raktas „user:1000” gali patekti į slot 5461, o „session:abc123” – į slot 12890. Šie slots yra paskirstyti tarp visų master mazgų. Jei turite tris master mazgus, pirmasis gali būti atsakingas už slots 0-5460, antrasis už 5461-10922, o trečiasis už 10923-16383.


# Pavyzdys: kaip Redis nusprendžia, kur saugoti raktą
CRC16("user:1000") % 16384 = 5461
CRC16("session:abc123") % 16384 = 12890

Šis mechanizmas leidžia lengvai pridėti ar pašalinti mazgus – tiesiog perkeliate slots iš vieno mazgo į kitą. Redis Cluster palaiko net „live” perkėlimą, kai duomenys perkeliami netrukdant aplikacijos veikimo. Tai nėra momentinis procesas, bet jis vyksta fone, o klientai gali toliau dirbti.

Svarbu suprasti, kad dėl šio paskirstymo mechanizmo kai kurios Redis operacijos tampa sudėtingesnės. Pavyzdžiui, operacijos, kurios dirba su keliais raktais vienu metu (kaip MGET ar transakcijos), veiks tik tada, kai visi raktai yra tame pačiame slot’e.

Cluster topologija ir konfigūracija

Minimalus Redis Cluster reikalauja bent trijų master mazgų. Kodėl trijų? Dėl kvorum – daugumos, reikalingos priimti sprendimus apie gedimus. Su trimis mazgais galite prarasti vieną ir vis dar turėti daugumą (2 iš 3). Su dviem mazgais praradus vieną, nebelieka daugumos, ir cluster negali priimti sprendimų apie atkūrimą.

Praktikoje rekomenduojama konfigūracija yra bent 6 mazgai: 3 master ir 3 replica. Taip užtikrinate, kad kiekvienas master turi bent vieną repliką, kuri gali perimti jo vaidmenį gedimo atveju.


# Tipinė cluster konfigūracija redis.conf
port 7000
cluster-enabled yes
cluster-config-file nodes-7000.conf
cluster-node-timeout 5000
appendonly yes

Kiekvienas mazgas saugo informaciją apie visą cluster topologiją – kurie mazgai egzistuoja, kurie slots jiems priskirti, kurie mazgai yra master, o kurie replica. Ši informacija sklinda tarp mazgų naudojant gossip protokolą. Kiekvienas mazgas periodiškai keičiasi informacija su kitais, todėl visi galiausiai turi tą pačią topologijos viziją.

Kai kuriate naują cluster, turite nurodyti, kurie slots priskiriami kiekvienam master. Redis pateikia įrankį redis-cli --cluster create, kuris automatiškai paskirsto slots tolygiai. Bet galite tai padaryti ir rankiniu būdu, jei reikia specifinės konfigūracijos.

Failover mechanizmas ir aukštas prieinamumas

Vienas iš svarbiausių Redis Cluster privalumų yra automatinis atkūrimas po gedimų. Kai master mazgas iškrista, jo replica automatiškai tampa nauju master. Šis procesas vyksta be žmogaus įsikišimo ir paprastai užtrunka kelias sekundes.

Kaip tai veikia? Kiekvienas mazgas nuolat stebi kitus mazgus siųsdamas PING žinutes. Jei mazgas neatsiliepia per cluster-node-timeout laiką, jis laikomas įtartinu (PFAIL – Possible Failure). Kai dauguma master mazgų sutinka, kad mazgas neveikia, jis pažymimas kaip tikrai neveikiantis (FAIL).

Tada prasideda replica promocija. Jei neveikiantis mazgas buvo master, jo replicos pradeda rinkimus. Replica su naujausiais duomenimis (didžiausiu replication offset) paprastai laimi ir tampa nauju master. Kitos replicos ir visi klientai automatiškai persijungia prie naujo master.


# Stebėti cluster būseną
redis-cli --cluster check 127.0.0.1:7000

# Peržiūrėti cluster mazgus
redis-cli -c -p 7000 cluster nodes

Svarbu suprasti, kad Redis Cluster nėra 100% duomenų saugumas. Jei master iškrista prieš spėdamas replikuoti naujausius įrašus į savo replikas, tie duomenys prarandami. Redis prioritizuoja greitį ir prieinamumą, o ne absoliutų duomenų saugumą. Jei jums reikia garantuoto duomenų saugumo, turėtumėte naudoti WAIT komandą, kuri blokuoja, kol duomenys replikuojami į nurodytą skaičių replikų.

Klientų sąveika su Cluster

Dirbant su Redis Cluster, jūsų aplikacija turi žinoti, kad duomenys paskirstyti tarp kelių mazgų. Laimei, dauguma Redis klientų bibliotekų palaiko cluster režimą ir automatiškai tvarko nukreipimus.

Kai klientas bando pasiekti raktą, kuris yra kitame mazge, Redis atsako su MOVED klaida, nurodančia teisingą mazgą. Cluster-aware klientas automatiškai persijungia prie nurodyto mazgo ir pakartoja užklausą. Pavyzdžiui:


# Klientas kreipiasi į neteisingą mazgą
GET user:1000
# Redis atsako:
-MOVED 5461 127.0.0.1:7001

# Klientas automatiškai persijungia ir pakartoja

Yra ir ASK nukreipimas, kuris naudojamas, kai slots perkeliamas iš vieno mazgo į kitą. Skirtingai nuo MOVED, ASK yra laikinas – jis sako „šį kartą eik ten, bet kitam kartui vis dar kreipkis čia”.

Programuojant su Redis Cluster, turite atsižvelgti į keletą dalykų. Pirma, operacijos su keliais raktais veiks tik tada, kai visi raktai yra tame pačiame slot’e. Galite tai užtikrinti naudodami hash tags:


# Šie raktai bus tame pačiame slot'e
SET {user:1000}:profile "data1"
SET {user:1000}:settings "data2"
# Tik tekstas tarp {} naudojamas hash skaičiavimui

Antra, Lua skriptai ir transakcijos taip pat turi dirbti tik su raktais iš vieno slot’o. Trečia, kai kurios komandos, kaip KEYS ar SCAN, veikia tik vieno mazgo kontekste – jei norite nuskaityti visus cluster raktus, turite kreiptis į kiekvieną mazgą atskirai.

Plėtimas ir slots perkėlimas

Vienas iš pagrindinių Redis Cluster privalumų yra galimybė pridėti naujus mazgus be prastovų. Procesas paprastas: pridedame naują mazgą, prijungiame jį prie cluster, ir perkeliame dalį slots iš esamų mazgų į naująjį.


# Pridėti naują mazgą prie cluster
redis-cli --cluster add-node 127.0.0.1:7006 127.0.0.1:7000

# Perskirstyti slots
redis-cli --cluster reshard 127.0.0.1:7000

Slots perkėlimas vyksta fone ir netrukdo aplikacijos veikimo. Redis naudoja protingą mechanizmą: kai slots perkeliamas, jis kurį laiką yra „migruojančios” būsenos. Nauji raktai jau rašomi į naują mazgą, o esami raktai perkeliami palaipsniui. Jei klientas bando pasiekti raktą, kuris dar neperkeltas, jis gauna ASK nukreipimą.

Svarbu suprasti, kad slots perkėlimas gali užtrukti, ypač jei turite daug duomenų. Didelis slot gali turėti milijonus raktų, ir jų perkėlimas gali trukti minutes ar net valandas. Per tą laiką cluster veikia normaliai, bet yra šiek tiek padidėjęs latency dėl papildomo darbo.

Kai pašalinate mazgą iš cluster, pirmiausia turite perkelti visus jo slots į kitus mazgus. Tik tada galite saugiai pašalinti mazgą:


# Pašalinti mazgą (pirmiausia perkelkite visus jo slots!)
redis-cli --cluster del-node 127.0.0.1:7000

Monitoringas ir problemų sprendimas

Redis Cluster monitoringas yra kritiškai svarbus. Turite stebėti ne tik atskirų mazgų būseną, bet ir visos cluster sveikatos rodiklius. Pagrindiniai dalykai, į kuriuos reikia atkreipti dėmesį:

  • Kiekvieno mazgo atmintis ir CPU naudojimas
  • Replication lag – kiek replica atsilieka nuo master
  • Cluster būsena – ar visi slots priskirti, ar nėra gedimų
  • Slots paskirstymas – ar duomenys tolygiai paskirstyti
  • Tinklo latency tarp mazgų

Redis pateikia keletą naudingų komandų monitoringui:


# Cluster informacija
CLUSTER INFO

# Mazgų sąrašas ir jų būsena
CLUSTER NODES

# Konkretaus slot'o informacija
CLUSTER SLOTS

# Mazgo statistika
INFO replication
INFO stats

Dažna problema – „split brain” situacija, kai tinklo problemos lemia, kad dalis cluster mano, jog kitas mazgas neveikia, nors iš tikrųjų jis veikia. Redis Cluster turi apsaugos mechanizmus nuo to, bet vis tiek galite susidurti su laikinais duomenų praradimais.

Kita problema – netolygus duomenų paskirstymas. Jei turite „hot keys” – raktus, kurie gaunami daug dažniau nei kiti – vienas mazgas gali būti perkrautas, o kiti beveik tušti. Redis Cluster nepalaiko automatinio hot keys perkėlimo, todėl turite tai spręsti aplikacijos lygmenyje, pavyzdžiui, naudodami local cache.

Jei cluster patenka į nesuderinamą būseną (pavyzdžiui, kai du mazgai mano esantys atsakingi už tuos pačius slots), galite naudoti CLUSTER SETSLOT komandą rankiniam taisymui. Bet būkite atsargūs – neteisingas naudojimas gali sukelti duomenų praradimą.

Praktiniai patarimai ir geriausia praktika

Įgyvendinant Redis Cluster gamybinėje aplinkoje, yra keletas dalykų, kuriuos būtina žinoti. Pirma, visada naudokite bent tris master mazgus. Du nepakanka, nes praradus vieną, nebelieka kvorum. Penki ar septyni master yra dar geriau, ypač jei tikitės didelių apkrovų ar norite aukšto prieinamumo.

Antra, kiekvienas master turėtų turėti bent vieną repliką, o geriau – dvi. Replica turėtų būti kitame fiziniame serveryje ar bent availability zone. Jei master ir jo replica yra tame pačiame serveryje, serverio gedimas išmuš abu.

Trečia, atidžiai planuokite atmintį. Redis Cluster neturi automatinio duomenų išmetimo tarp mazgų. Jei vienas mazgas prisipildo, jis prisipildo – duomenys nebus automatiškai perkelti į kitus mazgus. Turėtumėte nustatyti maxmemory ir maxmemory-policy kiekvienam mazgui.


# Rekomenduojama konfigūracija
maxmemory 2gb
maxmemory-policy allkeys-lru
cluster-require-full-coverage no # Leisti cluster veikti net jei ne visi slots prieinami

Ketvirta, naudokite persistence (AOF ar RDB) bent master mazguose. Taip, tai sulėtins įrašymo operacijas, bet apsaugos nuo duomenų praradimo, jei visas cluster staiga išsijungia. AOF su appendfsync everysec yra geras kompromisas tarp greičio ir saugumo.

Penkta, testuokite failover scenarijus. Specialiai išjunkite master mazgą ir pažiūrėkite, kaip greitai replica perima jo vaidmenį, kaip elgiasi jūsų aplikacija. Geriau sužinoti apie problemas testuose nei gamyboje.

Kada Redis Cluster yra tinkamas pasirinkimas ir kada ne

Redis Cluster nėra visada geriausias sprendimas. Jei jūsų duomenų kiekis telpa į vieno serverio atmintį ir neturite ekstremalių prieinamumo reikalavimų, paprastas master-replica setup gali būti paprastesnis ir lengviau valdomas.

Cluster turi prasmę, kai:
– Jūsų duomenų kiekis viršija vieno serverio atmintį
– Reikia daugiau nei 100,000 operacijų per sekundę
– Norite aukšto prieinamumo su automatiniu failover
– Planuojate augti ir norite galimybės lengvai pridėti resursų

Bet Cluster nėra idealus, kai:
– Jūsų aplikacija daug naudoja multi-key operacijas
– Reikia transakcijų su raktais iš skirtingų slots
– Turite daug Lua skriptų, kurie dirba su keliais raktais
– Komanda neturi patirties su paskirstytomis sistemomis

Alternatyvos Redis Cluster yra Redis Sentinel (automatinis failover be sharding), proxy sprendimai kaip Twemproxy ar Envoy, arba visiškai kiti sprendimai kaip Hazelcast ar Memcached su consistent hashing. Kiekvienas turi savo privalumų ir trūkumų.

Svarbiausia – suprasti savo poreikius. Jei jums reikia tik cache su automatišku failover, Sentinel gali būti paprastesnis. Jei reikia sudėtingų duomenų struktūrų ir milijardų raktų, Cluster yra kelias. Jei reikia garantuoto duomenų saugumo ir ACID transakcijų, galbūt Redis apskritai nėra tinkamas įrankis – žiūrėkite į PostgreSQL ar panašias duomenų bazes.

Redis Cluster – tai galingas įrankis, bet kaip ir su bet kokiu paskirstytu sistemu, jis prideda sudėtingumo. Įsitikinkite, kad tas sudėtingumas yra pateisinamas jūsų poreikiais. Kartais paprastas sprendimas yra geriausias sprendimas.

Daugiau

Saugūs mokėjimai internete, ką tikrinti prieš patvirtinant