Solucionando Erros Comuns de Conexão Redis de Forma Eficaz

Lutando com problemas de conexão Redis? Este guia prático fornece etapas claras para diagnosticar e resolver erros comuns como 'Conexão Recusada', 'Tempos Limite' e 'Falhas de Autenticação'. Aprenda a verificar o status do servidor, configurações de rede, firewalls e métricas de desempenho do Redis. Inclui exemplos acionáveis para `redis-cli` e bibliotecas de cliente para colocar suas conexões Redis online de forma eficiente.

Solucionando Erros Comuns de Conexão Redis de Forma Eficaz

Erros de conexão Redis geralmente são simples quando você os separa em três perguntas: o cliente consegue alcançar o host e a porta, o Redis aceita a conexão e o cliente tem permissão para executar comandos após conectar?

Faça isso em ordem. Pular direto para o código da aplicação perde tempo quando o Redis está parado. Reconstruir uma regra de firewall perde tempo quando a senha está errada. Uma pequena lista de verificação repetível leva você à falha real mais rapidamente.

Primeiro, teste do mesmo local que a aplicação

Testar do seu laptop é útil, mas não prova que um pod Kubernetes, VM, contêiner ou executor de CI pode alcançar o Redis. Comece dentro do mesmo local de rede da aplicação com falha.

redis-cli -h redis.exemplo.interno -p 6379 PING

Saída esperada:

PONG

Se o Redis exigir TLS, use as opções TLS que sua implantação espera:

redis-cli --tls -h redis.exemplo.interno -p 6380 PING

Se o Redis exigir autenticação:

redis-cli -u redis://app-usuario:[email protected]:6379 PING

Tenha cuidado com senhas no histórico do shell. Para produção, use credenciais temporárias ou variáveis de ambiente quando possível.

Conexão recusada

ECONNREFUSED, Conexão recusada ou Não foi possível conectar ao Redis geralmente significa que a conexão TCP alcançou o host de destino, mas nada a aceitou naquela porta. As causas mais comuns são simples:

  • O Redis não está em execução.
  • O cliente está usando o host ou porta errados.
  • O Redis está vinculado apenas ao localhost.
  • Um mapeamento de contêiner ou serviço aponta para a porta errada.
  • Um firewall rejeita ativamente a conexão.

No host Redis, verifique o processo e o ouvinte:

redis-cli PING
ps aux | grep '[r]edis-server'
ss -ltnp | grep redis

Você quer ver o Redis ouvindo no endereço e porta esperados, comumente 127.0.0.1:6379, 0.0.0.0:6379 ou um endereço de interface privada.

Verifique redis.conf ou a configuração efetiva:

redis-cli CONFIG GET bind
redis-cli CONFIG GET port
redis-cli CONFIG GET protected-mode

Se bind for 127.0.0.1, clientes remotos não podem conectar diretamente. Isso geralmente é intencional. Não o altere para 0.0.0.0 como uma correção rápida, a menos que o Redis esteja protegido por autenticação, ACLs, regras de firewall e rede privada. Redis exposto na internet pública é um incidente de segurança grave prestes a acontecer.

No Docker, lembre-se da diferença entre porta do contêiner e porta do host:

docker ps
docker port <contêiner-redis>

Dentro de uma rede Docker Compose, as aplicações geralmente se conectam ao nome do serviço e à porta interna:

redis://redis:6379

Do host, elas podem se conectar a uma porta publicada como localhost:6379 ou localhost:6381, dependendo do mapeamento.

Tempo limite de conexão

Um tempo limite significa que o cliente esperou e não completou a operação a tempo. Ao contrário de conexões recusadas, tempos limite geralmente apontam para um problema de caminho ou um servidor ocupado.

Verifique o caminho TCP:

nc -vz redis.exemplo.interno 6379
ping -c 5 redis.exemplo.interno

ping não é perfeito porque o ICMP pode estar bloqueado enquanto o TCP funciona, mas pode revelar erros óbvios de DNS ou roteamento. nc está mais próximo do que o cliente Redis precisa.

Se o TCP conectar, mas os comandos Redis expirarem, verifique se o Redis está ocupado:

redis-cli INFO clients
redis-cli INFO stats
redis-cli INFO memory
redis-cli SLOWLOG GET 10
redis-cli LATENCY DOCTOR

Procure por clientes bloqueados, contagens altas de clientes conectados, memória próxima de maxmemory, swap no host, comandos lentos e eventos de latência. Um único comando caro como KEYS *, um grande HGETALL ou um script Lua longo pode atrasar clientes não relacionados porque a execução de comandos Redis é amplamente single-threaded.

Verifique também as configurações de tempo limite do cliente. Algumas bibliotecas usam padrões curtos para tempos limite de conexão ou de comando. Aumentar o tempo limite pode reduzir falhas falsas em uma rede lenta, mas não deve esconder uma instância Redis sobrecarregada. Se um simples PING leva segundos do host da aplicação, corrija isso antes de ajustar as tentativas.

Problemas de resolução de nome e endpoint errado

Nem todo erro de conexão é Redis. DNS e descoberta de serviço causam muitos deles.

Do host da aplicação:

getent hosts redis.exemplo.interno
nslookup redis.exemplo.interno

No Kubernetes:

kubectl exec -it deploy/minha-app -- sh
getent hosts redis.default.svc.cluster.local
nc -vz redis.default.svc.cluster.local 6379

Verifique se a aplicação está usando um endpoint de réplica de leitura, um endpoint sentinel, um endpoint de cluster ou um endpoint de nó direto. Clientes Redis Cluster precisam de bibliotecas cientes de cluster porque as chaves podem pertencer a slots diferentes e os comandos podem receber redirecionamentos. Um cliente não ciente de cluster pode conectar com sucesso e depois falhar com erros MOVED ou ASK assim que enviar comandos reais.

Erros de autenticação

Falhas de autenticação aparecem como:

  • NOAUTH Authentication required
  • WRONGPASS invalid username-password pair
  • NOPERM this user has no permissions
  • Exceções de autenticação específicas da biblioteca do cliente

Para Redis 6 e mais recentes, usuários ACL são comuns. Uma string de conexão pode precisar tanto do nome de usuário quanto da senha:

redis://app-usuario:[email protected]:6379/0

Com o usuário padrão, alguns clientes usam apenas uma senha:

redis://:[email protected]:6379/0

Verifique a configuração do usuário ativo se você tiver acesso de administrador:

redis-cli ACL LIST
redis-cli ACL GETUSER app-usuario

NOAUTH significa que o cliente não autenticou antes de emitir um comando. WRONGPASS significa que a autenticação foi tentada, mas rejeitada. NOPERM significa que a autenticação funcionou, mas o usuário não tem permissão para o comando, padrão de chave ou canal Pub/Sub.

Quando os segredos são rotacionados, confirme que cada processo em execução realmente recebeu o novo valor. Em plataformas de contêiner, atualizar um objeto secreto nem sempre reinicia pods ou processos existentes. Uma falha comum no mundo real é metade da aplicação usando a nova senha e metade ainda usando a antiga.

Incompatibilidade TLS

Erros de TLS podem parecer redefinições de conexão, tempos limite ou erros de protocolo ilegíveis.

Verifique a porta. Serviços gerenciados geralmente usam portas diferentes para TLS e Redis não TLS. Por exemplo, um endpoint pode esperar protocolo Redis simples e outro pode esperar TLS desde o primeiro byte.

Teste com:

redis-cli --tls -h redis.exemplo.interno -p 6380 PING
redis-cli -h redis.exemplo.interno -p 6379 PING

Se sua organização usar certificados privados, o cliente também pode precisar de um arquivo CA:

redis-cli --tls --cacert /caminho/para/ca.pem -h redis.exemplo.interno -p 6380 PING

Nos logs da aplicação, erros de certificado são geralmente mais claros do que a exceção Redis de nível superior. Procure por mensagens sobre autoridades desconhecidas, certificados expirados, incompatibilidade de nome de host ou falha de handshake.

Muitas conexões

O Redis tem um limite maxclients. O sistema operacional também tem limites de descritores de arquivo. Quando qualquer um é esgotado, novos clientes podem falhar ou clientes existentes podem se comportar mal.

Verifique:

redis-cli INFO clients
redis-cli CONFIG GET maxclients
ulimit -n

Campos úteis incluem connected_clients, blocked_clients e rejected_connections de INFO stats.

Muitas conexões geralmente vêm de um destes padrões:

  • Criar um novo cliente Redis por requisição web.
  • Não fechar clientes em trabalhos de curta duração.
  • Muitos processos de trabalho, cada um com seu próprio pool grande.
  • Assinaturas Pub/Sub pegando emprestado conexões de um pool de comandos normal.
  • Tempestades de repetição durante uma reinicialização do Redis.

Corrija a forma da aplicação antes de aumentar os limites. Use um cliente compartilhado ou um pool limitado por processo. Adicione backoff de reconexão com jitter para que cada instância não se reconecte no mesmo milissegundo após uma interrupção.

Modo protegido e configurações de bind

O modo protegido do Redis é projetado para reduzir o dano de exposição acidental. Se o Redis estiver vinculado amplamente e não tiver autenticação, o modo protegido pode rejeitar conexões remotas.

Verifique:

redis-cli CONFIG GET protected-mode
redis-cli CONFIG GET bind
redis-cli CONFIG GET requirepass

Não desabilite o modo protegido apenas para fazer uma conexão remota funcionar. O caminho mais seguro geralmente é rede privada mais autenticação e um endereço de bind estreito. Se o Redis deve aceitar clientes remotos, coloque-o em uma sub-rede privada, restrinja IPs de origem, exija credenciais e use TLS quando apropriado.

Uma ordem prática de operações

Quando uma aplicação não consegue conectar, use esta sequência:

  1. Do ambiente da aplicação, execute redis-cli PING contra o mesmo host e porta.
  2. Se recusado, verifique processo Redis, ouvinte, bind, porta e mapeamento de contêiner.
  3. Se expirado, verifique roteamento, regras de firewall, carga do servidor, comandos lentos e configurações de tempo limite do cliente.
  4. Se a autenticação falhar, verifique nome de usuário, senha, permissões ACL e implantação de segredo.
  5. Se apenas alguns comandos falharem, verifique permissões de comando/chave ACL e redirecionamentos Redis Cluster.
  6. Se as falhas acontecerem sob carga, verifique contagens de conexão, dimensionamento do pool, tentativas e métricas de recursos do servidor.

Solução de problemas de conexão é principalmente coleta de evidências. Obtenha um resultado CLI limpo do mesmo lugar que a aplicação, depois compare-o com o que a biblioteca do cliente está fazendo. Uma vez que esses dois caminhos diferem, a lacuna geralmente é visível: uma flag TLS ausente, uma senha antiga, um nome de serviço errado ou um pool que cria muito mais conexões do que o Redis foi dimensionado para lidar.

Lendo erros da aplicação sem reagir exageradamente

Bibliotecas de cliente envolvem erros Redis em sua própria linguagem. Um serviço Node.js pode mostrar ECONNRESET, um worker Python pode mostrar redis.exceptions.ConnectionError e um serviço Java pode relatar um tempo limite de aquisição de pool. Todos podem descrever diferentes camadas do mesmo problema.

Separe-os:

  • Tempo limite de conexão: a conexão TCP não foi concluída rápido o suficiente.
  • Tempo limite de leitura: a conexão existe, mas uma resposta de comando não chegou a tempo.
  • Redefinição de conexão: a conexão foi fechada pelo Redis, um proxy, a rede ou o par.
  • Tempo limite de pool: a aplicação não conseguiu pegar uma conexão Redis emprestada de seu próprio pool.
  • Erro de autenticação: Redis rejeitou as credenciais ou permissões.

Um tempo limite de pool é fácil de interpretar erroneamente como uma interrupção do Redis. Às vezes o Redis está bem, mas a aplicação pegou todas as conexões do pool e nunca as devolveu. O uso indevido de Pub/Sub pode causar isso. Também comandos de bloqueio longos, manipuladores de requisição que esquecem de fechar clientes ou um pool muito pequeno para a concorrência do processo.

Verifique ambos os lados ao mesmo tempo. Na aplicação, inspecione métricas do pool se a biblioteca as expuser: conexões ativas, conexões ociosas, esperas, contagem de tentativas. No Redis, verifique:

redis-cli INFO clients
redis-cli CLIENT LIST | head

Se o Redis mostrar apenas um punhado de clientes, mas a aplicação disser que seu pool está esgotado, o problema provavelmente está dentro do processo da aplicação. Se o Redis mostrar milhares de conexões da mesma implantação, o serviço pode estar criando clientes com muita frequência.

Tentativas merecem atenção especial. Um loop de reconexão sem backoff pode transformar uma reinicialização curta do Redis em uma tempestade. Cada instância da aplicação tenta se reconectar imediatamente, picos de autenticação e handshakes TLS, e o Redis tem que se recuperar enquanto é bombardeado por clientes. Use backoff exponencial com jitter. Também decida quais comandos são seguros para repetir. Repetir um GET de cache idempotente é diferente de repetir uma escrita que pode já ter sido bem-sucedida antes da conexão cair.

Para notas de incidente, capture o texto exato do erro e o tempo. "Redis estava fora do ar" geralmente está errado. "Das 14:03 às 14:06 UTC, pods da aplicação viram tempos limite de leitura enquanto a CPU do Redis estava em um núcleo e SLOWLOG mostrava grandes chamadas HGETALL" é acionável.