{"id":91846,"date":"2020-08-19T19:41:57","date_gmt":"2020-08-19T17:41:57","guid":{"rendered":"https:\/\/prohoster.info\/blog\/administrirovanie\/o-pereezde-s-redis-na-redis-cluster"},"modified":"2020-08-19T19:41:57","modified_gmt":"2020-08-19T17:41:57","slug":"o-pereezde-s-redis-na-redis-cluster","status":"publish","type":"post","link":"https:\/\/prohoster.info\/pt\/blog\/administrirovanie\/o-pereezde-s-redis-na-redis-cluster","title":{"rendered":"Sobre a migra\u00e7\u00e3o de Redis para Redis-cluster","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Sobre a migra\u00e7\u00e3o de Redis para Redis-cluster\" src=\"\/wp-content\/uploads\/2020\/08\/ea8bc47f73ef3b06ccfdf94d323592bf.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Ao entrar em um produto que est\u00e1 em desenvolvimento h\u00e1 mais de uma d\u00e9cada, n\u00e3o \u00e9 surpreendente encontrar tecnologias desatualizadas. Mas e se, em seis meses, voc\u00ea precisar suportar uma carga dez vezes maior, e o custo das falhas aumentar centenas de vezes? Nesse caso, voc\u00ea precisar\u00e1 de um engenheiro de alta carga qualificado. Por\u00e9m, na falta de tal profissional, a solu\u00e7\u00e3o do problema foi confiada a mim. Na primeira parte do artigo, contarei como migramos de Redis para Redis-cluster, e na segunda parte, darei dicas de como come\u00e7ar a usar o cluster e o que observar na sua opera\u00e7\u00e3o.<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h1 id=\"vybor-tehnologii\">Escolha da tecnologia<\/h1>\n<p><\/p>\n<p>\u00c9 t\u00e3o ruim <em>um Redis separado<\/em> (redis standalone) na configura\u00e7\u00e3o de 1 mestre e N escravos? Por que o considero uma tecnologia desatualizada?<\/p>\n<p><\/p>\n<blockquote><p>N\u00e3o, o Redis n\u00e3o \u00e9 t\u00e3o ruim... No entanto, h\u00e1 algumas falhas que n\u00e3o podem ser ignoradas.<\/p><\/blockquote>\n<p><\/p>\n<ul>\n<li>\n<p>Primeiro, o Redis n\u00e3o suporta mecanismos de recupera\u00e7\u00e3o de falhas ap\u00f3s a queda do mestre. Para resolver esse problema, utilizamos uma configura\u00e7\u00e3o com redirecionamento autom\u00e1tico de VIPs para um novo mestre, trocando o papel de um dos escravos e alternando os demais. Esse mecanismo funcionou, mas n\u00e3o pode ser considerado uma solu\u00e7\u00e3o confi\u00e1vel. Em primeiro lugar, houve disparos falsos, e em segundo lugar, era uma solu\u00e7\u00e3o de uso \u00fanico, e ap\u00f3s a ativa\u00e7\u00e3o eram necess\u00e1rias a\u00e7\u00f5es manuais para reiniciar o sistema.<\/p>\n<p>\n<\/li>\n<li>\n<p>Em segundo lugar, a exist\u00eancia de apenas um mestre levou ao problema de sharding. Era necess\u00e1rio criar v\u00e1rios clusters independentes de '1 mestre e N escravos', depois distribuir manualmente os bancos de dados entre essas m\u00e1quinas e torcer para que amanh\u00e3 um dos bancos n\u00e3o crescesse tanto que fosse necess\u00e1rio mov\u00ea-lo para uma inst\u00e2ncia separada.<\/p>\n<p>\n<\/li>\n<\/ul>\n<p><\/p>\n<p>Quais s\u00e3o as op\u00e7\u00f5es?<\/p>\n<p><\/p>\n<ul>\n<li>A solu\u00e7\u00e3o mais cara e completa \u00e9 o Redis-Enterprise. Esta \u00e9 uma solu\u00e7\u00e3o pronta com suporte t\u00e9cnico completo. Embora pare\u00e7a ideal do ponto de vista t\u00e9cnico, n\u00e3o nos serviu por raz\u00f5es ideol\u00f3gicas. <\/li>\n<li>Redis-cluster. A partir da caixa, h\u00e1 suporte para failover autom\u00e1tico do mestre e sharding. A interface quase n\u00e3o difere da vers\u00e3o comum. Parece promissora; falaremos sobre as armadilhas mais adiante.<\/li>\n<li>Tarantool, Memcache, Aerospike e outros. Todas essas ferramentas fazem aproximadamente a mesma coisa. Mas cada uma tem suas desvantagens. Decidimos n\u00e3o colocar todos os ovos na mesma cesta. Usamos Memcache e Tarantool para outras tarefas e, adiantando, posso dizer que em nossa pr\u00e1tica tivemos mais problemas com eles.<\/li>\n<\/ul>\n<p><\/p>\n<h1 id=\"specifika-ispolzovaniya\">Especificidade de uso<\/h1>\n<p><\/p>\n<p>Vamos dar uma olhada nas tarefas que historicamente resolvemos com Redis e qual funcionalidade utilizamos:<\/p>\n<p><\/p>\n<ul>\n<li>Cache antes de solicita\u00e7\u00f5es a servi\u00e7os remotos, como 2GIS | Golang<br \/>\n<blockquote><p>GET SET MGET MSET \"SELECIONAR DB\"\n<\/p><\/blockquote>\n<\/li>\n<li>Cache antes do MYSQL | PHP<br \/>\n<blockquote><p>GET SET MGET MSET SCAN \"CHAVE POR PADR\u00c3O\" \"SELECIONAR DB\"\n<\/p><\/blockquote>\n<\/li>\n<li>Armazenamento principal para o servi\u00e7o de gerenciamento de sess\u00f5es e coordenadas de motoristas | Golang<br \/>\n<blockquote><p>GET SET MGET MSET \"SELECIONAR DB\" \"ADICIONAR CHAVE GEO\" \"OBTER CHAVE GEO\" SCAN\n<\/p><\/blockquote>\n<\/li>\n<\/ul>\n<p><\/p>\n<p>Como podem ver, n\u00e3o h\u00e1 nada de alta matem\u00e1tica. Ent\u00e3o, qual \u00e9 a dificuldade? Vamos analisar separadamente cada m\u00e9todo.<\/p>\n<p><\/p>\n<p>M\u00e9todo<br \/>\nDescri\u00e7\u00e3o<br \/>\nCaracter\u00edsticas do Redis-cluster<br \/>\nSolu\u00e7\u00e3o<\/p>\n<p>GET SET<br \/>\nGravar\/ler uma chave<\/p>\n<p>MGET MSET<br \/>\nGravar\/ler v\u00e1rias chaves<br \/>\nAs chaves estar\u00e3o em diferentes n\u00f3s. Bibliotecas prontas conseguem realizar opera\u00e7\u00f5es m\u00faltiplas apenas dentro de um \u00fanico n\u00f3.<br \/>\nSubstituir MGET por um pipeline de N opera\u00e7\u00f5es GET<\/p>\n<p>SELECT DB<br \/>\nSelecionar o banco que vamos trabalhar<br \/>\nN\u00e3o suporta m\u00faltiplos bancos de dados<br \/>\nArmazenar tudo em um \u00fanico banco. Adicionar prefixos \u00e0s chaves<\/p>\n<p>SCAN<br \/>\nPercorrer todas as chaves no banco<br \/>\nComo temos um banco, percorrer todas as chaves no cluster \u00e9 muito custoso.<br \/>\nManter o invariante dentro de uma chave e fazer HSCAN nessa chave. Ou abrir m\u00e3o completamente.<\/p>\n<p>GEO<br \/>\nOpera\u00e7\u00f5es com chave geogr\u00e1fica<br \/>\nA chave geogr\u00e1fica n\u00e3o \u00e9 particionada<\/p>\n<p>KEY BY PATTERN<br \/>\nProcurar chave por padr\u00e3o<br \/>\nComo temos um banco, vamos buscar por todas as chaves no cluster. Muito custoso.<br \/>\nAbrir m\u00e3o ou manter o invariante, assim como no caso do SCAN.<\/p>\n<p><\/p>\n<h1 id=\"redis-vs-redis-cluster\">Redis vs Redis-cluster<\/h1>\n<p><\/p>\n<p>O que perdemos e o que ganhamos ao migrar para o cluster?<\/p>\n<p><\/p>\n<ul>\n<li>Desvantagens: perdemos a funcionalidade de v\u00e1rios bancos. \n<ul>\n<li>Se quisermos armazenar dados logicamente n\u00e3o relacionados em um \u00fanico cluster, teremos que criar gambiarras na forma de prefixos. <\/li>\n<li>Perdemos todas as opera\u00e7\u00f5es 'por banco', como SCAN, DBSIZE, CLEAR DB, etc.<\/li>\n<li>Opera\u00e7\u00f5es m\u00faltiplas se tornaram significativamente mais complexas de implementar, pois pode ser necess\u00e1rio acessar v\u00e1rios n\u00f3s.<\/li>\n<\/ul>\n<\/li>\n<li>Vantagens: \n<ul>\n<li>Resili\u00eancia em forma de failover de mestre.<\/li>\n<li>Particionamento no lado do Redis.<\/li>\n<li>Transfer\u00eancia de dados entre n\u00f3s de forma at\u00f4mica e sem downtime.<\/li>\n<li>Adi\u00e7\u00e3o e redistribui\u00e7\u00e3o de recursos e cargas sem downtime.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p><\/p>\n<p><em>Eu diria que se voc\u00ea n\u00e3o precisa garantir um alto n\u00edvel de disponibilidade, a migra\u00e7\u00e3o para um cluster n\u00e3o vale a pena, pois pode ser uma tarefa n\u00e3o trivial. Mas se a escolha inicial for entre uma vers\u00e3o separada e uma vers\u00e3o em cluster, \u00e9 melhor optar pelo cluster, j\u00e1 que ele n\u00e3o \u00e9 inferior em nada e, al\u00e9m disso, aliviar\u00e1 parte da sua dor de cabe\u00e7a.<\/em><\/p>\n<p><\/p>\n<h1 id=\"podgotovka-k-pereezdu\">Prepara\u00e7\u00e3o para a migra\u00e7\u00e3o<\/h1>\n<p><\/p>\n<p>Vamos come\u00e7ar pelos requisitos para a migra\u00e7\u00e3o:<\/p>\n<p><\/p>\n<ul>\n<li>Ela deve ser sem interrup\u00e7\u00f5es. Uma parada total do servi\u00e7o por 5 minutos n\u00e3o \u00e9 aceit\u00e1vel para n\u00f3s.<\/li>\n<li>Deve ser o mais segura e gradual poss\u00edvel. Queremos ter algum controle sobre a situa\u00e7\u00e3o. N\u00e3o desejamos despejar tudo de uma vez e rezar sobre o bot\u00e3o de retorno.<\/li>\n<li>M\u00ednimas perdas de dados durante a migra\u00e7\u00e3o. Entendemos que migrar de forma at\u00f4mica ser\u00e1 muito dif\u00edcil, portanto, aceitamos alguma desincroniza\u00e7\u00e3o entre os dados no Redis normal e no cluster.<\/li>\n<\/ul>\n<p><\/p>\n<h1 id=\"obsluzhivanie-klastera\">Manuten\u00e7\u00e3o do cluster<\/h1>\n<p><\/p>\n<p>Antes da migra\u00e7\u00e3o, devemos considerar se conseguimos manter o cluster:<\/p>\n<p><\/p>\n<ul>\n<li>Gr\u00e1ficos. Usamos Prometheus e Grafana para gr\u00e1ficos de carga dos processadores, mem\u00f3ria ocupada, n\u00famero de clientes, quantidade de opera\u00e7\u00f5es GET, SET, AUTH, etc.<\/li>\n<li>Especializa\u00e7\u00e3o. Imagine que amanh\u00e3 voc\u00ea ser\u00e1 respons\u00e1vel por um enorme cluster. Se ele falhar, ningu\u00e9m al\u00e9m de voc\u00ea poder\u00e1 consert\u00e1-lo. Se come\u00e7ar a travar, todos correr\u00e3o at\u00e9 voc\u00ea. Se precisar adicionar recursos ou redistribuir a carga, ser\u00e1 novamente com voc\u00ea. Para n\u00e3o ficar grisalho aos 25, \u00e9 desej\u00e1vel prever esses casos e testar de antem\u00e3o como a tecnologia se comportar\u00e1 em determinadas a\u00e7\u00f5es. Vamos discutir isso mais detalhadamente na se\u00e7\u00e3o \"Especializa\u00e7\u00e3o\".<\/li>\n<li>Monitoramento e alertas. Quando o cluster falhar, queremos ser os primeiros a saber. Aqui limitamos a notifica\u00e7\u00e3o para quando todos os n\u00f3s retornam as mesmas informa\u00e7\u00f5es sobre o estado do cluster (sim, isso pode ser diferente). E os outros problemas podem ser percebidos mais rapidamente atrav\u00e9s das notifica\u00e7\u00f5es dos servi\u00e7os-clientes do Redis.<\/li>\n<\/ul>\n<p><\/p>\n<h1 id=\"pereezd\">Migra\u00e7\u00e3o<\/h1>\n<p><\/p>\n<p>Como vamos migrar:<\/p>\n<p><\/p>\n<ul>\n<li>Primeiro, \u00e9 preciso preparar a biblioteca para trabalhar com o cluster. Para a vers\u00e3o em G\u043e, utilizamos o go-redis e fizemos algumas altera\u00e7\u00f5es para atender \u00e0s nossas necessidades. Implementamos m\u00e9todos Multi atrav\u00e9s de pipelines e tamb\u00e9m ajustamos as regras de repeti\u00e7\u00e3o de solicita\u00e7\u00f5es. A vers\u00e3o para PHP apresentou mais problemas, mas no final decidimos usar o php-redis. Recentemente, eles introduziram suporte para clusters, e, em nossa opini\u00e3o, isso est\u00e1 bem implementado.<\/li>\n<li>Em seguida, precisamos implantar o pr\u00f3prio cluster. Isso \u00e9 feito literalmente com dois comandos com base em um arquivo de configura\u00e7\u00e3o. Vamos discutir a configura\u00e7\u00e3o mais detalhadamente abaixo.<\/li>\n<li>Para uma transi\u00e7\u00e3o gradual, utilizamos o modo dry. Como temos duas vers\u00f5es da biblioteca com a mesma interface (uma para a vers\u00e3o padr\u00e3o e outra para o cluster), n\u00e3o \u00e9 dif\u00edcil criar um wrapper que trabalhe com a vers\u00e3o separada e, ao mesmo tempo, duplique todas as solicita\u00e7\u00f5es no cluster, comparando as respostas e registrando as discrep\u00e2ncias nos logs (neste caso, no NewRelic). Dessa forma, mesmo que a vers\u00e3o cluster falhe durante a implanta\u00e7\u00e3o, nossa produ\u00e7\u00e3o n\u00e3o ser\u00e1 afetada. <\/li>\n<li>Ao implantar o cluster em modo dry, podemos observar tranquilamente o gr\u00e1fico de discrep\u00e2ncias nas respostas. Se a propor\u00e7\u00e3o de erros se aproxima lentamente, mas de forma constante, de uma pequena constante, significa que est\u00e1 tudo bem. Por que ainda existem discrep\u00e2ncias? Porque a grava\u00e7\u00e3o na vers\u00e3o separada ocorre um pouco antes do que no cluster, e devido ao microdelay, os dados podem divergir. Basta olhar para os logs de discrep\u00e2ncias, e se todas forem explic\u00e1veis pela n\u00e3o atomicidade da grava\u00e7\u00e3o, podemos prosseguir.<\/li>\n<li>Agora podemos inverter o modo dry. Vamos gravar e ler do cluster, enquanto duplicamos na vers\u00e3o separada. Por qu\u00ea? Durante a pr\u00f3xima semana, queremos observar o funcionamento do cluster. Se, de repente, constatamos que h\u00e1 problemas sob carga m\u00e1xima ou esquecemos algo, sempre teremos um retorno de emerg\u00eancia para o c\u00f3digo antigo e dados atualizados gra\u00e7as ao modo dry.<\/li>\n<li>Agora s\u00f3 precisamos desativar o modo dry e desmontar a vers\u00e3o separada. <\/li>\n<\/ul>\n<p><\/p>\n<h1 id=\"ekspertiza\">Especializa\u00e7\u00e3o<\/h1>\n<p><\/p>\n<p>Primeiro, vamos falar brevemente sobre a estrutura do cluster.<\/p>\n<p><\/p>\n<p>Primeiro de tudo, o Redis \u00e9 um armazenamento key-value. Strings arbitr\u00e1rias s\u00e3o utilizadas como chaves. Os valores podem ser n\u00fameros, strings e estruturas inteiras. Existem in\u00fameras dessas estruturas, mas para entender a configura\u00e7\u00e3o geral, isso n\u00e3o \u00e9 importante.<br \/>\nO pr\u00f3ximo n\u00edvel de abstra\u00e7\u00e3o ap\u00f3s as chaves s\u00e3o os slots (SLOTS). Cada chave pertence a um dos 16.383 slots. Dentro de cada slot, pode haver quantas chaves forem necess\u00e1rias. Assim, todas as chaves se dividem em 16.383 conjuntos n\u00e3o sobrepostos.<br \/>\n<img decoding=\"async\" alt=\"Sobre a migra\u00e7\u00e3o de Redis para Redis-cluster\" src=\"\/wp-content\/uploads\/2020\/08\/a5e4be23381b42287f693e01d5d59a99.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Al\u00e9m disso, deve haver N n\u00f3s mestres no cluster. Cada n\u00f3 pode ser visto como uma inst\u00e2ncia separada do Redis, que conhece tudo sobre os outros n\u00f3s dentro do cluster. Cada n\u00f3 mestre cont\u00e9m uma certa quantidade de slots. Cada slot pertence apenas a um \u00fanico n\u00f3 mestre. Todos os slots devem ser distribu\u00eddos entre os n\u00f3s. Se alguns slots n\u00e3o forem distribu\u00eddos, as chaves armazenadas neles estar\u00e3o inacess\u00edveis. Faz sentido executar cada n\u00f3 mestre em uma m\u00e1quina l\u00f3gica ou f\u00edsica separada. Tamb\u00e9m \u00e9 importante lembrar que cada n\u00f3 opera em apenas um n\u00facleo, e se voc\u00ea quiser executar v\u00e1rias inst\u00e2ncias do Redis em uma \u00fanica m\u00e1quina l\u00f3gica, certifique-se de que elas funcionem em n\u00facleos diferentes (n\u00e3o experimentamos isso, mas teoricamente deveria funcionar). Em ess\u00eancia, os n\u00f3s mestres proporcionam a fragmenta\u00e7\u00e3o normal, e um maior n\u00famero de n\u00f3s mestres permite escalar as solicita\u00e7\u00f5es de grava\u00e7\u00e3o e leitura.<\/p>\n<p><\/p>\n<p>Depois que todas as chaves estiverem distribu\u00eddas pelos slots e os slots estiverem espalhados pelos n\u00f3s mestres, pode-se adicionar um n\u00famero arbitr\u00e1rio de n\u00f3s escravos a cada n\u00f3 mestre. Dentro de cada tal par \"mestre-escravo\", a replica\u00e7\u00e3o padr\u00e3o ocorrer\u00e1. Os escravos s\u00e3o necess\u00e1rios para escalar solicita\u00e7\u00f5es de leitura e para failover em caso de falha do mestre.<br \/>\n<img decoding=\"async\" alt=\"Sobre a migra\u00e7\u00e3o de Redis para Redis-cluster\" src=\"\/wp-content\/uploads\/2020\/08\/90feb7ef9dacb858d5f21edc214df14d.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Agora, vamos falar sobre as opera\u00e7\u00f5es que seria bom saber fazer.<\/p>\n<p><\/p>\n<p>Vamos acessar o sistema atrav\u00e9s do Redis-CLI. Como o Redis n\u00e3o possui um \u00fanico ponto de entrada, as seguintes opera\u00e7\u00f5es podem ser executadas em qualquer um dos n\u00f3s. Em cada item, chamo a aten\u00e7\u00e3o para a possibilidade de realizar a opera\u00e7\u00e3o sob carga.<\/p>\n<p><\/p>\n<ul>\n<li>A primeira e mais importante opera\u00e7\u00e3o de que precisamos: cluster nodes. Ela retorna o estado do cluster, mostrando a lista de n\u00f3s, seus pap\u00e9is, a distribui\u00e7\u00e3o dos slots, etc. Informa\u00e7\u00f5es adicionais podem ser obtidas com cluster info e cluster slots.<\/li>\n<li>Seria bom poder adicionar e remover n\u00f3s. Para isso, existem as opera\u00e7\u00f5es cluster meet e cluster forget. Note que o cluster forget deve ser aplicado a CADA n\u00f3, tanto mestres quanto r\u00e9plicas. J\u00e1 o cluster meet pode ser chamado apenas em um n\u00f3. Essa diferen\u00e7a pode ser desencorajador, ent\u00e3o \u00e9 melhor conhec\u00ea-la antes de colocar o cluster em produ\u00e7\u00e3o. A adi\u00e7\u00e3o de um n\u00f3 \u00e9 feita com seguran\u00e7a durante opera\u00e7\u00f5es e n\u00e3o afeta o funcionamento do cluster (o que faz sentido). No entanto, se voc\u00ea pretende remover um n\u00f3 do cluster, deve garantir que n\u00e3o sobraram slots nele (caso contr\u00e1rio, voc\u00ea corre o risco de perder o acesso a todas as chaves nesse n\u00f3). Al\u00e9m disso, n\u00e3o remova um mestre que tem escravos, pois isso resultar\u00e1 em uma vota\u00e7\u00e3o desnecess\u00e1ria para um novo mestre. Se n\u00e3o h\u00e1 mais slots nos n\u00f3s, isso \u00e9 um pequeno problema, mas por que queremos decis\u00f5es extras se podemos primeiro remover os escravos.<\/li>\n<li>Se for necess\u00e1rio for\u00e7ar a troca entre mestre e escravo, ent\u00e3o use o comando cluster failover. Ao cham\u00e1-lo durante opera\u00e7\u00f5es, \u00e9 necess\u00e1rio entender que, durante a execu\u00e7\u00e3o da opera\u00e7\u00e3o, o mestre ficar\u00e1 indispon\u00edvel. Normalmente, a troca ocorre em menos de um segundo, mas n\u00e3o de forma at\u00f4mica. Voc\u00ea pode esperar que parte das solicita\u00e7\u00f5es para o mestre termine com erro nesse tempo.<\/li>\n<li>Antes de remover um n\u00f3 do cluster, n\u00e3o deve haver slots restantes nele. \u00c9 melhor redistribu\u00ed-los usando o comando cluster reshard. Os slots ser\u00e3o transferidos de um mestre para outro. Todo o processo pode levar alguns minutos, dependendo do volume de dados a serem transferidos, mas a transfer\u00eancia \u00e9 segura e n\u00e3o afeta o funcionamento do cluster. Assim, todos os dados podem ser transferidos de um n\u00f3 para outro sob carga, sem se preocupar com sua disponibilidade. No entanto, existem algumas nuances. Primeiro, a transfer\u00eancia de dados imp\u00f5e uma certa carga ao n\u00f3 receptor e ao remetente. Se o n\u00f3 receptor j\u00e1 estiver muito sobrecarregado em termos de CPU, n\u00e3o deve ser sobrecarregado com a recep\u00e7\u00e3o de novos dados. Em segundo lugar, assim que n\u00e3o houver nenhum slot no mestre remetente, todos os seus slaves automaticamente se conectar\u00e3o ao mestre para o qual esses slots foram transferidos. O problema \u00e9 que todos esses slaves querer\u00e3o sincronizar os dados ao mesmo tempo. E voc\u00ea pode ter sorte se isso for uma sincroniza\u00e7\u00e3o parcial e n\u00e3o total. Leve isso em considera\u00e7\u00e3o e combine as opera\u00e7\u00f5es de transfer\u00eancia de slots com a desconex\u00e3o\/transfer\u00eancia de slaves. Ou ent\u00e3o, espere que voc\u00ea tenha uma margem de seguran\u00e7a suficiente.<\/li>\n<li>O que fazer se, durante a transfer\u00eancia, voc\u00ea descobrir que perdeu slots? Espero que esse problema n\u00e3o ocorra com voc\u00ea, mas se acontecer, existe a opera\u00e7\u00e3o cluster fix. Ela redistribui os slots pelos n\u00f3s de forma aleat\u00f3ria. Recomendo verificar seu funcionamento, removendo previamente do cluster um n\u00f3 com slots distribu\u00eddos. Como os dados nos slots n\u00e3o distribu\u00eddos j\u00e1 est\u00e3o indispon\u00edveis, preocupar-se com problemas de disponibilidade desses slots j\u00e1 \u00e9 tarde demais. Por sua vez, a opera\u00e7\u00e3o n\u00e3o afetar\u00e1 os slots distribu\u00eddos.<\/li>\n<li>Outra opera\u00e7\u00e3o \u00fatil \u00e9 a monitor. Ela permite visualizar em tempo real toda a lista de solicita\u00e7\u00f5es que est\u00e3o indo para o n\u00f3. Al\u00e9m disso, voc\u00ea pode fazer um grep nela para saber se h\u00e1 o tr\u00e1fego necess\u00e1rio.<\/li>\n<\/ul>\n<p><\/p>\n<p>Tamb\u00e9m vale mencionar o procedimento de failover do master. Em resumo, ele existe e, na minha opini\u00e3o, funciona muito bem. No entanto, n\u00e3o se deve pensar que, se voc\u00ea desconectar o cabo da tomada de uma m\u00e1quina com um n\u00f3 master, o Redis mudar\u00e1 imediatamente e os clientes n\u00e3o notar\u00e3o a queda. Na minha pr\u00e1tica, a transi\u00e7\u00e3o leva alguns segundos. Durante esse tempo, parte dos dados ficar\u00e1 indispon\u00edvel: a indisponibilidade do master \u00e9 detectada, os n\u00f3s votam em um novo, os slaves fazem a troca e os dados s\u00e3o sincronizados. A melhor maneira de se certificar de que o esquema funciona \u00e9 realizar exerc\u00edcios locais. Levante um cluster no seu laptop, aplique uma carga m\u00ednima, simule uma queda (por exemplo, bloqueando as portas), e avalie a velocidade de troca. Na minha opini\u00e3o, s\u00f3 depois de brincar assim por um ou dois dias \u00e9 que se pode ter certeza do funcionamento da tecnologia. Ou, ent\u00e3o, contar que o software que metade da internet usa deve funcionar bem.<\/p>\n<p><\/p>\n<h1 id=\"konfiguraciya\">Configura\u00e7\u00e3o<\/h1>\n<p><\/p>\n<p>Geralmente, a configura\u00e7\u00e3o \u00e9 a primeira coisa que \u00e9 necess\u00e1ria para come\u00e7ar a trabalhar com a ferramenta. E quando tudo est\u00e1 funcionando, n\u00e3o se quer mexer na configura\u00e7\u00e3o. \u00c9 necess\u00e1rio um esfor\u00e7o consider\u00e1vel para se for\u00e7ar a voltar \u00e0s configura\u00e7\u00f5es e revis\u00e1-las minuciosamente. Na minha mem\u00f3ria, tivemos pelo menos dois problemas s\u00e9rios devido \u00e0 falta de aten\u00e7\u00e3o \u00e0 configura\u00e7\u00e3o. Preste aten\u00e7\u00e3o especial aos seguintes pontos:<\/p>\n<p><\/p>\n<ul>\n<li>timeout 0<br \/>\n<em>O tempo ap\u00f3s o qual as conex\u00f5es inativas s\u00e3o fechadas (em segundos). 0 \u2014 n\u00e3o s\u00e3o fechadas.<\/em><br \/>\nNem toda nossa biblioteca conseguia fechar as conex\u00f5es corretamente. Desativando essa configura\u00e7\u00e3o, corremos o risco de atingir o limite de n\u00famero de clientes. Por outro lado, se esse problema existir, a quebra autom\u00e1tica de conex\u00f5es perdidas poder\u00e1 mascar\u00e1-lo, e podemos n\u00e3o perceber. Al\u00e9m disso, n\u00e3o \u00e9 recomend\u00e1vel ativar essa configura\u00e7\u00e3o ao usar conex\u00f5es persistentes.<\/li>\n<li>Save x y &amp; appendonly yes<br \/>\n<em>Salvamento de snapshot em RDB.<\/em><br \/>\nProblemas com RDB\/AOF discutiremos detalhadamente a seguir.<\/li>\n<li>stop-writes-on-bgsave-error no &amp; slave-serve-stale-data yes<br \/>\n<em>Se ativado, ao ocorrer uma falha no snapshot RDB, o master deixar\u00e1 de aceitar requisi\u00e7\u00f5es de altera\u00e7\u00e3o. Se a conex\u00e3o com o master for perdida, o slave pode continuar a responder \u00e0s requisi\u00e7\u00f5es (yes). Ou pode parar de responder (no).<\/em><br \/>\nN\u00e3o estamos satisfeitos com a situa\u00e7\u00e3o em que o Redis se torna um ab\u00f3bora.<\/li>\n<li>repl-ping-slave-period 5<br \/>\n<em>Ap\u00f3s esse intervalo, come\u00e7aremos a nos preocupar que o mestre falhou, e ser\u00e1 hora de realizar o procedimento de failover.<\/em><br \/>\nTeremos que encontrar manualmente um equil\u00edbrio entre alarmes falsos e o acionamento do failover. Em nossa experi\u00eancia, isso leva cerca de 5 segundos.<\/li>\n<li>repl-backlog-size 1024mb &amp; epl-backlog-ttl 0<br \/>\n<em>\u00c9 exatamente a quantidade de dados que podemos armazenar no buffer para uma r\u00e9plica que falhou. Se o buffer acabar, ser\u00e1 necess\u00e1rio fazer uma sincroniza\u00e7\u00e3o completa.<\/em><br \/>\nA pr\u00e1tica sugere que \u00e9 melhor definir um valor maior. Existem muitas raz\u00f5es pelas quais a r\u00e9plica pode come\u00e7ar a ficar para tr\u00e1s. Se ela estiver para tr\u00e1s, provavelmente seu mestre j\u00e1 est\u00e1 lutando, e a sincroniza\u00e7\u00e3o completa ser\u00e1 a gota d'\u00e1gua.<\/li>\n<li>maxclients 10000<br \/>\n<em>N\u00famero m\u00e1ximo de clientes simult\u00e2neos.<\/em><br \/>\nEm nossa experi\u00eancia, \u00e9 melhor definir um valor maior. O Redis lida bem com at\u00e9 10 mil conex\u00f5es. Apenas certifique-se de que o sistema tenha sockets suficientes. <\/li>\n<li>maxmemory-policy volatile-ttl<br \/>\n<em>Regra pela qual as chaves s\u00e3o removidas ao atingir o limite de mem\u00f3ria dispon\u00edvel.<\/em><br \/>\nAqui, o importante n\u00e3o \u00e9 apenas a regra, mas a compreens\u00e3o de como isso ocorrer\u00e1. O Redis merece elogios por saber lidar bem ao atingir o limite de mem\u00f3ria. <\/li>\n<\/ul>\n<p><\/p>\n<h1 id=\"problemy-rdb-i-aof\">Problemas RDB e AOF<\/h1>\n<p><\/p>\n<p>Embora o pr\u00f3prio Redis armazene todas as informa\u00e7\u00f5es na mem\u00f3ria RAM, tamb\u00e9m h\u00e1 mecanismos para salvar dados no disco. Mais precisamente, tr\u00eas mecanismos:<\/p>\n<p><\/p>\n<ul>\n<li>RDB-snapshot \u2014 um snapshot completo de todos os dados. \u00c9 configurado usando SAVE X Y e interpretado como 'Salvar um snapshot completo de todos os dados a cada X segundos, se pelo menos Y chaves mudarem'.<\/li>\n<li>Arquivo de append-only \u2014 uma lista de opera\u00e7\u00f5es na ordem em que foram realizadas. Adiciona novas opera\u00e7\u00f5es ao arquivo a cada X segundos ou a cada Y opera\u00e7\u00f5es.<\/li>\n<li>RDB e AOF \u2014 uma combina\u00e7\u00e3o dos dois anteriores.<\/li>\n<\/ul>\n<p><\/p>\n<p>Todos os m\u00e9todos t\u00eam suas vantagens e desvantagens; n\u00e3o vou listar todas, mas gostaria de chamar a aten\u00e7\u00e3o para alguns pontos que n\u00e3o s\u00e3o \u00f3bvios, na minha opini\u00e3o.<\/p>\n<p><\/p>\n<p>Primeiro, para salvar um snapshot RDB, \u00e9 necess\u00e1rio chamar o FORK. Se os dados forem muitos, isso pode travar todo o Redis por um per\u00edodo que varia de alguns milissegundos a um segundo. Al\u00e9m disso, o sistema precisa alocar mem\u00f3ria para esse snapshot, o que leva \u00e0 necessidade de manter uma reserva de mem\u00f3ria RAM na m\u00e1quina l\u00f3gica: se o Redis aloca 8 GB, a m\u00e1quina virtual deve ter 16 GB dispon\u00edveis.<\/p>\n<p><\/p>\n<p>Em segundo lugar, existem problemas com a sincroniza\u00e7\u00e3o parcial. No modo AOF, ao reconectar o slave, em vez da sincroniza\u00e7\u00e3o parcial, pode ocorrer uma sincroniza\u00e7\u00e3o completa. N\u00e3o consegui entender por que isso acontece. Mas \u00e9 algo que vale a pena lembrar.<\/p>\n<p><\/p>\n<p>Esses dois pontos j\u00e1 fazem voc\u00ea pensar se realmente precisamos desses dados no disco, j\u00e1 que tudo \u00e9 duplicado pelos slaves. A perda de dados s\u00f3 pode ocorrer se todos os slaves falharem, e isso \u00e9 um problema de n\u00edvel \"inc\u00eandio no datacenter\". Como compromisso, pode-se sugerir que os dados sejam armazenados apenas nos slaves, mas nesse caso \u00e9 preciso garantir que esses slaves nunca se tornem mestres em uma recupera\u00e7\u00e3o de emerg\u00eancia (para isso, existe uma configura\u00e7\u00e3o de prioridade dos slaves em sua configura\u00e7\u00e3o). Para cada caso espec\u00edfico, refletimos se \u00e9 necess\u00e1rio armazenar dados no disco e, na maioria das vezes, respondemos \"n\u00e3o\".<\/p>\n<p><\/p>\n<h1 id=\"zaklyuchenie\">Conclus\u00e3o<\/h1>\n<p><\/p>\n<p>Por fim, espero ter dado uma vis\u00e3o geral do funcionamento do redis-cluster para aqueles que nunca ouviram falar dele, al\u00e9m de ter destacado alguns pontos n\u00e3o \u00f3bvios para quem j\u00e1 o utiliza h\u00e1 algum tempo.<br \/>\nObrigado pelo seu tempo e, como sempre, coment\u00e1rios sobre o assunto s\u00e3o bem-vindos.<\/p>\n<p>Fonte: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/citymobil\/blog\/515620\/\">habr.com<\/a> <\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u041f\u0440\u0438\u0445\u043e\u0434\u044f \u0432 \u043f\u0440\u043e\u0434\u0443\u043a\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0440\u0430\u0437\u0432\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0431\u043e\u043b\u044c\u0448\u0435 \u0434\u0435\u0441\u044f\u0442\u043a\u0430 \u043b\u0435\u0442, \u0441\u043e\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u043e \u043d\u0435 \u0443\u0434\u0438\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0432\u0441\u0442\u0440\u0435\u0442\u0438\u0442\u044c \u0432 \u043d\u0435\u043c \u0443\u0441\u0442\u0430\u0440\u0435\u0432\u0448\u0438\u0435 \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u0438. \u041d\u043e \u0447\u0442\u043e \u0435\u0441\u043b\u0438 \u0447\u0435\u0440\u0435\u0437 \u043f\u043e\u043b\u0433\u043e\u0434\u0430 \u0432\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0434\u0435\u0440\u0436\u0430\u0442\u044c \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0443 \u0432 10 \u0440\u0430\u0437 \u0432\u044b\u0448\u0435, \u0430 \u0446\u0435\u043d\u0430 \u043f\u0430\u0434\u0435\u043d\u0438\u0439 \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0442\u0441\u044f \u0432 \u0441\u043e\u0442\u043d\u0438 \u0440\u0430\u0437? \u0412 \u044d\u0442\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0432\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c \u043a\u0440\u0443\u0442\u043e\u0439 Highload Engineer. \u041d\u043e \u0437\u0430 \u043d\u0435\u0438\u043c\u0435\u043d\u0438\u0435\u043c \u0433\u043e\u0440\u043d\u0438\u0447\u043d\u043e\u0439 \u0442\u0430\u043a\u043e\u0432\u043e\u0433\u043e, \u0440\u0435\u0448\u0430\u0442\u044c \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443 \u0434\u043e\u0432\u0435\u0440\u0438\u043b\u0438 \u043c\u043d\u0435. \u0412 \u043f\u0435\u0440\u0432\u043e\u0439 [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":91847,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-91846","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.3 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u041f\u0440\u0438\u0445\u043e\u0434\u044f \u0432 \u043f\u0440\u043e\u0434\u0443\u043a\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0440\u0430\u0437\u0432\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0431\u043e\u043b\u044c\u0448\u0435.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/pt\/blog\/administrirovanie\/o-pereezde-s-redis-na-redis-cluster\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.3\" \/>\n\t\t<meta property=\"og:locale\" content=\"pt_PT\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u041e \u043f\u0435\u0440\u0435\u0435\u0437\u0434\u0435 \u0441 Redis \u043d\u0430 Redis-cluster | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u041f\u0440\u0438\u0445\u043e\u0434\u044f \u0432 \u043f\u0440\u043e\u0434\u0443\u043a\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0440\u0430\u0437\u0432\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0431\u043e\u043b\u044c\u0448\u0435.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/pt\/blog\/administrirovanie\/o-pereezde-s-redis-na-redis-cluster\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2020-08-19T17:41:57+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-08-19T17:41:57+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Sobre a migra\u00e7\u00e3o de Redis para Redis-cluster | ProHoster","description":"Chegando em um produto que est\u00e1 mais em desenvolvimento.","canonical_url":"https:\/\/prohoster.info\/pt\/blog\/administrirovanie\/o-pereezde-s-redis-na-redis-cluster","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"pt_PT","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u041e \u043f\u0435\u0440\u0435\u0435\u0437\u0434\u0435 \u0441 Redis \u043d\u0430 Redis-cluster | ProHoster","og:description":"\u041f\u0440\u0438\u0445\u043e\u0434\u044f \u0432 \u043f\u0440\u043e\u0434\u0443\u043a\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0440\u0430\u0437\u0432\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0431\u043e\u043b\u044c\u0448\u0435.","og:url":"https:\/\/prohoster.info\/pt\/blog\/administrirovanie\/o-pereezde-s-redis-na-redis-cluster","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2020-08-19T17:41:57+00:00","article:modified_time":"2020-08-19T17:41:57+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"91846","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":null,"breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 12:19:41","updated":"2022-10-03 14:54:15","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/posts\/91846","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/comments?post=91846"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/posts\/91846\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/media\/91847"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/media?parent=91846"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/categories?post=91846"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/tags?post=91846"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}