Dépannage efficace des erreurs courantes de connexion Redis
Vous rencontrez des problèmes de connexion Redis ? Ce guide pratique fournit des étapes claires pour diagnostiquer et résoudre les erreurs courantes telles que 'Connexion refusée', 'Délais d'attente' et 'Échecs d'authentification'. Apprenez à vérifier l'état du serveur, les configurations réseau, les pare-feu et les métriques de performance Redis. Inclut des exemples concrets pour `redis-cli` et les bibliothèques clientes afin de rétablir efficacement vos connexions Redis.
Dépannage efficace des erreurs courantes de connexion Redis
Les erreurs de connexion Redis sont généralement simples une fois que vous les séparez en trois questions : le client peut-il atteindre l'hôte et le port, Redis accepte-t-il la connexion, et le client est-il autorisé à exécuter des commandes après la connexion ?
Procédez dans cet ordre. Sauter directement dans le code de l'application fait perdre du temps lorsque Redis est arrêté. Reconstruire une règle de pare-feu fait perdre du temps lorsque le mot de passe est erroné. Une petite liste de contrôle reproductible vous mène plus rapidement à la véritable panne.
D'abord, testez depuis le même endroit que l'application
Tester depuis votre ordinateur portable est utile, mais cela ne prouve pas qu'un pod Kubernetes, une VM, un conteneur ou un exécuteur CI peut atteindre Redis. Commencez à l'intérieur du même emplacement réseau que l'application défaillante.
redis-cli -h redis.example.internal -p 6379 PING
Sortie attendue :
PONG
Si Redis nécessite TLS, utilisez les options TLS attendues par votre déploiement :
redis-cli --tls -h redis.example.internal -p 6380 PING
Si Redis nécessite une authentification :
redis-cli -u redis://app-user:[email protected]:6379 PING
Soyez prudent avec les mots de passe dans l'historique du shell. Pour la production, utilisez des identifiants temporaires ou des variables d'environnement lorsque c'est possible.
Connexion refusée
ECONNREFUSED, Connection refused, ou Could not connect to Redis signifie généralement que la connexion TCP a atteint l'hôte cible, mais que rien ne l'a acceptée sur ce port. Les causes les plus courantes sont simples :
- Redis n'est pas en cours d'exécution.
- Le client utilise un mauvais hôte ou un mauvais port.
- Redis est lié uniquement à localhost.
- Un mappage de conteneur ou de service pointe vers le mauvais port.
- Un pare-feu rejette activement la connexion.
Sur l'hôte Redis, vérifiez le processus et l'écouteur :
redis-cli PING
ps aux | grep '[r]edis-server'
ss -ltnp | grep redis
Vous voulez voir Redis écouter sur l'adresse et le port attendus, généralement 127.0.0.1:6379, 0.0.0.0:6379, ou une adresse d'interface privée.
Vérifiez redis.conf ou la configuration effective :
redis-cli CONFIG GET bind
redis-cli CONFIG GET port
redis-cli CONFIG GET protected-mode
Si bind est 127.0.0.1, les clients distants ne peuvent pas se connecter directement. C'est souvent intentionnel. Ne le modifiez pas en 0.0.0.0 comme solution rapide à moins que Redis ne soit protégé par l'authentification, les ACL, les règles de pare-feu et le réseau privé. Redis exposé sur l'internet public est un incident de sécurité grave en attente de se produire.
Dans Docker, rappelez-vous la différence entre le port du conteneur et le port de l'hôte :
docker ps
docker port <redis-container>
À l'intérieur d'un réseau Docker Compose, les applications se connectent généralement au nom du service et au port interne :
redis://redis:6379
Depuis l'hôte, elles peuvent se connecter à un port publié tel que localhost:6379 ou localhost:6381, selon le mappage.
Délai d'attente de connexion
Un délai d'attente signifie que le client a attendu et n'a pas terminé l'opération à temps. Contrairement aux connexions refusées, les délais d'attente indiquent souvent un problème de chemin ou un serveur occupé.
Vérifiez le chemin TCP :
nc -vz redis.example.internal 6379
ping -c 5 redis.example.internal
ping n'est pas parfait car ICMP peut être bloqué alors que TCP fonctionne, mais cela peut révéler des erreurs évidentes de DNS ou de routage. nc est plus proche de ce dont le client Redis a besoin.
Si TCP se connecte mais que les commandes Redis expirent, vérifiez si Redis est occupé :
redis-cli INFO clients
redis-cli INFO stats
redis-cli INFO memory
redis-cli SLOWLOG GET 10
redis-cli LATENCY DOCTOR
Recherchez les clients bloqués, un nombre élevé de clients connectés, une mémoire proche de maxmemory, du swap sur l'hôte, des commandes lentes et des événements de latence. Une seule commande coûteuse comme KEYS *, un grand HGETALL, ou un long script Lua peut retarder des clients non liés car l'exécution des commandes Redis est largement monothread.
Vérifiez également les paramètres de délai d'attente du client. Certaines bibliothèques utilisent des valeurs par défaut courtes pour les délais d'attente de connexion ou de commande. Augmenter le délai d'attente peut réduire les faux échecs sur un réseau lent, mais cela ne devrait pas cacher une instance Redis surchargée. Si un simple PING prend des secondes depuis l'hôte de l'application, corrigez cela avant de régler les tentatives.
Problèmes de résolution de nom et de mauvais point de terminaison
Toutes les erreurs de connexion ne sont pas liées à Redis. Le DNS et la découverte de services en causent beaucoup.
Depuis l'hôte de l'application :
getent hosts redis.example.internal
nslookup redis.example.internal
Dans Kubernetes :
kubectl exec -it deploy/my-app -- sh
getent hosts redis.default.svc.cluster.local
nc -vz redis.default.svc.cluster.local 6379
Vérifiez si l'application utilise un point de terminaison de réplica en lecture, un point de terminaison sentinel, un point de terminaison de cluster, ou un point de terminaison de nœud direct. Les clients Redis Cluster ont besoin de bibliothèques compatibles avec le cluster car les clés peuvent appartenir à différents slots et les commandes peuvent recevoir des redirections. Un client non compatible avec le cluster peut se connecter avec succès puis échouer avec des erreurs MOVED ou ASK une fois qu'il envoie des commandes réelles.
Erreurs d'authentification
Les échecs d'authentification se manifestent par :
NOAUTH Authentication requiredWRONGPASS invalid username-password pairNOPERM this user has no permissions- Des exceptions d'authentification spécifiques à la bibliothèque cliente
Pour Redis 6 et plus récent, les utilisateurs ACL sont courants. Une chaîne de connexion peut nécessiter à la fois un nom d'utilisateur et un mot de passe :
redis://app-user:[email protected]:6379/0
Avec l'utilisateur par défaut, certains clients utilisent uniquement un mot de passe :
redis://:[email protected]:6379/0
Vérifiez la configuration utilisateur active si vous avez un accès administrateur :
redis-cli ACL LIST
redis-cli ACL GETUSER app-user
NOAUTH signifie que le client ne s'est pas authentifié avant d'émettre une commande. WRONGPASS signifie que l'authentification a été tentée mais rejetée. NOPERM signifie que l'authentification a fonctionné, mais que l'utilisateur n'a pas la permission pour la commande, le modèle de clé ou le canal Pub/Sub.
Lorsque les secrets sont renouvelés, confirmez que chaque processus en cours d'exécution a réellement reçu la nouvelle valeur. Dans les plateformes de conteneurs, la mise à jour d'un objet secret ne redémarre pas toujours les pods ou processus existants. Un échec courant dans le monde réel est que la moitié de l'application utilise le nouveau mot de passe et l'autre moitié utilise encore l'ancien.
Incompatibilité TLS
Les erreurs TLS peuvent ressembler à des réinitialisations de connexion, des délais d'attente ou des erreurs de protocole illisibles.
Vérifiez le port. Les services gérés utilisent souvent des ports différents pour TLS et non-TLS Redis. Par exemple, un point de terminaison peut attendre le protocole Redis simple et un autre peut attendre TLS dès le premier octet.
Testez avec :
redis-cli --tls -h redis.example.internal -p 6380 PING
redis-cli -h redis.example.internal -p 6379 PING
Si votre organisation utilise des certificats privés, le client peut également avoir besoin d'un fichier CA :
redis-cli --tls --cacert /path/to/ca.pem -h redis.example.internal -p 6380 PING
Dans les journaux d'application, les erreurs de certificat sont souvent plus claires que l'exception Redis de niveau supérieur. Recherchez des messages concernant des autorités inconnues, des certificats expirés, une non-concordance du nom d'hôte ou un échec de négociation.
Trop de connexions
Redis a une limite maxclients. Le système d'exploitation a également des limites de descripteurs de fichiers. Lorsque l'une ou l'autre est épuisée, de nouveaux clients peuvent échouer ou les clients existants peuvent se comporter mal.
Vérifiez :
redis-cli INFO clients
redis-cli CONFIG GET maxclients
ulimit -n
Les champs utiles incluent connected_clients, blocked_clients, et rejected_connections de INFO stats.
Trop de connexions provient généralement de l'un de ces modèles :
- Créer un nouveau client Redis par requête web.
- Ne pas fermer les clients dans des tâches de courte durée.
- Trop de processus de travail, chacun avec son propre grand pool.
- Les abonnements Pub/Sub empruntant des connexions à un pool de commandes normal.
- Tempêtes de tentatives lors d'un redémarrage Redis.
Corrigez la forme de l'application avant d'augmenter les limites. Utilisez un client partagé ou un pool limité par processus. Ajoutez un backoff de reconnexion avec gigue pour que toutes les instances ne se reconnectent pas à la même milliseconde après une panne.
Mode protégé et paramètres de liaison
Le mode protégé de Redis est conçu pour réduire les dommages causés par une exposition accidentelle. Si Redis est lié largement et n'a pas d'authentification, le mode protégé peut rejeter les connexions distantes.
Vérifiez :
redis-cli CONFIG GET protected-mode
redis-cli CONFIG GET bind
redis-cli CONFIG GET requirepass
Ne désactivez pas le mode protégé simplement pour faire fonctionner une connexion distante. Le chemin le plus sûr est généralement le réseau privé plus l'authentification et une adresse de liaison étroite. Si Redis doit accepter des clients distants, placez-le sur un sous-réseau privé, restreignez les IP sources, exigez des identifiants et utilisez TLS lorsque c'est approprié.
Un ordre pratique des opérations
Lorsqu'une application ne peut pas se connecter, utilisez cette séquence :
- Depuis l'environnement de l'application, exécutez
redis-cli PINGcontre le même hôte et port. - Si refusé, vérifiez le processus Redis, l'écouteur, la liaison, le port et le mappage du conteneur.
- Si délai d'attente, vérifiez le routage, les règles de pare-feu, la charge du serveur, les commandes lentes et les paramètres de délai d'attente du client.
- Si l'authentification échoue, vérifiez le nom d'utilisateur, le mot de passe, les permissions ACL et le déploiement des secrets.
- Si seulement certaines commandes échouent, vérifiez les permissions de commande/clé ACL et les redirections Redis Cluster.
- Si les échecs se produisent sous charge, vérifiez les nombres de connexions, la taille du pool, les tentatives et les métriques de ressources du serveur.
Le dépannage des connexions est principalement une collecte de preuves. Obtenez un résultat CLI propre depuis le même endroit que l'application, puis comparez-le avec ce que fait la bibliothèque cliente. Une fois que ces deux chemins diffèrent, l'écart est généralement visible : un drapeau TLS manquant, un ancien mot de passe, un mauvais nom de service, ou un pool qui crée beaucoup plus de connexions que Redis n'a été dimensionné pour gérer.
Lire les erreurs d'application sans réagir de manière excessive
Les bibliothèques clientes encapsulent les erreurs Redis dans leur propre langage. Un service Node.js peut afficher ECONNRESET, un worker Python peut afficher redis.exceptions.ConnectionError, et un service Java peut signaler un délai d'attente d'acquisition de pool. Ceux-ci peuvent tous décrire différentes couches du même problème.
Séparez-les :
- Délai d'attente de connexion : la connexion TCP ne s'est pas terminée assez rapidement.
- Délai d'attente de lecture : la connexion existe, mais une réponse de commande n'est pas arrivée à temps.
- Réinitialisation de connexion : la connexion a été fermée par Redis, un proxy, le réseau ou le pair.
- Délai d'attente de pool : l'application n'a pas pu emprunter une connexion Redis à son propre pool.
- Erreur d'authentification : Redis a rejeté les identifiants ou les permissions.
Un délai d'attente de pool est facile à interpréter à tort comme une panne Redis. Parfois Redis va bien, mais l'application a emprunté toutes les connexions du pool et ne les a jamais rendues. Une mauvaise utilisation de Pub/Sub peut en être la cause. Ainsi que des commandes bloquantes longues, des gestionnaires de requêtes qui oublient de fermer les clients, ou un pool trop petit pour la concurrence du processus.
Vérifiez les deux côtés en même temps. Dans l'application, inspectez les métriques du pool si la bibliothèque les expose : connexions actives, connexions inactives, attentes, nombre de tentatives. Dans Redis, vérifiez :
redis-cli INFO clients
redis-cli CLIENT LIST | head
Si Redis n'affiche qu'une poignée de clients mais que l'application dit que son pool est épuisé, le problème est probablement à l'intérieur du processus de l'application. Si Redis affiche des milliers de connexions depuis le même déploiement, le service peut créer des clients trop souvent.
Les tentatives méritent une attention particulière. Une boucle de reconnexion sans backoff peut transformer un court redémarrage Redis en tempête. Chaque instance d'application essaie de se reconnecter immédiatement, les négociations d'authentification et TLS grimpent, et Redis doit récupérer tout en étant bombardé par les clients. Utilisez un backoff exponentiel avec gigue. Décidez également quelles commandes sont sûres à réessayer. Réessayer un GET de cache idempotent est différent de réessayer une écriture qui a peut-être déjà réussi avant la chute de la connexion.
Pour les notes d'incident, capturez le texte exact de l'erreur et le timing. "Redis était en panne" est souvent faux. "De 14:03 à 14:06 UTC, les pods de l'application ont vu des délais d'attente de lecture alors que le CPU Redis était à un cœur et que SLOWLOG montrait de grands appels HGETALL" est exploitable.