GH GambleHub

Architecture de cache : Redis, Memcached

Architecture de cache : Redis, Memcached

1) Quand et pourquoi kesh

Objectifs : réduire la latence, décharger les DB/PSP/API externes et atténuer les pics.
Les couches de cache sont souvent multi-niveaux : in-process (L1) → service-level (Redis/Memcached L2) → edge/CDN. Le cache interne accélère les lectures « chaudes », L2 - commun aux services, edge - pour le contenu public.

2) Redis vs Memcached - brièvement

CritèreRedisMemcached
Types de donnéesChaînes, hachages, listes, multiples, zset, bitmap, HyperLogLog, Streams, Bloom/CF (via les modules)Clé-valeur (lignes)
La persévéranceAOF/RDB, no-fsync-loss lors de la configurationNon
ClusterRedis Cluster (sharding, failover )/SentinelleShard client, sans failover natif
Transactions/scriptsMULTI/EXEC, EVAL (Lua), opérations atomiquesNon
TTL/evictionRéglage fin des stratégiesDe base
Latence/mémoireUn peu plus d'overheadTrès léger, prévisible

Règle : si vous avez besoin de structures de données complexes, de la persévérance, pub/sub/scripts - prenez Redis. Si super simple, rapide, bon marché KV-cache-couche sans durabilité - Memcached.

3) Modèles de cache

3. 1 Cache-aside (lazy)

L'application lit de la cache → les défauts → lit de l'OBD → met dans la cache avec la TTL.

Contrôle TTL simple, indépendance du cache. − Une « tempête » est possible en cas de défauts.

3. 2 Read-through

Le client/proxy lui-même tire de l'origin en cas d'échec et le met dans le cache.

Logique centralisée : − Plus complexe sur le plan des infrastructures.

3. 3 Write-through / Write-behind

Write-through : écrire d'abord dans le cache, puis dans la base de données.
Write-behind : entrée en file d'attente, flash asynchrone dans la base de données (perte potentielle lors de la peinture - vous avez besoin d'un journal).

3. 4 Two-tier (L1+L2)

L1 (in-process) avec TTL court et soft TTL, L2 (Redis/Memcached) - « vérité de cache ». Invalidité par pub/sub.

4) TTL, tempêtes et consistance

TTL : placez-le près de la fréquence de changement des données. Pour les clés chaudes, utilisez la randomisation TTL (jitter) : 'ttl = base ± rand (0.. base0. 1) "- supprime les expirations synchrones.

Dogpile (thundering herd) : protéger les défauts :
  • Singleflight : un seul processus transforme la valeur (voir exemple Lua).
  • Soft-TTL + arrière-plan refresh : après 'soft _ ttl', donnez l'obsolète (stale) et mettez à jour l'arrière-plan.
  • Semaphore/lock: `SET key:lock value NX PX=2000`.
  • Near-stale : 'stale-while-revalidate'pour l'API des réponses (voir section 8).

5) Clés, neumspace, sérialisation

5. 1 Nommage des clés

Modèle : '{domain} : {entity} : {id} : {field}'

Exemples :
  • `user:profile:42` `catalog:product:1001:v2` `psp:rates:2025-11-03`

Ajoutez une version du schéma (': v2'), ce qui facilite l'invalidité de masse.

5. 2 Neimspace via la « version de l'espace »

Gardez la clé 'ns : catalogue = 17'. Clés réelles : 'bou : 17 : product : 1001'. Pour un catalogue global invalide, il suffit d'incrémenter 'ns : catalogue'.

5. 3 Sérialisation/compression

JSON - confortable, mais lourd. Utilisez MessagePack/CBOR.
Allumez la compression (LZ4/ZSTD) pour les gros payload (> 1-2 KB). Chez Redis, c'est du côté du client.

6) Clés chaudes et Chardonnages

Hot-keys : surveillez le top-N par hit/miss/byte. Pour les clés extrêmement chaudes :
  • Replicated read pattern : dupliquez la valeur dans plusieurs clés shard 'hot : k : 1.. N', choisissez aléatoire lors de la lecture.
  • Local L1 : Gardez en mémoire le processus avec un abonnement handicap.
Chardonnages :
  • Redis Cluster est natif (16384 machines à sous hash).
  • Memcached est un hachage de consistance client.
  • Hash-tag dans Redis '{...}' fixe un slot pour le jeu de clés : 'user : {42} : profile' et 'user : {42} : limit'se trouveront sur la même boule.

7) Politiques de déplacement et dimensions

Redis `maxmemory-policy`: `allkeys-lru`, `volatile-lru`, `allkeys-lfu`, `noeviction` и т. д. Pour le kesh, habituellement 'allkeys-lru '/' allkeys-lfu'.
Memcached — LRU на item-slab.
Taille de la clé et valeur : regardez max item size (Memcached par défaut 1 Mo, tuning slab).
L'excès de mémoire doit se dégrader de manière prévisible : pas « noevision » sur le chemin actif.

Redis config (fragment) :

maxmemory 32gb maxmemory-policy allkeys-lfu hz 50 tcp-keepalive 60

8) Modèles de protection contre les tempêtes - code

8. 1 Redis Lua singleflight (pseudo)

lua
-- KEYS[1] = data_key, KEYS[2] = lock_key
-- ARGV[1] = now_ms, ARGV[2] = soft_ttl_ms, ARGV[3] = hard_ttl_ms, ARGV[4] = lock_ttl_ms local payload = redis. call("GET", KEYS[1])
if payload then local meta = redis. call("HGETALL", KEYS[1].. ":meta")
local last = tonumber(meta[2] or "0")
if tonumber(ARGV[1]) - last < tonumber(ARGV[2]) then return { "HIT", payload }
end if redis. call ("SET," KEYS [2], "1," "NX," "PX," ARGV [4]) then return {"REFRESH," payload} - one worker updates, the rest give stale end return {"STALE," payload}
end if redis. call("SET", KEYS[2], "1", "NX", "PX", ARGV[4]) then return { "MISS", nil }
end return { "BUSY", nil }

8. 2 Node. js cache-aside (simplifié)

js const v = await redis. get(key);
if (v) return decode(v);
const lock = await redis. setNX(key+":lock", "1", { PX: 1500 });
if (lock) {
const fresh = await loadFromDB(id);
await redis. set(key, encode(fresh), { EX: ttl, NX: false });
await redis. del(key+":lock");
return fresh;
} else {
await sleep(60);           // short backoff const retry = await redis. get (key) ;//give someone's already filled return decode (retry);
}

9) Handicap et cohérence

Par événement : si vous changez de base de données, publiez 'pub/sub' événement 'invalidate : {ns} : {id}' → les abonnés suppriment les clés.
Par minuterie : TTL court pour les données changeant souvent.
Versioning : voir 'ns :' clés.
Outbox : garantie de livraison de handicaps (événement en log/top, retrai).
Idempotence des opérations de cache : utilisez 'SETXX/SETNX', la version ('etag') et les champs de hachage pour incrémenter.

10) Réplication, cluster, failover

10. 1 Redis

Sentinelle : failover automatique master-replica (stateFUL IP/nom).
Cluster : Chardonnage + failover automatique ; les clients doivent maintenir le redirect 'MOVED/ASK'.
AOF/RDB : pour un cache généralement 'appendfsync everysec', vous pouvez sans persévérance (comme un cache pur).

10. 2 Memcached

Pas de réplication de la boîte. La fiabilité est à travers un shard multifaisceaux + répétition 'n' (client-side).
En cas de chute, le nod est une augmentation des erreurs et un « réapprentissage » de la cache.

10. 3 aspects K8s et réseaux

Redis/Memcached n'aiment pas la surenchère fréquente des pod's ; Utilisez StatefulSet + antipodes AZ fixes PVC/POD IP.
Mettez PodDissolutionBudget et TopologySpreadConstraints.

11) Transactions, scripts et atomicité (Redis)

INCR/DECR, HINCRBY - compteurs, quotas, taux-limites (ne tenez compte que de la persiste).
MULTI/EXEC est un paquet de commandes atomiques.
Lua (EVAL) - read-modify-write sans course.
Pipeline - Réduit la RTT (en particulier dans les réseaux hop).

Exemple de rate-limit (token bucket, simplifié) :
lua
-- KEYS[1]=bucket, ARGV[1]=capacity, ARGV[2]=refill_rate_per_sec, ARGV[3]=now_ms
-- Returns 1 if the token is issued, otherwise 0

12) Files d'attente, pub/sub et Streams (Redis)

Pub/Sub : handicap, signaux. Pas de sauvegarde, seulement les auditeurs en ligne.
Streams : files d'événements avec confirmation (ACK), groupes de consommateurs, rétroactions - pratique pour write-behind/fan-out.
Listes ('BRPOP') : files d'attente simples.
Ne pas utiliser Redis comme « un seul pneu de tout » sans backup est un cache/pneu rapide, pas un Kafka.

13) Sécurité et accès

Isolation réseau/VPC, mTLS au niveau ingress, ACL/mots de passe (« requirepass »/ACL dans Redis 6 +).
Disable dangerous commandes dans Redis (BOU, FLUSHALL, KEYS) via ACL.
Pour Memcached, ne pas écouter les interfaces publiques, '-U 0' (sans UDP), seulement les réseaux privés.
Ne pas stocker de PII ; si nécessaire, un court cryptage TTL + au niveau de l'application.

14) Observation et entretien

Mesures clés :
  • Hit ratio/Miss ratio (par namespace/route).
  • Latinity p95/p99 commandes 'GET/SET/MGET', timeouts.
  • Evictions и OOM errors.
  • Replication lag (Redis), cluster state, migrate/rehash events.
  • Top-N keys par trafic/octets (sampling).
  • Logs : commandes lentes ('slowlog'), erreurs de réseau.
  • Dashboards : général (CPU/RAM/connexions), équipes, slots de cluster, sentinelles, en passant par Prometheus-exportateurs.

15) Configi et déploiement - exemples

15. 1 Redis Sentinel (fragment)


port 6379 protected-mode yes appendonly yes appendfsync everysec maxmemory-policy allkeys-lfu
`sentinel. conf`:

sentinel monitor m1 10. 0. 0. 11 6379 2 sentinel auth-pass m1 sentinel down-after-milliseconds m1 5000 sentinel failover-timeout m1 60000

15. 2 Redis Cluster (valeur helm, simplifiée)

yaml cluster:
enabled: true nodes: 6  # 3 masters + 3 replicas persistence:
size: 100Gi resources:
requests: { cpu: "500m", memory: "2Gi" }

15. 3 Memcached (deployment)

yaml containers:
- image: memcached:1. 6 args: ["-m", "32768", "-I", "2m", "-v", "-t", "8", "-o", "modern"]
ports: [{ containerPort: 11211 }]

15. 4 NGINX en tant que proxy read-through (boucle API)

nginx proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=api:100m max_size=10g inactive=10m;
map $request_uri $cache_key { default "api:$request_uri"; }
location /api/ {
proxy_cache api;
proxy_cache_valid 200 1m;
proxy_cache_use_stale updating error timeout http_500 http_502 http_503 http_504;
proxy_cache_lock on;      # singleflight на уровне NGINX proxy_cache_key $cache_key;
proxy_pass http://backend;
}

16) Tests et gates

Profils de charge « cache froid/chaud/chaud ».
Injection de défauts (purge massivement) - l'origin doit résister à un « réapprentissage ».
Alertie : chute spectaculaire du hit-ratio, croissance de la miss latency, avalanche d'evictions, croissance des timeouts.

17) Anti-modèles

Gardez la « vérité » dans Redis sans AOF/RDB et sans réservation.
TTL = 0 (indéfiniment) pour les données volatiles → la non-consistance perpétuelle.
"KEYs'en vrac.
L'absence de jitter/soft-TTL → les expirations synchrones et les tempêtes.
Une instance sur toutes les commandes sans chardage/répliques.
Utiliser Memcached pour les tâches nécessitant de l'atomicité/des scripts.

18) Chèque de mise en œuvre (0-45 jours)

0-10 jours

Sélectionnez un modèle (cache-aside + L1/L2), décrivez les clés, TTL, neimspace.
Activer jitter/soft-TTL, singleflight ; alertes de base/dashboards.
Pour Redis - configurer ACL, protected-mode, slowlog, maxmemory-policy.

11-25 jours

Aller au chardage (Redis Cluster ou hachage client), répliques.
Invalidation par pub/sub ou version de neimspace ; outbox en DB.
Tests de charge de « réapprentissage » de la cache ; limiting origin.

26-45 jours

Auto promo/TTL Canaries, échauffement avant la sortie.
Streams pour write-behind/backup.
Rapports hebdomadaires sur hit-ratio, clés supérieures, coût de la mémoire.

19) Métriques de maturité

Hit-ratio L2 ≥ 80 % (statistiques sur les itinéraires/neimspace).
P95 GET <2-3 ms (in-DC), omissions <SLO origin.
0 tempête en cas d'invalidité massive (prouvée par des tests).
Invalidation et versionation automatiques des neumspaces.
Le chardage/réplication couvre une défaillance de 1 nœud sans dégradation notable.

20) Conclusion

L'architecture forte de la cache est la discipline des clés et de la TTL, la protection contre les tempêtes, le chardon correct et le déplacement prévisible. Redis donne une riche sémantique, une pureté et une atomicité ; Memcached - un maximum de simplicité et de vitesse. Ajoutez l'observabilité, le handicap par événements, L1 + L2, et le cache deviendra un accélérateur de plateforme et non une source de chutes aléatoires et de bugs « mystiques ».

Contact

Prendre contact

Contactez-nous pour toute question ou demande d’assistance.Nous sommes toujours prêts à vous aider !

Telegram
@Gamble_GC
Commencer l’intégration

L’Email est obligatoire. Telegram ou WhatsApp — optionnels.

Votre nom optionnel
Email optionnel
Objet optionnel
Message optionnel
Telegram optionnel
@
Si vous indiquez Telegram — nous vous répondrons aussi là-bas.
WhatsApp optionnel
Format : +code pays et numéro (ex. +33XXXXXXXXX).

En cliquant sur ce bouton, vous acceptez le traitement de vos données.