Redis est bien plus qu'un simple magasin clé-valeur ; c'est un serveur de structures de données en mémoire, monothread, doté d'une persistance sur disque optionnelle et d'une réplication intégrée. Comprendre son architecture interne — comment il traite les commandes, gère la mémoire, réplique les données et bascule en cas de panne — fait la différence entre l'utiliser comme une boîte noire et l'exploiter de manière fiable à grande échelle. Ce guide relie les composants de Redis aux commandes observables, aux sorties attendues, aux signaux de défaillance et aux décisions de récupération pour les développeurs, les ingénieurs DevOps et les équipes techniques qui font tourner Redis en production.
Architecture cœur : boucle d'événements, mémoire et structures de données
Redis exécute une boucle d'événements monothread (la bibliothèque AE avant la version 6.0, io_uring/epoll/kqueue par la suite) qui multiplexe les entrées/sorties réseau, les événements temporels et l'exécution des commandes. Comme l'exécution des commandes est atomique et monothread, les commandes longues (par exemple KEYS *, FLUSHALL, scripts Lua lents) bloquent tous les autres clients. Cette conception élimine la contention des verrous, mais rend la latence prévisible seulement lorsque les commandes sont en O(1) ou O(log N).
Gestion de la mémoire : Redis alloue la mémoire via jemalloc (par défaut) ou glibc malloc. Chaque clé entraîne une surcharge : l'en-tête d'objet robj (~16–48 octets), l'en-tête SDS (Simple Dynamic String) pour le nom de la clé et l'encodage de la valeur. Les petits hachages, listes et ensembles utilisent des encodages compacts (ziplist/listpack) jusqu'à ce qu'ils dépassent hash-max-ziplist-entries (par défaut 512) ou hash-max-ziplist-value (par défaut 64 octets), après quoi ils basculent vers des tables de hachage, doublant la surcharge mémoire.
Observation pratique : lancez INFO memory et comparez used_memory_human à used_memory_rss_human. Un ratio RSS-sur-utilisé élevé (> 1,5) indique une fragmentation. Exécutez MEMORY STATS (Redis 4.0+) pour voir allocator.allocated, allocator.active et allocator.resident. Si fragmentation_ratio dépasse 1,3, envisagez un redémarrage pendant une fenêtre de maintenance ou activez activedefrag (Redis 4.0+).
Inspection des clés : utilisez MEMORY USAGE <clé> [SAMPLES <nombre>] pour mesurer l'empreinte exacte d'une clé spécifique, y compris les structures imbriquées. Pour un hachage de 10 000 champs, cela renvoie le total d'octets consommés, vous permettant de valider les transitions d'encodage.
Persistance : RDB, AOF et stratégies hybrides
Redis propose deux mécanismes de persistance, souvent utilisés conjointement.
RDB (Instantanés) : crée un processus fils qui écrit un instantané à un instant T sur disque (dump.rdb). Les directives save dans redis.conf (par exemple save 900 1, save 300 10, save 60 10000) contrôlent les conditions de déclenchement. Le RDB se charge rapidement mais perd les données entre deux instantanés.
AOF (Append-Only File) : journalise chaque opération d'écriture. La politique appendfsync détermine la durabilité :
always: fsync après chaque écriture (lent, durable).everysec: fsync une fois par seconde (par défaut, ~1 s de perte de données en cas de crash).no: délègue au système d'exploitation (rapide, risque de perte plus importante).
Hybride (RDB + AOF) : depuis Redis 4.0, aof-use-rdb-preamble yes écrit un en-tête RDB suivi des incréments AOF lors des réécritures. Cela combine un redémarrage rapide (RDB) et la durabilité (AOF).
Commandes de vérification :
# Vérifier la configuration de persistance actuelle
CONFIG GET save appendonly appendfsync aof-use-rdb-preamble
# Déclencher un RDB manuel (bloque seulement le temps du fork)
BGSAVE
# Déclencher une réécriture AOF (compacte le journal)
BGREWRITEAOF
# Surveiller le statut de la dernière sauvegarde
INFO persistence
# Chercher : rdb_last_bgsave_status:ok, aof_last_rewrite_status:ok
Signal de défaillance : rdb_last_bgsave_status:err ou aof_last_rewrite_status:err dans INFO persistence. Consultez le journal Redis pour les échecs de fork() (souvent dus aux huge pages transparentes ou à la pression mémoire) ou aux erreurs d'E/S disque.
Récupération : si l'AOF est corrompu, redis-check-aof --fix appendonly.aof peut le tronquer à la dernière commande valide. Pour le RDB, redis-check-rdb dump.rdb valide l'intégrité. Testez toujours les restaurations sur une instance de préproduction avant la production.
Réplication et haute disponibilité : Sentinel et Cluster
Réplication maître-réplique : asynchrone par défaut. Les répliques envoient PSYNC <replid> <offset> ; si l'offset se trouve dans le backlog de réplication du maître (par défaut 1 Mo, configurable via repl-backlog-size), une resynchronisation partielle a lieu. Sinon, une resynchronisation complète se déclenche : le maître fork, génère le RDB, le diffuse à la réplique, puis diffuse le backlog.
Réglages critiques : définissez repl-backlog-size assez grand pour absorber les partitions réseau (par exemple 100–500 Mo). Activez repl-diskless-sync yes (Redis 5.0+) pour diffuser le RDB directement par socket, évitant les E/S disque sur le maître lors d'une resynchronisation complète.
Sentinel (HA pour autonome/réplication) : Sentinel surveille les maîtres, promeut les répliques en cas de défaillance et notifie les clients. Nécessite un quorum (par exemple sentinel monitor monserveur 10.0.0.1 6379 2). Sentinel doit tourner sur au moins trois nœuds.
Redis Cluster (Partitionnement + HA) : 16 384 slots de hachage répartis sur les maîtres. Chaque clé correspond à un slot via CRC16(clé) % 16384. Les clients suivent les redirections MOVED/ASK. Le cluster requiert au moins trois maîtres pour le quorum. Les répliques assurent la montée en charge en lecture et servent de cibles de basculement.
Commandes d'observabilité :
# Statut de réplication
INFO replication
# Champs clés : role, master_replid, master_repl_offset, slave0..N, repl_backlog_active, repl_backlog_size
# Statut Sentinel (à lancer sur Sentinel)
SENTINEL masters
SENTINEL replicas monserveur
SENTINEL get-master-addr-by-name monserveur
# Statut Cluster
CLUSTER INFO
CLUSTER NODES
# Chercher : cluster_state:ok, slots_assigned:16384, nombre known_nodes
Modes de défaillance :
- Split-brain : deux maîtres acceptent les écritures. Prévenez avec
min-replicas-to-write 1etmin-replicas-max-lag 10sur le maître ; il cesse d'accepter les écritures si aucune réplique n'accuse réception dans les 10 secondes. - Tempêtes de resynchronisation complète : de nombreuses répliques se reconnectent simultanément et saturent la mémoire du maître. Échelonnez les redémarrages des répliques ; augmentez
repl-backlog-size; utilisez la synchronisation sans disque. - Migration de slots Cluster :
CLUSTER SETSLOT <slot> IMPORTING|MIGRATING <node-id>déplace les slots manuellement. SurveillezCLUSTER NODESpour les étatsMIGRATING/IMPORTING.
Éviction mémoire, scripts Lua et garde-fous opérationnels
Politiques d'éviction : lorsque maxmemory est atteint, Redis évince les clés selon la politique :
volatile-lru/volatile-lfu: évince parmi les clés avec TTL.allkeys-lru/allkeys-lfu: évince n'importe quelle clé.volatile-ttl: évince le TTL le plus court.noeviction: renvoie des erreurs OOM (par défaut).
Recommandation : utilisez allkeys-lfu (Redis 4.0+) pour le cache général ; il suit la fréquence et la récence d'accès. Fixez maxmemory à 70–80 % de la RAM du conteneur/VM pour laisser de la marge au copy-on-write du fork() pendant la réécriture RDB/AOF.
Scripts Lua : s'exécutent atomiquement via EVAL/EVALSHA. Les scripts bloquent la boucle d'événements ; gardez-les sous 10 ms. Utilisez SCRIPT LOAD pour mettre en cache le SHA, puis EVALSHA pour éviter de renvoyer le source. SCRIPT KILL termine un script en lecture seule dépassant lua-time-limit (par défaut 5000 ms) ; SCRIPT FLUSH vide le cache.
Garde-fous opérationnels :
- Désactiver les commandes dangereuses :
rename-command FLUSHALL "",rename-command CONFIG "",rename-command KEYS ""dansredis.conf. UtilisezSCANau lieu deKEYS. - Limites des tampons de sortie client :
client-output-buffer-limit normal 0 0 0,slave 256mb 64mb 60,pubsub 32mb 8mb 60empêchent les répliques lentes ou les consommateurs pub/sub de saturer la mémoire du maître. - Surveillance de la latence :
CONFIG SET latency-monitor-threshold 100(ms).LATENCY DOCTORetLATENCY HISTOGRAM <événement>diagnostiquent les blocages (fork, fsync, commande).
Conclusion
Exploiter Redis en toute sécurité signifie traiter sa boucle d'événements monothread, son allocateur mémoire, ses pipelines de persistance et son protocole de réplication comme des systèmes observables et réglables — et non comme des défauts opaques. La configuration selon la version (par exemple activedefrag dans 4.0+, repl-diskless-sync dans 5.0+, LFU dans 4.0+, ACLs dans 6.0+) doit correspondre à votre version déployée. Capturez des lignes de base avec INFO, MEMORY STATS, LATENCY et CLUSTER NODES avant tout changement. Validez chaque modification face à une charge de préproduction qui reflète les distributions de clés et le mélange de commandes de la production. Documentez le retour arrière exact : CONFIG REWRITE pour persister les changements à chaud, ou redémarrage avec le redis.conf précédent. Lorsque survient une défaillance — OOM, tempête de fork, split-brain, corruption AOF — le runbook est déjà écrit parce que vous avez vérifié les signaux et répété la récupération.