E-NO
Concepts avancés Redis 7 min de lecture

Redis : concepts avancés expliqués avec des exemples pratiques

calendar_today Publié : 2026-08-14
update Dernière mise à jour : 2026-08-14
analytics Efficacité SEO : 100%
Illustration du guide technique pour « Redis : concepts avancés expliqués avec des exemples pratiques ».

Redis est bien plus qu'un simple cache clé-valeur. En production, il sert de magasin de données principal, de courtier de messages, de limiteur de débit, de backend de session et de coordinateur de verrous distribués. Comprendre ses mécanismes internes avancés — gestion de la mémoire, internaux de la réplication, compromis de persistance, atomicité des scripts Lua et extensibilité par modules — sépare les équipes qui exploitent Redis en toute sécurité de celles qui subissent des pertes de données silencieuses, des pics de latence ou des défaillances en cascade lors d'incidents. Cet article parcourt chaque concept avec des commandes spécifiques aux versions, des signaux observables et des étapes de récupération vérifiées pour Redis 6.2 à 7.4.

Architecture mémoire et mécanismes d'éviction

Redis stocke toutes les données dans un dictionnaire en mémoire mono-thread. L'allocateur (jemalloc par défaut, optionnellement jemalloc, glibc ou tcmalloc) gère la fragmentation des arènes. Chaque clé entraîne une surcharge : un en-tête redisObject (16 octets sur 64 bits), une structure de chaîne SDS, une entrée de dictionnaire et des métadonnées d'expiration si un TTL est défini. Une valeur chaîne de 100 octets consomme généralement 72 à 104 octets de RSS réel selon l'encodage.

Observer la répartition de la mémoire :

redis-cli -h <hôte> -p <port> INFO memory
# Se concentrer sur : used_memory, used_memory_rss, mem_fragmentation_ratio, used_memory_lua
redis-cli -h <hôte> -p <port> MEMORY STATS
redis-cli -h <hôte> -p <port> MEMORY DOCTOR

Un mem_fragmentation_ratio supérieur à 1,5 signale une fragmentation de l'allocateur ; au-dessus de 2,0, il est souvent corrélé à des pics de latence lors du fork() pour la réécriture RDB/AOF. Atténuation : redémarrer l'instance pendant une fenêtre de maintenance, ou activer activedefrag yes (Redis 6.0+) avec active-defrag-threshold-lower 10 et active-defrag-threshold-upper 100.

Le choix de la politique d'éviction est un contrat de capacité, pas un défaut. Le configurer explicitement dans redis.conf ou à l'exécution :

redis-cli CONFIG SET maxmemory-policy allkeys-lru
# Alternatives : volatile-lru, allkeys-lfu, volatile-lfu, allkeys-random, noeviction

Vérifier avec CONFIG GET maxmemory-policy. Pour les charges de travail à accès selon une loi de puissance (ex. magasins de session), allkeys-lfu (Redis 4.0+) surpasse LRU en suivant la fréquence d'accès avec un compteur logarithmique. Pour les caches à écriture intensive avec accès uniforme, allkeys-lru reste prévisible.

Les transitions d'encodage des clés affectent la mémoire silencieusement. Un SET avec des valeurs entières utilise l'encodage intset pour les petits ensembles ; dépasser 512 entrées ou un seul élément > 64 octets promeut vers hashtable. Un HASH avec ≤ 512 champs et valeurs ≤ 64 octets utilise ziplist (Redis < 7) ou listpack (Redis 7+) ; dépasser l'un ou l'autre seuil promeut vers hashtable, multipliant la surcharge par champ. Surveiller avec :

redis-cli DEBUG OBJECT <clé>
# La sortie inclut : encoding, serializedlength, refcount

Planifier la capacité en utilisant la longueur sérialisée, non le nombre logique de clés.

Internaux de la réplication et mécanique du basculement

La réplication Redis est asynchrone par défaut. Le primaire diffuse les commandes d'écriture vers les répliques via un backlog de réplication (1 Mo par défaut, configurable via repl-backlog-size). Une réplique qui se déconnecte et se reconnecte dans la fenêtre du backlog effectue une resynchronisation partielle (PSYNC) ; sinon, elle déclenche une resynchronisation complète : le primaire fait un fork, génère un instantané RDB, le transfère, puis diffuse le backlog.

Commandes d'observabilité critiques :

redis-cli -h <réplique> INFO replication
# Champs : master_link_status, master_last_io_seconds_ago, master_sync_in_progress, replica_repl_offset
redis-cli -h <primaire> INFO replication
# Champs : connected_slaves, repl_backlog_active, repl_backlog_size, repl_backlog_first_offset, repl_backlog_histlen

Un master_link_status:down avec master_last_io_seconds_ago > repl-timeout (défaut 60 s) signifie que la réplique est déconnectée depuis plus longtemps que le délai — elle demandera une resynchronisation complète à la reconnexion. Si repl_backlog_histlen approche repl-backlog-size, augmenter le backlog (ex. 64–256 Mo pour charges à écriture intense) pour absorber les partitions réseau.

Commande WAIT pour garanties de durabilité :

redis-cli -h <primaire> SET clé valeur
redis-cli -h <primaire> WAIT 2 1000
# Retourne le nombre de répliques ayant accusé réception de l'écriture dans 1000 ms

WAIT bloque le client jusqu'à ce que le nombre spécifié de répliques accuse réception de l'offset d'écriture. Il ne garantit pas la persistance sur disque (voir AOF/fsync ci-dessous), seulement l'accusé de réception de la réplication. Utiliser pour les chemins critiques comme les clés d'idempotence de paiement.

Sentinel et le basculement Redis Cluster diffèrent fondamentalement. Sentinel (autonome) surveille les primaires, promeut une réplique après quorum (sentinel monitor mymaster <ip> <port> 2) et réécrit la configuration client via sentinel client-reconfig-script. Redis Cluster (Redis 3.0+) répartit les clés sur 16384 slots de hachage ; le basculement est interne, basé sur les slots, et requiert la majorité des maîtres. Pour Cluster, observer :

redis-cli -h <nœud> -p <port> CLUSTER INFO
redis-cli -h <nœud> -p <port> CLUSTER NODES
# Rechercher : cluster_state:ok, slots_assigned:16384, pas de fail? ou états handshake

Un CLUSTER FAILOVER sur une réplique déclenche un basculement manuel ; CLUSTER FAILOVER FORCE contourne les vérifications d'accessibilité du primaire — à utiliser uniquement lors d'une perte confirmée du primaire.

Persistance : RDB, AOF et stratégies hybrides

Les instantanés RDB sont des forks à un instant T. save 900 1, save 300 10, save 60 10000 dans redis.conf déclenchent des sauvegardes en arrière-plan après N changements en M secondes. La latence du fork évolue avec la taille du jeu de données : un jeu de 50 Go sur une VM 16 vCPU fork généralement en 200–800 ms ; sur des hôtes surengagés, 2–5 secondes. Pendant le fork, le primaire bloque toutes les écritures (défauts de page copy-on-write). Surveiller avec :

redis-cli INFO persistence
# Champs : rdb_bgsave_in_progress, rdb_last_bgsave_status, rdb_last_bgsave_time_sec, rdb_changes_since_last_save

Un rdb_last_bgsave_status:err avec errno=12 (ENOMEM) signifie que le fork a échoué à cause de la politique d'overcommit. Correction : echo 1 > /proc/sys/vm/overcommit_memory ou réduire la taille du jeu de données.

AOF (Append-Only File) journalise chaque commande d'écriture. Trois politiques fsync :

  • always : fsync après chaque écriture — durable, ~10–50 k ops/sec sur NVMe.
  • everysec (défaut) : fsync une fois par seconde — équilibre débit et durabilité ; pire cas 1 seconde de perte.
  • no : délégation à l'OS — débit maximal, perte jusqu'à 30 secondes en cas de crash.
redis-cli CONFIG SET appendfsync everysec
redis-cli CONFIG GET appendfsync

La réécriture AOF (BGREWRITEAOF) compacte le journal en rejouant le jeu de données courant en un ensemble minimal de commandes. Déclenchée automatiquement via auto-aof-rewrite-percentage 100 et auto-aof-rewrite-min-size 64mb. Surveiller la progression :

redis-cli INFO persistence
# aof_rewrite_in_progress, aof_rewrite_scheduled, aof_last_rewrite_time_sec

La persistance hybride (Redis 4.0+) combine préambule RDB et queue AOF : aof-use-rdb-preamble yes. Au redémarrage, Redis charge le préfixe RDB (rapide) puis rejoue le suffixe AOF (durable). C'est le défaut de production recommandé pour jeux de données > 10 Go. Vérifier avec :

redis-cli CONFIG GET aof-use-rdb-preamble
# Doit retourner "yes"

Test de récupération : arrêter Redis, renommer appendonly.aof en appendonly.aof.bak, redémarrer — confirmer que le jeu de données charge depuis le préambule RDB et que les écritures récentes sont présentes.

Atomicité des scripts Lua et motifs EVALSHA

Redis exécute les scripts Lua de façon atomique : aucune autre commande n'y intercède. Cela permet des motifs lecture-modification-écriture (limitation de débit, verrous distribués, mises à jour conditionnelles) sans coordination externe. Les scripts sont mis en cache par SHA1 ; EVALSHA évite de retransmettre le texte du script.

Exemple de limiteur de débit (fenêtre glissante, Redis 6.2+) :

-- KEYS[1] = clé de limite, ARGV[1] = fenêtre ms, ARGV[2] = max requêtes, ARGV[3] = maintenant ms
local key = KEYS[1]
local window = tonumber(ARGV[1])
local limit = tonumber(ARGV[2])
local now = tonumber(ARGV[3])
local start = now - window
redis.call('ZREMRANGEBYSCORE', key, '-inf', start)
local count = redis.call('ZCARD', key)
if count >= limit then
  return {0, count}
end
redis.call('ZADD', key, now, now .. '-' .. math.random())
redis.call('PEXPIRE', key, window)
return {1, count + 1}

Charger une fois :

SCRIPT LOAD "$(cat ratelimit.lua)"
# Retourne le SHA1, ex. "a1b2c3d4..."

Exécuter :

redis-cli EVALSHA a1b2c3d4... 1 ratelimit:user:123 60000 100 $(date +%s%3N)
# Retourne : 1) "1" 2) "42"  (autorisé, compteur courant)

Contraintes critiques : Les scripts doivent être purs (pas de math.random sans graine, pas de os.time, pas d'E/S externe). Temps d'exécution maximal : lua-time-limit (défaut 5000 ms). Un script lent bloque toute la boucle d'événements. Profiler avec redis-cli --eval script.lua clé arg et surveiller INFO commandstats pour les percentiles de latence evalsha.

Éviction du cache de scripts : SCRIPT FLUSH vide tous les scripts mis en cache (dangereux en production). Préférer SCRIPT EXISTS <sha1> pour vérifier, puis SCRIPT LOAD au démarrage via script d'initialisation. Pour Cluster, les scripts ne doivent accéder qu'à des clés dans le même slot de hachage — utiliser les tags de hachage : {user:123}:ratelimit et {user:123}:session routent vers le même slot.

Extensibilité par modules : RedisJSON, RediSearch et filtres de Bloom

Les modules Redis 4.0+ s'exécutent en-processus, étendant types de données et commandes. Trois modules de qualité production :

RedisJSON (v2.x) fournit un stockage natif de documents JSON avec accès par chemin :

redis-cli JSON.SET user:1001 $ '{"name":"Alice","orders":[{"id":55,"total":120},{"id":56,"total":85}]}'
redis-cli JSON.GET user:1001 $.orders[0].total
# Retourne : "120"
redis-cli JSON.NUMINCRBY user:1001 $.orders[1].total 15
# Incrémente atomiquement la valeur imbriquée

L'indexation via RediSearch permet des requêtes secondaires sur les chemins JSON.

RediSearch (v2.x) ajoute l'indexation plein texte et numérique :

redis-cli FT.CREATE idx:user ON JSON PREFIX 1 user: SCHEMA $.name AS name TEXT $.orders[*].total AS order_total NUMERIC
redis-cli FT.SEARCH idx:user "@order_total:[100 200]"
# Retourne les clés user: correspondantes avec totaux de commande dans l'intervalle

Les mises à jour d'index sont synchrones à l'écriture ; surveiller FT.INFO idx:user pour num_docs, indexing_failures, inverted_sz_mb.

RedisBloom (v2.x) fournit l'appartenance probabiliste avec taux de faux positifs configurable :

redis-cli BF.RESERVE seen:users 0.01 1000000
# taux d'erreur 1%, capacité initiale 1M
redis-cli BF.ADD seen:users "user:1001"
redis-cli BF.EXISTS seen:users "user:1001"
# Retourne 1 (peut-être) ou 0 (certainement pas)

Utiliser pour protection contre la pénétration de cache, pipelines de déduplication ou bucketing de tests A/B. La mémoire évolue avec capacité × log2(1/taux_erreur).

Chargement des modules : Ajouter à redis.conf :

loadmodule /usr/lib/redis/modules/rejson.so
loadmodule /usr/lib/redis/modules/search.so
loadmodule /usr/lib/redis/modules/redisbloom.so

Vérifier avec MODULE LIST. Les modules doivent correspondre à la version ABI de Redis ; mettre à jour les modules lors de la mise à niveau de Redis.

Liste de vérification opérationnelle

Avant tout changement de configuration ou mise à niveau de version, exécuter cette séquence :

  1. Capture de référence :
   redis-cli INFO all > baseline-$(date +%F-%H%M).txt
   redis-cli MEMORY STATS >> baseline-$(date +%F-%H%M).txt
   redis-cli --latency-history -i 1 > latency-baseline-$(date +%F-%H%M).log &
  1. Changement à portée unique : Appliquer une configuration (ex. CONFIG SET maxmemory-policy allkeys-lfu), puis vérifier :
   redis-cli CONFIG GET maxmemory-policy
   # Confirmer : "maxmemory-policy" "allkeys-lfu"
  1. Observer 2–3 cycles GC ou 10 minutes : Vérifier INFO memory pour mem_fragmentation_ratio, used_memory_peak et taux evicted_keys.
  1. Déclencheur de rollback : Si evicted_keys grimpe inattendu, latence p99 > 10 ms, ou rejected_connections > 0, revenir immédiatement :
   redis-cli CONFIG SET maxmemory-policy allkeys-lru
  1. Documenter le résultat : Consigner horodatage, commande, delta de métrique observée et décision dans le runbook.

Conclusion

Exploiter Redis à grande échelle exige de traiter chaque fonctionnalité avancée comme un contrat avec des invariants mesurables : ratio de fragmentation mémoire sous 1,5, backlog de réplication dimensionné pour la durée maximale de partition attendue, politique AOF fsync alignée sur le RPO, scripts Lua bornés à 5 ms p99, et versions de modules verrouillées à l'ABI Redis. Les commandes et étapes de vérification ci-dessus ne sont pas théoriques — ce sont la séquence exacte utilisée pour diagnostiquer un blocage de fork sur un jeu de 40 Go, récupérer une réplique bloquée en resynchronisation complète, et valider un limiteur de débit survivant à une tempête de requêtes. Commencez par une vérification : capturez INFO memory, lancez MEMORY DOCTOR, et comparez mem_fragmentation_ratio à votre référence. Cette unique observation révèle souvent la prochaine décision de capacité avant qu'elle ne devienne un incident.

Recherches connexes

Score de qualité de l’article

Utilité pour le lecteur 100%
  • check_circle Guide prêt à lire
  • check_circle Exemples pratiques inclus
  • check_circle URL d’article optimisée pour le SEO