Sobre o traslado de Redis a Redis-cluster

Sobre o traslado de Redis a Redis-cluster

Chegando a un produto que leva máis dunha década desenvolvendo, non é de estrañar que se atope nel con tecnoloxías obsoletas. Pero e se en seis meses tes que manter a carga 10 veces maior e o custo das caídas aumentará centos de veces? Neste caso, necesitas un enxeñeiro de alta carga xenial. Pero ante a ausencia dunha criada, encomendáronme a solución do problema. Na primeira parte do artigo contarei como pasamos de Redis a Redis-cluster, e na segunda parte darei consellos sobre como comezar a usar o clúster e a que prestar atención á hora de utilizalo.

Selección de tecnoloxía

É tan malo? separar Redis (redis autónomo) nunha configuración de 1 mestre e N escravos? Por que lle chamo tecnoloxía obsoleta?

Non, Redis non está tan mal... Porén, hai algunhas carencias que non se poden ignorar.

  • En primeiro lugar, Redis non admite mecanismos de recuperación ante desastres despois dun fallo principal. Para solucionar este problema, utilizamos unha configuración con transferencia automática de VIP a un novo mestre, cambiando o papel dun dos escravos e cambiando o resto. Este mecanismo funcionou, pero non se podía chamar unha solución fiable. En primeiro lugar, producíronse falsas alarmas e, en segundo lugar, era desbotable, e despois da operación foron necesarias accións manuais para cargar o resorte.

  • En segundo lugar, ter só un mestre levou ao problema da fragmentación. Tivemos que crear varios clústeres independentes "1 mestre e N escravos", despois distribuír manualmente as bases de datos entre estas máquinas e esperar que mañá unha das bases de datos non se inchara tanto como para ter que trasladala a unha instancia separada.

Cales son as opcións?

  • A solución máis cara e rica é Redis-Enterprise. Esta é unha solución en caixa con soporte técnico completo. A pesar de que desde o punto de vista técnico parece ideal, non nos conveña por razóns ideolóxicas.
  • Redis-cluster. Fóra da caixa hai soporte para a conmutación por fallo principal e a fragmentación. A interface case non é diferente da versión normal. Parece prometedor, falaremos das trampas máis adiante.
  • Tarantool, Memcache, Aerospike e outros. Todas estas ferramentas fan practicamente o mesmo. Pero cada un ten as súas propias deficiencias. Decidimos non poñer todos os nosos ovos nunha mesma cesta. Usamos Memcache e Tarantool para outras tarefas e, mirando cara adiante, direi que na nosa práctica houbo máis problemas con eles.

Especificidades de uso

Vexamos que problemas resolvemos historicamente con Redis e que funcionalidades utilizamos:

  • Caché antes de solicitudes a servizos remotos como 2GIS | Golang

    GET SET MGET MSET "SELECT DB"

  • Caché antes de MYSQL | PHP

    GET SET MGET MSET SCAN "TECLA POR PATRÓN" "SELECCIONAR DB"

  • O almacenamento principal para o servizo de traballo con sesións e coordenadas de condutor | Golang

    OBTENIR SET MGET MSET "SELECT DB" "ADD GEO KEY" "OBTER GEO KEY" ESCANEO

Como podes ver, non hai matemáticas superiores. Cal é entón a dificultade? Vexamos cada método por separado.

Método
Descrición
Características de Redis-cluster
decisión

CONXUNTE
Tecla de escritura/lectura

MGET MSET
Escribir/ler varias claves
As claves estarán en diferentes nodos. As bibliotecas preparadas só poden realizar varias operacións nun nodo
Substitúe MGET por unha canalización de N operacións GET

SELECCIONAR DB
Selecciona a base coa que traballaremos
Non admite varias bases de datos
Pon todo nunha base de datos. Engadir prefixos ás claves

SCAN
Pasa por todas as claves da base de datos
Xa que temos unha base de datos, pasar por todas as claves do clúster é demasiado caro
Mantén un invariante dentro dunha chave e fai un HSCAN nesta chave. Ou rexeitar completamente

GEO
Operacións cunha xeokey
O xeokey non está fragmentado

CLAVE POR PATRÓN
Buscando unha clave por patrón
Xa que temos unha base de datos, buscaremos en todas as claves do clúster. Caro de máis
Rexeitar ou manter o invariante, como no caso de SCAN

Redis vs Redis-cluster

Que perdemos e que gañamos ao cambiar a un clúster?

  • Desvantaxes: perdemos a funcionalidade de varias bases de datos.
    • Se queremos almacenar datos loxicamente non relacionados nun clúster, teremos que facer muletas en forma de prefixos.
    • Perdemos todas as operacións "base", como SCAN, DBSIZE, CLEAR DB, etc.
    • As operacións múltiples volvéronse moito máis difíciles de implementar porque poden requirir acceso a varios nodos.
  • Pluses:
    • Tolerancia a fallos en forma de failover mestre.
    • Sharding no lado de Redis.
    • Transfire datos entre nodos de forma atómica e sen tempo de inactividade.
    • Engade e redistribuír capacidade e cargas sen tempo de inactividade.

Concluiría que se non precisa proporcionar un alto nivel de tolerancia a fallos, pasar a un clúster non paga a pena, porque pode ser unha tarefa non trivial. Pero se inicialmente elixes entre unha versión separada e unha versión de clúster, entón deberías escoller un clúster, xa que non é peor e, ademais, aliviarache algúns dos dores de cabeza.

Preparándose para moverse

Comecemos cos requisitos para movernos:

  • Debe ser transparente. Non nos convén unha parada completa do servizo durante 5 minutos.
  • Debe ser o máis seguro e gradual posible. Quero ter algún control sobre a situación. Non queremos botar todo á vez e rezar polo botón de retroceso.
  • Mínima perda de datos ao moverse. Entendemos que será moi difícil moverse atómicamente, polo que permitimos certa desincronización entre os datos en Redis regular e agrupado.

Mantemento do clúster

Xusto antes do traslado, debemos pensar se podemos apoiar o clúster:

  • Gráficos. Usamos Prometheus e Grafana para graficar a carga da CPU, o uso da memoria, o número de clientes, o número de operacións GET, SET, AUTH, etc.
  • Pericia. Imaxina que mañá terás un enorme clúster baixo a túa responsabilidade. Se rompe, ninguén máis que ti podes arranxalo. Se comeza a diminuír a velocidade, todos correrán cara a ti. Se precisas engadir recursos ou redistribuír a carga, volve contigo. Para non quedar gris aos 25 anos, convén prever estes casos e comprobar previamente como se comportará a tecnoloxía baixo determinadas accións. Falemos sobre isto con máis detalle na sección "Experiencia".
  • Seguimento e alertas. Cando un clúster se rompe, queres ser o primeiro en enterarse del. Aquí limitámonos a unha notificación de que todos os nodos devolven a mesma información sobre o estado do clúster (si, ocorre de forma diferente). E outros problemas pódense notar máis rapidamente mediante as alertas dos servizos de clientes de Redis.

Reubicación

Como nos moveremos:

  • En primeiro lugar, cómpre preparar unha biblioteca para traballar co clúster. Tomamos go-redis como base para a versión de Go e cambiamos un pouco para adaptarnos a nós mesmos. Implementamos métodos múltiples mediante canalizacións e tamén corriximos lixeiramente as regras para repetir solicitudes. A versión de PHP tivo máis problemas, pero finalmente decidimos por php-redis. Recentemente introduciron o soporte de clúster e parece ben na nosa opinión.
  • A continuación, cómpre implementar o propio clúster. Isto faise literalmente en dous comandos baseados no ficheiro de configuración. A continuación comentaremos a configuración con máis detalle.
  • Para o movemento gradual usamos o modo seco. Dado que temos dúas versións da biblioteca coa mesma interface (unha para a versión normal, a outra para o clúster), non custa nada crear un wrapper que funcione cunha versión separada e en paralelo duplicar todas as solicitudes ao clúster. compara as respostas e escribe discrepancias nos rexistros (no noso caso en NewRelic). Así, aínda que a versión do clúster se rompa durante o lanzamento, a nosa produción non se verá afectada.
  • Despois de lanzar o clúster en modo seco, podemos mirar tranquilamente o gráfico de discrepancias de resposta. Se a taxa de erro se move lentamente pero con certeza cara a algunha pequena constante, entón todo está ben. Por que aínda hai discrepancias? Dado que a gravación nunha versión separada ocorre un pouco antes que no clúster, e debido ao microlag, os datos poden diverxer. Só queda mirar os rexistros de discrepancias, e se todos se explican pola non atomicidade do rexistro, podemos seguir adiante.
  • Agora podes cambiar o modo seco na dirección oposta. Escribiremos e leremos desde o clúster, e duplicarémolo nunha versión separada. Para qué? Durante a próxima semana gustaríame observar o traballo do clúster. Se de súpeto resulta que hai problemas na carga máxima, ou non tivemos en conta algo, sempre temos unha reversión de emerxencia ao código antigo e aos datos actuais grazas ao modo seco.
  • Todo o que queda é desactivar o modo seco e desmontar a versión separada.

Pericia

En primeiro lugar, brevemente sobre o deseño do clúster.

En primeiro lugar, Redis é unha tenda de clave-valor. As cadeas arbitrarias utilízanse como claves. Pódense usar números, cadeas e estruturas enteiras como valores. Hai moitos destes últimos, pero para comprender a estrutura xeral isto non é importante para nós.
O seguinte nivel de abstracción despois das claves son os slots (SLOTS). Cada chave pertence a un dos 16 slots. Pode haber calquera número de chaves dentro de cada slot. Así, todas as claves están divididas en 383 conxuntos disxuntos.
Sobre o traslado de Redis a Redis-cluster

A continuación, debe haber N nodos mestres no clúster. Cada nodo pódese pensar como unha instancia de Redis separada que sabe todo sobre outros nodos dentro do clúster. Cada nodo mestre contén un número de slots. Cada slot pertence só a un nodo mestre. Todos os slots deben estar distribuídos entre nós. Se non se asignan algúns slots, as claves almacenadas nelas non serán accesibles. Ten sentido executar cada nodo mestre nunha máquina lóxica ou física separada. Tamén vale a pena lembrar que cada nodo só se executa nun núcleo e, se queres executar varias instancias de Redis na mesma máquina lóxica, asegúrate de que funcionen en núcleos diferentes (non o probamos, pero en teoría debería funcionar) . Esencialmente, os nodos mestres proporcionan fragmentos regulares e máis nodos mestres permiten escalar solicitudes de lectura e escritura.

Despois de que todas as claves estean distribuídas entre os slots e os slots estén espallados entre os nodos mestres, pódese engadir un número arbitrario de nodos escravos a cada nodo mestre. Dentro de cada enlace mestre-escravo, funcionará a replicación normal. Os escravos son necesarios para escalar as solicitudes de lectura e para a conmutación por fallo en caso de falla principal.
Sobre o traslado de Redis a Redis-cluster

Agora imos falar de operacións que sería mellor poder facer.

Accederemos ao sistema a través de Redis-CLI. Dado que Redis non ten un único punto de entrada, pode realizar as seguintes operacións en calquera dos nodos. En cada punto chamo por separado a atención sobre a posibilidade de realizar a operación baixo carga.

  • O primeiro e máis importante que necesitamos é o funcionamento dos nodos do clúster. Devolve o estado do clúster, mostra unha lista de nodos, as súas funcións, distribución de slots, etc. Pódese obter máis información usando a información do clúster e os slots do clúster.
  • Sería bo poder engadir e eliminar nós. Para este fin existen operacións de reunión de cluster e esquecemento de cluster. Ten en conta que o esquecemento do clúster debe aplicarse a TODOS os nodos, tanto mestres como réplicas. E a reunión do clúster só precisa ser chamada nun nodo. Esta diferenza pode ser desconcertante, polo que o mellor é que infórmese sobre ela antes de entrar en funcionamento co seu clúster. Engadir un nodo faise de forma segura na batalla e non afecta de ningún xeito ao funcionamento do clúster (o que é lóxico). Se vas eliminar un nodo do clúster, debes asegurarte de que non queden ranuras nel (se non corres o risco de perder o acceso a todas as claves deste nodo). Ademais, non elimine un mestre que teña escravos, se non, realizarase un voto innecesario para un novo mestre. Se os nodos xa non teñen slots, entón este é un pequeno problema, pero por que necesitamos opcións adicionais se primeiro podemos eliminar os escravos.
  • Se precisa intercambiar forzadamente as posicións mestre e escravo, o comando de conmutación por falla do clúster funcionará. Ao chamalo na batalla, debes entender que o mestre non estará dispoñible durante a operación. Normalmente o cambio ocorre en menos dun segundo, pero non é atómico. Podes esperar que algunhas solicitudes ao mestre fallan durante este tempo.
  • Antes de eliminar un nodo do clúster, non debería quedar ningún slot. É mellor redistribuílos usando o comando cluster reshard. Os slots transferiranse dun mestre a outro. Toda a operación pode levar varios minutos, depende do volume de datos que se transfiran, pero o proceso de transferencia é seguro e non afecta de ningún xeito o funcionamento do clúster. Así, todos os datos pódense transferir dun nodo a outro directamente baixo carga e sen preocuparse pola súa dispoñibilidade. Non obstante, tamén hai sutilezas. En primeiro lugar, a transferencia de datos está asociada a unha determinada carga nos nodos receptor e remitente. Se o nodo receptor xa está moi cargado no procesador, non debería cargalo coa recepción de novos datos. En segundo lugar, en canto non quede nin un só slot no mestre emisor, todos os seus escravos irán inmediatamente ao mestre ao que se transferiron estes slots. E o problema é que todos estes escravos quererán sincronizar os datos á vez. E terás sorte se é unha sincronización parcial e non completa. Teña isto en conta e combine as operacións de transferencia de slots e desactivación/transferencia de escravos. Ou espero que teña unha marxe de seguridade suficiente.
  • Que debes facer se, durante a transferencia, atopas que perdeches as túas prazas nalgún lugar? Espero que este problema non che afecte, pero se o fai, hai unha operación de corrección do clúster. Polo menos, espallará as ranuras polos nodos nunha orde aleatoria. Recomendo comprobar o seu funcionamento eliminando primeiro o nodo con ranuras distribuídas do clúster. Dado que os datos dos espazos non asignados xa non están dispoñibles, é demasiado tarde para preocuparse polos problemas coa dispoñibilidade destes espazos. Pola súa banda, a operación non afectará aos slots distribuídos.
  • Outra operación útil é o monitor. Permite ver en tempo real a lista completa de solicitudes que van ao nodo. Ademais, pode grep-lo e descubrir se hai o tráfico necesario.

Tamén paga a pena mencionar o procedemento de conmutación por fallo mestre. En resumo, existe e, na miña opinión, funciona moi ben. Non obstante, non penses que se desconectas o cable de alimentación nunha máquina cun nodo mestre, Redis cambiará inmediatamente e os clientes non notarán a perda. Na miña práctica, o cambio ocorre nuns segundos. Durante este tempo, algúns dos datos non estarán dispoñibles: detéctase a non dispoñibilidade do mestre, os nodos votan por un novo, os escravos cámbianse e os datos sincronízanse. A mellor forma de asegurarse de que o esquema funciona é realizar exercicios locais. Levanta o clúster do teu portátil, dálle unha carga mínima, simula un fallo (por exemplo, bloqueando os portos) e avalía a velocidade de conmutación. Na miña opinión, só despois de xogar deste xeito durante un ou dous días podes ter confianza no funcionamento da tecnoloxía. Ben, ou espero que o software que usa a metade de Internet probablemente funcione.

Configuración

Moitas veces, a configuración é o primeiro que necesitas para comezar a traballar coa ferramenta e, cando todo funciona, nin sequera queres tocar a configuración. Fai un esforzo para obrigarte a volver á configuración e revisalas con coidado. Na miña memoria, tivemos polo menos dous fallos graves debido á falta de atención á configuración. Preste especial atención aos seguintes puntos:

  • tempo de espera 0
    Tempo despois do cal se pechan as conexións inactivas (en segundos). 0 - non pechar
    Non todas as nosas bibliotecas foron capaces de pechar as conexións correctamente. Ao desactivar esta configuración, corremos o risco de alcanzar o límite no número de clientes. Por outra banda, se hai tal problema, entón a terminación automática das conexións perdidas enmascaralo, e é posible que non nos decatemos. Ademais, non debería activar esta configuración cando use conexións persistentes.
  • Gardar xy e apéndice só si
    Gardando unha instantánea RDB.
    A continuación discutiremos os problemas RDB/AOF en detalle.
  • stop-writes-on-bgsave-error non e slave-serve-stale-data si
    Se está activado, se a instantánea RDB rompe, o mestre deixará de aceptar solicitudes de cambio. Se se perde a conexión co mestre, o escravo pode seguir respondendo ás solicitudes (si). Ou deixará de responder (non)
    Non estamos contentos coa situación na que Redis se converte nunha cabaza.
  • repl-ping-slave-período 5
    Pasado este período de tempo, comezaremos a preocuparnos de que o master se avare e sexa o momento de realizar o procedemento de failover.
    Terás que atopar manualmente un equilibrio entre falsos positivos e activar unha conmutación por fallo. Na nosa práctica son 5 segundos.
  • repl-backlog-size 1024mb e epl-backlog-ttl 0
    Podemos almacenar exactamente esta cantidade de datos nun búfer para unha réplica fallida. Se o búfer se esgota, terás que sincronizalo completamente.
    A práctica suxire que é mellor establecer un valor máis alto. Hai moitas razóns polas que unha réplica pode comezar a retrasarse. Se está atrasado, o máis probable é que o teu mestre xa teña dificultades para facerlle fronte, e a sincronización total será a última gota.
  • clientes máximos 10000
    Número máximo de clientes únicos.
    Na nosa experiencia, é mellor establecer un valor máis alto. Redis manexa ben 10k conexións. Só asegúrese de que haxa sockets suficientes no sistema.
  • maxmemory-policy volatile-ttl
    A regra pola que se eliminan as claves cando se alcanza o límite de memoria dispoñible.
    O importante aquí non é a regra en si, senón a comprensión de como vai ocorrer isto. Redis pódese eloxiar pola súa capacidade de funcionar normalmente cando se alcanza o límite de memoria.

Problemas RDB e AOF

Aínda que o propio Redis almacena toda a información na memoria RAM, tamén existe un mecanismo para gardar datos no disco. Máis precisamente, tres mecanismos:

  • RDB-snapshot: unha instantánea completa de todos os datos. Establécese usando a configuración SAVE XY e di "Gardar unha instantánea completa de todos os datos cada X segundos se polo menos as teclas Y cambiaron".
  • Ficheiro de só engadir: unha lista de operacións na orde en que se realizan. Engade novas operacións de entrada ao ficheiro cada X segundos ou cada Y operacións.
  • RDB e AOF son unha combinación dos dous anteriores.

Todos os métodos teñen as súas vantaxes e desvantaxes, non os enumerarei todos, só chamarei a atención sobre puntos que, na miña opinión, non son obvios.

En primeiro lugar, para gardar unha instantánea de RDB é necesario chamar a FORK. Se hai moitos datos, isto pode colgar todo Redis durante un período de varios milisegundos a un segundo. Ademais, o sistema necesita asignar memoria para tal instantánea, o que leva á necesidade de manter unha dobre subministración de RAM na máquina lóxica: se se asignan 8 GB para Redis, entón deberían estar dispoñibles 16 GB na máquina virtual con iso.

En segundo lugar, hai problemas coa sincronización parcial. No modo AOF, cando se volve conectar o escravo, en lugar da sincronización parcial, pódese realizar a sincronización total. Por que pasa isto, non podía entender. Pero paga a pena lembralo.

Estes dous puntos xa nos fan pensar se realmente necesitamos estes datos no disco se xa todo está duplicado por escravos. Os datos só se poden perder se todos os escravos fallan, e este é un problema de nivel de "incendio no DC". Como compromiso, pode propoñer gardar datos só nos escravos, pero neste caso cómpre asegurarse de que estes escravos nunca se converterán nun mestre durante a recuperación ante desastres (para iso hai unha configuración de prioridade de escravos na súa configuración). Por nós mesmos, en cada caso específico pensamos se é necesario gardar os datos no disco, e a maioría das veces a resposta é "non".

Conclusión

En conclusión, espero que puiden dar unha idea xeral de como funciona redis-cluster para aqueles que non o escoitaron nada, e tamén chamar a atención sobre algúns puntos non obvios para os que o estiveron usando. por moito tempo.
Grazas polo teu tempo e, coma sempre, os comentarios sobre o tema son benvidos.

Fonte: www.habr.com

Engadir un comentario