Pourquoi Redis utilise-t-il beaucoup de CPU ? Techniques de débogage et d'optimisation
Redis, réputé pour ses performances ultra-rapides en mémoire, est un composant essentiel pour la mise en cache, la gestion des sessions et le traitement des données en temps réel. Cependant, lorsque votre instance Redis connaît une augmentation soudaine de l'utilisation du CPU, les performances peuvent se dégrader rapidement, impactant toutes les applications qui en dépendent. Comprendre la cause de ce phénomène est la première étape vers la résolution. Ce guide explore en détail les causes courantes d'une forte utilisation du CPU par Redis — des commandes inefficaces aux opérations d'E/S en arrière-plan — et fournit des techniques de débogage et d'optimisation concrètes pour rétablir immédiatement la santé du système.
Comprendre l'architecture de Redis et la charge CPU
Redis fonctionne principalement comme une application mono-thread pour la gestion des commandes principales. Cela signifie que la majorité des opérations s'exécutent séquentiellement sur un seul cœur de CPU. Une utilisation élevée du CPU indique donc souvent que ce thread unique est surchargé, ou que des processus d'arrière-plan (tels que la persistance ou les E/S réseau) consomment des ressources importantes.
Facteurs clés influençant la charge CPU de Redis
- Temps d'exécution des commandes : Les commandes complexes ou gourmandes en ressources bloquent le thread principal.
- Opérations de persistance : La sauvegarde des données sur disque (RDB ou AOF) peut entraîner des pics temporaires de CPU et de la latence.
- Charge réseau : Un trafic élevé ou un comportement client inefficace peuvent mettre à rude épreuve les capacités de gestion des E/S.
- Surcharge des structures de données : Les opérations effectuées sur de très grandes structures de données.
Débogage de l'utilisation élevée du CPU
Avant d'optimiser, vous devez identifier avec précision la source de la charge. Les outils de surveillance et les commandes Redis intégrées sont essentiels pour le diagnostic.
1. Utilisation des commandes INFO et LATENCY
La commande INFO fournit un instantané de l'état du serveur. Concentrez-vous sur la section CPU et les statistiques des commandes.
redis-cli INFO cpu
Recherchez des valeurs élevées dans des métriques telles que used_cpu_sys et used_cpu_user. Un used_cpu_user élevé indique souvent un traitement intensif des commandes, tandis qu'un used_cpu_sys élevé peut signaler des interactions avec le noyau, fréquemment liées aux E/S ou à la gestion de la mémoire.
La commande LATENCY peut identifier les commandes provoquant des pics de latence constants.
redis-cli LATENCY HISTORY command
2. Identification des commandes lentes avec SLOWLOG
Le Slow Log de Redis enregistre les commandes qui dépassent un temps d'exécution spécifié. C'est votre outil le plus direct pour trouver les opérations peu performantes.
Configuration : Assurez-vous que slowlog-log-slower-than (microsecondes) et slowlog-max-len sont configurés de manière appropriée dans votre fichier redis.conf ou dynamiquement via CONFIG SET.
Exemple de configuration :
# Enregistrer les commandes prenant plus de 1000 microsecondes (1ms)
SLOWLOG-LOG-SLOWER-THAN 1000
SLOWLOG-MAX-LEN 1024
Récupération du journal :
redis-cli SLOWLOG GET 10
Examinez la sortie pour voir quelles commandes (par exemple, KEYS, de grands HGETALL, ou des scripts Lua complexes) dominent le temps d'exécution.
3. Surveillance du réseau et de l'activité des clients
Utilisez la commande MONITOR avec prudence (elle génère une surcharge importante) ou fiez-vous à des outils externes/de surveillance du système d'exploitation (netstat, ss) pour vérifier le nombre de connexions actives et le débit total du réseau. Une augmentation soudaine des connexions ou des commandes par seconde peut submerger le thread unique.
Causes courantes et stratégies d'optimisation
Une fois que vous avez identifié les commandes ou processus problématiques, appliquez des techniques d'optimisation ciblées.
1. Élimination des commandes bloquantes
La source principale des pics de CPU dans un modèle mono-thread est constituée par les opérations bloquantes. N'utilisez jamais de commandes qui balayent l'intégralité du jeu de données sur un système de production.
| Commande Inefficace | Pourquoi elle cause une utilisation élevée du CPU | Optimisation / Alternative |
|---|---|---|
KEYS * |
Balaye tout l'espace de clés. O(N). | Utilisez SCAN de manière itérative ou restructurez l'accès aux données. |
FLUSHALL / FLUSHDB |
Supprime toutes les clés. | Utilisez la suppression explicite ou UNLINK (suppression non bloquante) pour les grandes clés. |
HGETALL, SMEMBERS (sur de très grands ensembles) |
Récupère et sérialise l'intégralité de la structure en mémoire. | Utilisez HSCAN, SSCAN ou divisez les grandes structures en clés plus petites. |
Meilleure pratique : Utilisez UNLINK au lieu de DEL pour les très grandes clés. DEL bloque le thread principal pendant la suppression de la clé. UNLINK effectue la suppression réelle en arrière-plan de manière asynchrone, réduisant considérablement les pics de charge CPU lors de l'éviction de grandes clés.
# Au lieu de DEL large_key
UNLINK large_key
2. Optimisation de la persistance (RDB et AOF)
Les opérations de sauvegarde en arrière-plan déclenchent l'utilisation de la commande BGSAVE, qui utilise le mécanisme fork() du système d'exploitation. Sur les systèmes avec de grands ensembles de données, fork() peut être intensif en CPU et en temps, provoquant une charge brève mais significative.
- Instantanés RDB : Si vous sauvegardez fréquemment (par exemple, toutes les minutes), les appels
fork()répétés entraîneront des pics de CPU récurrents. Réduisez la fréquence des sauvegardes automatiques. - Réécriture AOF : La réécriture AOF (
BGREWRITEAOF) est également gourmande en ressources. Redis tente de l'optimiser en effectuant des E/S minimales, mais l'utilisation du CPU augmentera pendant le processus.
Conseil d'optimisation : Si vous rencontrez une latence inacceptable pendant la persistance, envisagez d'ajuster les intervalles de save ou de suspendre brièvement la persistance pendant les heures de pointe, bien que cela augmente le risque de perte de données.
3. Gestion de la fragmentation de la mémoire et de l'échange (Swapping)
Bien que les problèmes de mémoire soient souvent associés à une utilisation élevée de la mémoire, une fragmentation sévère de la mémoire ou, pire, le début de l'échange des données Redis vers le disque par le système d'exploitation (thrashing) augmentera considérablement l'utilisation du CPU à mesure que le noyau lutte pour gérer la mémoire.
- Vérification de l'échange : Utilisez des outils du système d'exploitation (
vmstat,top) pour vérifier si le système échange activement des pages de mémoire appartenant au processus Redis. - Ratio de fragmentation de la mémoire : Vérifiez le
mem_fragmentation_ratiodans la sortie deINFO memory. Un ratio significativement supérieur à 1,0 suggère une fragmentation élevée, ce qui peut augmenter la charge CPU pendant l'allocation/désallocation de mémoire.
Si l'échange se produit, la solution est toujours de réduire la taille de l'ensemble de données ou d'ajouter plus de RAM physique, car Redis n'est pas conçu pour fonctionner efficacement lorsque la mémoire est échangée (swapped).
4. Optimisation du réseau et du Pipelining
Si la charge CPU est directement corrélée à un débit élevé de commandes, la latence peut être causée par la surcharge de nombreux allers-retours réseau.
Pipelining (Pipeline) : Au lieu d'envoyer 100 commandes SET individuelles, regroupez-les dans un seul bloc de commandes en utilisant le pipelining via votre bibliothèque cliente. Cela réduit la latence du réseau et la surcharge par commande traitée par le thread unique de Redis, conduisant à une meilleure efficacité globale du CPU pour les opérations de masse.
Meilleures pratiques pour des performances durables
Pour prévenir les futurs pics de CPU, adoptez ces meilleures pratiques d'architecture et de configuration :
- Utilisation de la suppression asynchrone : Préférez toujours
UNLINKàDELpour les clés susceptibles d'être volumineuses. - N'utilisez jamais
KEYS: UtilisezSCANpour la découverte de clés dans les environnements de production. - Surveiller le comportement des clients : Assurez-vous que les développeurs d'applications comprennent les implications de complexité des commandes Redis qu'ils utilisent.
- Régler la fréquence de persistance : Ajustez les points de sauvegarde RDB pour éviter qu'ils ne se chevauchent avec les heures de pointe du trafic, ou fiez-vous davantage à AOF si les
forksRDB sont le principal coupable. - Mise à l'échelle verticale (si nécessaire) : Si un cœur est constamment saturé malgré les optimisations, considérez de fragmenter l'ensemble de données sur plusieurs instances Redis (en utilisant Redis Cluster ou le sharding côté client).
Conclusion
L'utilisation élevée du CPU dans Redis est rarement un mystère ; c'est généralement le symptôme d'une boucle d'événements mono-thread surchargée par des commandes inefficaces ou une persistance excessive en arrière-plan. En utilisant méthodiquement SLOWLOG, en éliminant les commandes bloquantes comme KEYS, et en ajustant les paramètres de persistance, vous pouvez diagnostiquer et résoudre efficacement la cause profonde, garantissant que votre instance Redis maintient ses performances élevées caractéristiques.