Sobre el trasllat de Redis a Redis-cluster

Sobre el trasllat de Redis a Redis-cluster

Arribats a un producte que s'ha desenvolupat durant més d'una dècada, no és gens estrany trobar-hi tecnologies obsoletes. Però, què passa si en sis mesos has de mantenir la càrrega 10 vegades superior i el cost de les caigudes augmentarà centenars de vegades? En aquest cas, necessiteu un enginyer de càrrega alta. Però en absència d'una minyona, em van confiar la resolució del problema. A la primera part de l'article us explicaré com vam passar de Redis a Redis-cluster, i a la segona part donaré consells sobre com començar a utilitzar el clúster i en què cal prestar atenció a l'hora d'utilitzar-lo.

Selecció de tecnologia

És tan dolent? separa Redis (redis autònom) en una configuració d'1 mestre i N esclaus? Per què en dic tecnologia obsoleta?

No, Redis no està tan malament... Tanmateix, hi ha algunes mancances que no es poden ignorar.

  • En primer lloc, Redis no admet mecanismes de recuperació de desastres després d'una fallada mestra. Per solucionar aquest problema, hem utilitzat una configuració amb transferència automàtica de VIPs a un nou mestre, canviant el rol d'un dels esclaus i canviant la resta. Aquest mecanisme va funcionar, però no es podia anomenar una solució fiable. En primer lloc, es van produir falses alarmes i, en segon lloc, era d'un sol ús, i després de l'operació es van requerir accions manuals per carregar la molla.

  • En segon lloc, tenir només un mestre va provocar el problema de la fragmentació. Vam haver de crear diversos clústers independents "1 mestre i N esclaus", després distribuir manualment les bases de dades entre aquestes màquines i esperar que demà una de les bases de dades no s'inflassi tant que s'hagués de traslladar a una instància separada.

Quines són les opcions?

  • La solució més cara i rica és Redis-Enterprise. Aquesta és una solució en caixa amb suport tècnic complet. Tot i que des del punt de vista tècnic sembli ideal, no ens va agradar per raons ideològiques.
  • Redis-cluster. Fora de la caixa, hi ha suport per a la migració per error mestre i la fragmentació. La interfície gairebé no és diferent de la versió normal. Sembla prometedor, més endavant parlarem de les trampes.
  • Tarantool, Memcache, Aerospike i altres. Totes aquestes eines fan pràcticament el mateix. Però cadascun té les seves mancances. Vam decidir no posar tots els nostres ous en una cistella. Utilitzem Memcache i Tarantool per a altres tasques i, mirant endavant, diré que a la nostra pràctica hi havia més problemes amb ells.

Especificitats d'ús

Fem una ullada a quins problemes hem resolt històricament amb Redis i quina funcionalitat hem utilitzat:

  • Memòria cau abans de les sol·licituds a serveis remots com 2GIS | Golang

    GET SET MGET MSET "SELECT DB"

  • Cache abans de MYSQL | PHP

    OBTENIR SET MGET MSET ESCANEAR "CLEU PER PATRÓ" "SELECCIONAR BD"

  • L'emmagatzematge principal per al servei de treball amb sessions i coordenades de conductor | Golang

    OBTENIR SET MGET MSET "SELECT DB" "AFEGIR GEO KEY" "OBTENIR GEO KEY" ESCANEIG

Com podeu veure, no hi ha matemàtiques superiors. Quina és, doncs, la dificultat? Vegem cada mètode per separat.

Mètode
Descripció
Característiques de Redis-cluster
decisió

PREPARA'T
Clau d'escriptura/lectura

MGET MSET
Escriure/llegir diverses claus
Les claus estaran en diferents nodes. Les biblioteques preparades només poden realitzar operacions múltiples dins d'un node
Substituïu MGET per una canalització d'operacions N GET

SELECCIONA DB
Seleccioneu la base amb la qual treballarem
No admet diverses bases de dades
Posa-ho tot en una base de dades. Afegiu prefixos a les claus

SCAN
Passeu per totes les claus de la base de dades
Com que tenim una base de dades, passar per totes les claus del clúster és massa car
Mantingueu un invariant dins d'una clau i feu un HSCAN en aquesta clau. O negar-se completament

GEO
Operacions amb geoclau
La geokey no està fragmentada

CLAU PER PATRÓ
Cercant una clau per patró
Com que tenim una base de dades, cercarem a totes les claus del clúster. Molt car
Rebutja o manté l'invariant, com en el cas d'ESCANY

Redis vs Redis-cluster

Què perdem i què guanyem en canviar a un clúster?

  • Inconvenients: perdem la funcionalitat de diverses bases de dades.
    • Si volem emmagatzemar dades lògicament no relacionades en un clúster, haurem de fer crosses en forma de prefixos.
    • Perdem totes les operacions "bàsiques", com ara SCAN, DBSIZE, CLEAR DB, etc.
    • Les operacions múltiples s'han tornat molt més difícils d'implementar perquè pot requerir accés a diversos nodes.
  • Plomes:
    • Tolerància a errors en forma de failover mestre.
    • Sharding al costat de Redis.
    • Transfereix dades entre nodes de manera atòmica i sense temps d'inactivitat.
    • Afegiu i redistribuïu la capacitat i les càrregues sense temps d'inactivitat.

Conclou que si no cal que proporcioneu un alt nivell de tolerància a errors, passar a un clúster no val la pena, perquè pot ser una tasca no trivial. Però si inicialment trieu entre una versió separada i una versió de clúster, haureu de triar un clúster, ja que no és pitjor i, a més, us alleujarà alguns dels mals de cap.

Preparant-se per moure's

Comencem amb els requisits per moure's:

  • Hauria de ser perfecta. Una parada completa del servei durant 5 minuts no ens convé.
  • Ha de ser el més segur i gradual possible. Vull tenir un cert control sobre la situació. No volem llençar-ho tot alhora i resar pel botó de retrocés.
  • Pèrdua de dades mínima en moure's. Entenem que serà molt difícil moure's atòmicament, així que permetem una certa desincronització entre les dades en Redis regulars i agrupats.

Manteniment del clúster

Just abans de moure'ns, hauríem de pensar si podem donar suport al clúster:

  • Gràfiques. Utilitzem Prometheus i Grafana per representar gràficament la càrrega de la CPU, l'ús de memòria, el nombre de clients, el nombre d'operacions GET, SET, AUTH, etc.
  • Perícia. Imagina que demà tindreu un enorme clúster sota la vostra responsabilitat. Si es trenca, ningú més que tu el podràs arreglar. Si comença a frenar, tothom correrà cap a tu. Si necessiteu afegir recursos o redistribuir la càrrega, torneu-vos-hi. Per no posar-se gris als 25, convé preveure aquests casos i comprovar amb antelació com es comportarà la tecnologia sota determinades accions. Parlem d'això amb més detall a la secció "Experiència".
  • Seguiment i alertes. Quan un clúster es trenca, voleu ser el primer a saber-ne. Aquí ens hem limitat a una notificació que tots els nodes retornen la mateixa informació sobre l'estat del clúster (sí, passa de manera diferent). I altres problemes es poden detectar més ràpidament mitjançant les alertes dels serveis al client de Redis.

Moure

Com ens mourem:

  • En primer lloc, heu de preparar una biblioteca per treballar amb el clúster. Vam prendre go-redis com a base per a la versió Go i l'hem canviat una mica per adaptar-nos a nosaltres mateixos. Hem implementat mètodes múltiples mitjançant canalitzacions i també hem corregit lleugerament les regles per repetir les sol·licituds. La versió PHP va tenir més problemes, però finalment ens vam establir amb php-redis. Recentment van introduir el suport de clúster i al nostre parer sembla bé.
  • A continuació, heu de desplegar el propi clúster. Això es fa literalment en dues ordres basades en el fitxer de configuració. A continuació parlarem de la configuració amb més detall.
  • Per al moviment gradual, utilitzem el mode sec. Com que tenim dues versions de la biblioteca amb la mateixa interfície (una per a la versió normal, l'altra per al clúster), no costa gens crear un embolcall que funcioni amb una versió separada i en paral·lel duplicar totes les peticions al clúster, compareu les respostes i escriviu discrepàncies als registres (en el nostre cas a NewRelic). Així, fins i tot si la versió del clúster es trenca durant el llançament, la nostra producció no es veurà afectada.
  • Després d'haver desplegat el clúster en mode sec, podem mirar tranquil·lament el gràfic de discrepàncies de resposta. Si la proporció d'errors es mou lentament però segurament cap a una petita constant, aleshores tot està bé. Per què encara hi ha discrepàncies? Com que l'enregistrament en una versió independent es produeix una mica abans que al clúster, i a causa del microlag, les dades poden divergir. Només queda mirar els registres de discrepàncies, i si tots s'expliquen per la no-atomicitat del registre, podem seguir endavant.
  • Ara podeu canviar el mode sec en la direcció oposada. Escriurem i llegirem del clúster i el duplicarem en una versió independent. Per a què? Durant la propera setmana m'agradaria observar el treball del clúster. Si de sobte resulta que hi ha problemes a la càrrega màxima, o no hem tingut en compte alguna cosa, sempre tenim una reposició d'emergència al codi antic i a les dades actuals gràcies al mode sec.
  • Només queda desactivar el mode sec i desmuntar la versió separada.

Expertesa

Primer, breument sobre el disseny del clúster.

En primer lloc, Redis és una botiga de valor-clau. Les cadenes arbitràries s'utilitzen com a claus. Els números, les cadenes i les estructures senceres es poden utilitzar com a valors. N'hi ha molts d'aquests últims, però per entendre l'estructura general això no és important per a nosaltres.
El següent nivell d'abstracció després de les claus són les ranures (SLOTS). Cada clau pertany a una de les 16 ranures. Hi pot haver qualsevol nombre de claus dins de cada ranura. Així, totes les claus es divideixen en 383 conjunts disjunts.
Sobre el trasllat de Redis a Redis-cluster

A continuació, hi ha d'haver N nodes mestres al clúster. Cada node es pot pensar com una instància de Redis independent que ho sap tot sobre altres nodes dins del clúster. Cada node mestre conté una sèrie de ranures. Cada ranura només pertany a un node mestre. Totes les ranures s'han de distribuir entre nodes. Si algunes ranures no estan assignades, les claus emmagatzemades en elles seran inaccessibles. Té sentit executar cada node mestre en una màquina lògica o física independent. També val la pena recordar que cada node només s'executa en un nucli i, si voleu executar diverses instàncies de Redis a la mateixa màquina lògica, assegureu-vos que s'executen en nuclis diferents (no ho hem provat, però en teoria hauria de funcionar) . Essencialment, els nodes mestres proporcionen fragments regulars i més nodes mestres permeten que les sol·licituds d'escriptura i lectura s'escallin.

Després de distribuir totes les claus entre les ranures i les ranures escampades entre els nodes mestres, es pot afegir un nombre arbitrari de nodes esclaus a cada node mestre. Dins de cada enllaç mestre-esclau, funcionarà la replicació normal. Es necessiten esclaus per escalar les sol·licituds de lectura i per a la migració per error en cas d'error mestre.
Sobre el trasllat de Redis a Redis-cluster

Ara parlem d'operacions que seria millor poder fer.

Accedim al sistema mitjançant Redis-CLI. Com que Redis no té un únic punt d'entrada, podeu realitzar les operacions següents en qualsevol dels nodes. En cada punt crido l'atenció per separat sobre la possibilitat de realitzar l'operació sota càrrega.

  • El primer i més important que necessitem és el funcionament dels nodes del clúster. Retorna l'estat del clúster, mostra una llista de nodes, els seus rols, distribució de ranures, etc. Es pot obtenir més informació mitjançant la informació del clúster i les ranures del clúster.
  • Seria bo poder afegir i eliminar nodes. Amb aquest propòsit, hi ha operacions de reunió i oblit de clúster. Tingueu en compte que l'oblit del clúster s'ha d'aplicar a CADA node, tant els mestres com les rèpliques. I la reunió de clúster només s'ha de cridar en un node. Aquesta diferència pot ser desconcertant, per la qual cosa és millor conèixer-la abans de posar-se en marxa amb el vostre clúster. L'addició d'un node es fa de manera segura a la batalla i no afecta de cap manera el funcionament del clúster (que és lògic). Si voleu eliminar un node del clúster, heu d'assegurar-vos que no hi queden ranures (en cas contrari, correu el risc de perdre l'accés a totes les claus d'aquest node). A més, no suprimiu un mestre que tingui esclaus, en cas contrari es realitzarà un vot innecessari per a un nou mestre. Si els nodes ja no tenen ranures, aquest és un petit problema, però per què necessitem opcions addicionals si primer podem eliminar els esclaus.
  • Si necessiteu intercanviar força les posicions mestre i esclau, l'ordre de failover del clúster servirà. En cridar-lo a la batalla, heu d'entendre que el mestre no estarà disponible durant l'operació. Normalment, el canvi es produeix en menys d'un segon, però no és atòmic. Podeu esperar que algunes sol·licituds al mestre fallaran durant aquest temps.
  • Abans d'eliminar un node del clúster, no hi hauria de quedar cap ranura. És millor redistribuir-los mitjançant l'ordre cluster reshard. Les ranures es transferiran d'un màster a un altre. Tota l'operació pot trigar uns quants minuts, depèn del volum de dades que es transfereixen, però el procés de transferència és segur i no afecta de cap manera el funcionament del clúster. Així, totes les dades es poden transferir d'un node a un altre directament sota càrrega, i sense preocupar-se per la seva disponibilitat. Tanmateix, també hi ha subtileses. En primer lloc, la transferència de dades s'associa amb una certa càrrega en els nodes receptor i remitent. Si el node receptor ja està molt carregat al processador, no hauríeu de carregar-lo amb la recepció de dades noves. En segon lloc, tan bon punt no quedi ni una ranura al mestre que envia, tots els seus esclaus aniran immediatament al mestre al qual s'han transferit aquestes ranures. I el problema és que tots aquests esclaus voldran sincronitzar dades alhora. I tindreu sort si és una sincronització parcial en lloc de completa. Tingueu-ho en compte i combineu les operacions de transferència de ranures i desactivació/transferència d'esclaus. O esperem que tingueu un marge de seguretat suficient.
  • Què heu de fer si, durant el trasllat, trobeu que heu perdut les vostres places en algun lloc? Espero que aquest problema no us afecti, però si ho fa, hi ha una operació de reparació del clúster. Com a mínim, dispersarà les ranures pels nodes en un ordre aleatori. Recomano que comproveu el seu funcionament eliminant primer el node amb ranures distribuïdes del clúster. Com que les dades de les ranures no assignades ja no estan disponibles, és massa tard per preocupar-se pels problemes amb la disponibilitat d'aquestes ranures. Al seu torn, l'operació no afectarà les ranures distribuïdes.
  • Una altra operació útil és el monitor. Permet veure en temps real tota la llista de peticions que van al node. A més, podeu fer-ho i esbrinar si hi ha el trànsit necessari.

També val la pena esmentar el procediment de failover mestre. En resum, existeix i, al meu entendre, funciona molt bé. Tanmateix, no us penseu que si desconnecteu el cable d'alimentació d'una màquina amb un node mestre, Redis canviarà immediatament i els clients no notaran la pèrdua. A la meva pràctica, el canvi es produeix en pocs segons. Durant aquest temps, algunes de les dades no estaran disponibles: es detecta la indisponibilitat del mestre, els nodes voten per un de nou, es canvien els esclaus, les dades es sincronitzen. La millor manera d'assegurar-vos que l'esquema funciona és fer exercicis locals. Augmenteu el clúster del vostre ordinador portàtil, doneu-li una càrrega mínima, simuleu un accident (per exemple, bloquejant els ports) i avalueu la velocitat de commutació. Al meu entendre, només després de jugar d'aquesta manera durant un dia o dos pots tenir confiança en el funcionament de la tecnologia. Bé, o esperem que el programari que fa servir la meitat d'Internet probablement funcioni.

Configuració

Sovint, la configuració és el primer que necessites per començar a treballar amb l'eina i, quan tot funciona, ni tan sols vols tocar la configuració. Cal un esforç forçar-se a tornar a la configuració i revisar-les amb cura. A la meva memòria, hem tingut almenys dos errors greus per falta d'atenció a la configuració. Presteu especial atenció als punts següents:

  • temps d'espera 0
    Temps després del qual es tanquen les connexions inactives (en segons). 0 - no tanquis
    No totes les biblioteques nostres van poder tancar les connexions correctament. En desactivar aquesta configuració, correm el risc d'arribar al límit de nombre de clients. D'altra banda, si hi ha aquest problema, la terminació automàtica de les connexions perdudes ho emmascarà i és possible que no ho notem. A més, no hauríeu d'activar aquesta configuració quan feu servir connexions persistents.
  • Desa xy i només sí
    Desant una instantània RDB.
    A continuació parlarem de problemes RDB/AOF amb detall.
  • stop-writes-on-bgsave-error no i slave-serve-stale-data sí
    Si està activat, si la instantània RDB es trenca, el mestre deixarà d'acceptar sol·licituds de canvi. Si es perd la connexió amb el mestre, l'esclau pot continuar responent a les peticions (sí). O deixarà de respondre (no)
    No estem contents amb la situació en què Redis es converteix en una carbassa.
  • repl-ping-esclau-període 5
    Passat aquest període de temps, començarem a preocupar-nos que el mestre s'hagi avariat i és el moment de dur a terme el procediment de failover.
    Haureu de trobar manualment un equilibri entre falsos positius i activar una migració per error. A la nostra pràctica això són 5 segons.
  • repl-backlog-size 1024mb i epl-backlog-ttl 0
    Podem emmagatzemar exactament aquesta quantitat de dades en una memòria intermèdia per a una rèplica fallida. Si s'esgota la memòria intermèdia, haureu de sincronitzar completament.
    La pràctica suggereix que és millor establir un valor més alt. Hi ha moltes raons per les quals una rèplica pot començar a retardar-se. Si es retarda, és molt probable que el vostre mestre ja estigui lluitant per fer front i la sincronització completa serà l'última gota.
  • màxim clients 10000
    Nombre màxim de clients puntuals.
    Segons la nostra experiència, és millor establir un valor més alt. Redis gestiona 10k connexions perfectament. Només assegureu-vos que hi hagi prou endolls al sistema.
  • maxmemory-policy volatile-ttl
    La regla per la qual s'eliminen les claus quan s'arriba al límit de memòria disponible.
    El que és important aquí no és la regla en si, sinó la comprensió de com passarà això. Redis es pot elogiar per la seva capacitat de funcionar amb normalitat quan s'arriba al límit de memòria.

Problemes RDB i AOF

Encara que el mateix Redis emmagatzema tota la informació a la memòria RAM, també hi ha un mecanisme per desar dades al disc. Més precisament, tres mecanismes:

  • RDB-snapshot: una instantània completa de totes les dades. Establiu amb la configuració SAVE XY i diu "Desa una instantània completa de totes les dades cada X segons si almenys han canviat les tecles Y".
  • Fitxer només per afegir: una llista d'operacions en l'ordre en què es realitzen. Afegeix noves operacions entrants al fitxer cada X segons o cada Y operacions.
  • RDB i AOF són una combinació dels dos anteriors.

Tots els mètodes tenen els seus avantatges i inconvenients, no els enumeraré tots, només cridaré l'atenció sobre punts que, al meu entendre, no són evidents.

En primer lloc, per desar una instantània RDB cal trucar a FORK. Si hi ha moltes dades, això pot penjar tot Redis durant un període d'uns quants mil·lisegons a un segon. A més, el sistema ha d'assignar memòria per a aquesta instantània, la qual cosa comporta la necessitat de mantenir un doble subministrament de RAM a la màquina lògica: si s'assignen 8 GB per a Redis, haurien d'estar disponibles 16 GB a la màquina virtual amb això.

En segon lloc, hi ha problemes amb la sincronització parcial. En el mode AOF, quan es torna a connectar l'esclau, en lloc de la sincronització parcial, es pot realitzar una sincronització completa. Per què passa això, no ho podia entendre. Però val la pena recordar-ho.

Aquests dos punts ja ens fan pensar si realment necessitem aquestes dades al disc si ja tot està duplicat per esclaus. Les dades només es poden perdre si tots els esclaus fallen, i es tracta d'un problema de nivell "incendi a la CC". Com a compromís, podeu proposar desar dades només als esclaus, però en aquest cas heu d'assegurar-vos que aquests esclaus mai es convertiran en mestres durant la recuperació de desastres (per això hi ha una configuració de prioritat d'esclaus a la seva configuració). Per a nosaltres mateixos, en cada cas concret pensem si és necessari desar dades al disc, i la majoria de vegades la resposta és "no".

Conclusió

En conclusió, espero haver pogut donar una idea general de com funciona redis-cluster per a aquells que no n'han sentit a parlar gens, i també haver cridat l'atenció sobre alguns punts no evidents per a aquells que l'han estat utilitzant. durant molt de temps.
Gràcies pel vostre temps i, com sempre, els comentaris sobre el tema són benvinguts.

Font: www.habr.com

Afegeix comentari