Aller au contenu

Mode cluster ElastiCache vs groupe de réplication — quelle topologie Redis convient à une charge SaaS

Le mode cluster fragmente les données entre plusieurs primaires pour dépasser la mémoire d'un nœud; le groupe de réplication offre des réplicas en lecture et un keyspace unique. Le choix change votre bibliothèque cliente, la conception des clés et le mode de défaillance.

Une application SaaS approche 60 Go de données de session et de réponses calculées en cache sur un cache.r6g.xlarge (26 Go utilisables). Le réflexe naturel est « passer plus gros » — cache.r6g.4xlarge libère 105 Go. Mais l’équipe veut aussi répartir le trafic de lecture et survivre à une panne d’AZ. L’architecte propose le mode cluster. Les services PHP et Node parlent tous deux à Redis. Node utilise ioredis. PHP utilise phpredis. L’un fonctionnera très bien en mode cluster après un changement de configuration. L’autre exigera une refonte. Choisir la mauvaise topologie transforme une décision de capacité en migration de six semaines.

Ce qui se passe

ElastiCache pour Redis offre deux topologies distinctes, et AWS les nomme de manière confuse.

Groupe de réplication (mode cluster désactivé). Un seul nœud primaire gère toutes les écritures. Jusqu’à cinq réplicas en lecture servent les lectures. La taille totale du dataset est bornée par la mémoire du primaire. Le cluster possède un seul keyspace Redis — chaque clé vit sur un nœud et n’importe quel client peut émettre n’importe quelle commande sans penser au routage. Les commandes multi-clés (MGET, MSET, EVAL entre clés) fonctionnent normalement. Pub/sub fonctionne normalement. Les transactions (MULTI/EXEC) fonctionnent normalement.

Mode cluster activé. Jusqu’à 500 fragments (shards), chaque fragment étant un primaire avec des réplicas optionnels. Le keyspace est divisé entre fragments selon le hash CRC16 de la clé — une clé préfixée {tenant42}: atterrit toujours sur le fragment responsable du hash de tenant42. Le dataset total peut atteindre des centaines de Go ou des To. Le piège : toute opération multi-clés doit utiliser des clés qui hashent vers le même slot, sinon elle échoue avec CROSSSLOT. Certains clients comprennent nativement la topologie cluster; d’autres exigent des mises à niveau explicites ou des wrappers.

La matrice de décision :

FacteurGroupe de réplicationMode cluster
Working set tient dans la mémoire d’un nœudBon choixExcessif
Working set dépasse ~100 GoMur à venirBon choix
Beaucoup de MGET/MSET entre clés non liéesFonctionne tel quelRéécriture avec hash tags requise
MULTI/EXEC entre clésFonctionne tel quelHash tags requis
Scripts Lua entre clésFonctionne tel quelHash tags requis
Pub/sub entre tous les abonnésFonctionne tel quelLes abonnés ne voient pas tous une publication
Réplicas en lecture pour mise à l’échelleJusqu’à 5 réplicasRéplicas par fragment
Bibliothèque cliente : ioredisFonctionneFonctionne avec new Redis.Cluster([...])
Bibliothèque cliente : lettuce (Java)FonctionneFonctionne avec RedisClusterClient
Bibliothèque cliente : Jedis (Java)FonctionneExige JedisCluster (surface d’API différente)
Bibliothèque cliente : phpredisFonctionneFonctionne avec la classe RedisCluster (constructeur différent, pas de MULTI entre clés)
Bibliothèque cliente : redis-pyFonctionneExigeait historiquement redis-py-cluster, natif dans les versions récentes
Panne d’un nœudPromotion d’un réplica; panne d’AZ survivableFailover par fragment; panne inter-fragments limitée aux slots concernés

Les deux topologies ne sont pas interchangeables au niveau applicatif. Migrer d’un groupe de réplication vers le mode cluster signifie au minimum changer la construction du client, et souvent réécrire tout code effectuant des opérations multi-clés.

Comment vérifier

Examinez trois choses avant de choisir.

Plafond mémoire. Vérifiez la taille du working set, pas du dataset. Le working set est ce qui reste chaud — sessions touchées dans les 30 derniers jours, réponses calculées avec un TTL de 24 heures. Un cache.r6g.xlarge a 26,32 Go utilisables. Un cache.r6g.4xlarge a 105,81 Go. Un cache.r6g.16xlarge a 419,09 Go. Si le working set est sous 100 Go et ne croît pas rapidement, un groupe de réplication à un seul fragment est plus simple et presque toujours correct.

aws elasticache describe-cache-clusters \
  --show-cache-node-info \
  --query 'CacheClusters[].[CacheClusterId,CacheNodeType,Engine]' \
  --output table

Puis vérifiez l’usage mémoire réel via CloudWatch :

aws cloudwatch get-metric-statistics \
  --namespace AWS/ElastiCache \
  --metric-name BytesUsedForCache \
  --dimensions Name=CacheClusterId,Value=saas-prod-001 \
  --start-time $(date -u -v-7d +%Y-%m-%dT%H:%M:%S) \
  --end-time   $(date -u +%Y-%m-%dT%H:%M:%S) \
  --period 3600 \
  --statistics Maximum \
  --query 'Datapoints[].Maximum' \
  --output text | sort -n | tail -1

Si le maximum approche maxmemory (typiquement 75–80 % de la mémoire du nœud avant que l’éviction démarre), le nœud est plein.

Inventaire des bibliothèques clientes. Listez chaque service qui parle à Redis. Pour chacun, identifiez la bibliothèque et la version. Le mode cluster exige le constructeur cluster-aware dans la plupart des bibliothèques. Certaines bibliothèques se dégradent silencieusement en comportement non-cluster et manquent les redirections — un bogue qui apparaît sur 2 % des requêtes lors d’un rééquilibrage de fragments, pas sous charge normale.

Audit de l’usage des commandes. Cherchez dans le code MGET, MSET, MULTI, EXEC, EVAL, SUNIONSTORE, ZUNIONSTORE, RENAME, BRPOPLPUSH. Si l’une de ces opérations agit sur des clés qui ne partagent pas un préfixe tenant, ces appels échoueront en mode cluster sans réécriture des clés avec hash tags.

grep -rn -E "MGET|MSET|MULTI|EXEC|EVAL|RENAME" src/ \
  | grep -v test \
  | head -30

Une surprise classique : connect-redis (magasin de sessions Node) émet un bloc MULTI/EXEC pour les écritures de session. En mode cluster cela fonctionne parce que toutes les clés du bloc partagent le slot de l’ID de session, mais seulement si la construction de clé utilise un hash tag. Si le préfixe est sess:{<sid>}:, parfait. Si c’est sess:<sid>:, la prochaine refonte causera un échec cross-slot.

La correction

La règle défendable pour choisir la topologie :

Choisissez par défaut un groupe de réplication. Un cache.r6g.xlarge avec un ou deux réplicas en lecture répartis sur des AZ couvre la vaste majorité des charges SaaS. Plus simple sur le plan opérationnel, plus simple dans le code, et tolère une panne d’AZ avec un blip de 30 secondes. Plafond mémoire ~26 Go, suffisant pour un working set de millions de sessions plus un cache de réponses décent.

Faites évoluer verticalement avant horizontalement. r6g.xlarge à r6g.2xlarge à r6g.4xlarge est un seul changement de configuration et un bref failover. Vous pouvez rester sur un groupe de réplication jusqu’à r6g.16xlarge (419 Go) — suffisant pour presque tout SaaS jusqu’à ce que vous ayez des raisons très précises de fragmenter.

Passez au mode cluster quand l’une de ces conditions est vraie.

  • Le working set dépasse ~100 Go et continue de croître.
  • Le débit d’écritures sur le primaire unique est le goulot d’étranglement (au-dessus de ~50 000 écritures/sec soutenues, selon la taille du payload).
  • Vous devez répartir les tenants entre régions ou comptes et voulez isoler par fragment selon le palier de tenant.
  • Vous utilisez Redis purement comme cache fragmenté où chaque opération est mono-clé (recherches de session par ID, par exemple) et le code utilise déjà des hash tags ou des patrons d’accès mono-clé.

Si vous passez au mode cluster, deux patrons qui paient.

Mettez un hash-tag sur chaque opération multi-clés. Réécrivez les clés de session en sess:{<sid>}:data, sess:{<sid>}:meta. Les accolades forcent les deux clés à hasher sur <sid> et à atterrir sur le même fragment. Appliquez le même patron aux caches par tenant : tenant:{<tid>}:user:123 au lieu de tenant:<tid>:user:123. Les {} font partie de la syntaxe de clé et Redis ne hash que ce qui est entre accolades.

Testez le comportement du client durant un rééquilibrage. Déclenchez un failover planifié sur un fragment et lancez une charge contre l’application. Le client doit suivre les redirections MOVED et ASK sans casser. Les bibliothèques qui n’implémentent pas la gestion des redirections feront surface comme un pic d’erreurs « clé non trouvée » durant le rééquilibrage. Attrapez ça en préproduction, pas en production.

Le résumé honnête : si vous n’êtes pas certain d’avoir besoin du mode cluster, vous n’en avez pas besoin. Un groupe de réplication mis à l’échelle verticalement sur cache.r6g.4xlarge ou cache.r6g.8xlarge exécute la plupart des charges de cache SaaS plus simplement, à coût moindre et avec moins de pièges qu’un cluster fragmenté. Le mode cluster se rentabilise quand le working set est le goulot d’étranglement, pas quand « plus de réplicas » semble une bonne idée.


Stack Harbor conçoit les topologies Redis dans le cadre du travail sur le palier cluster en Gestion AWS et de la couche Clusters HA. Si vous pesez une fragmentation contre une autre montée verticale, commencez par une consultation d’infrastructure.