GH GambleHub

Arhitectura caching: Redis, Memcached

Arhitectura caching: Redis, Memcached

1) Când și de ce cache

Obiective: reducerea latenței, descărcarea API DB/PSP/externe și atenuarea vârfurilor.
Straturile cache sunt adesea multilevel: în proces (L1) → service-level (Redis/Memcached L2) → edge/CDN. Memoria cache internă accelerează citirile fierbinți, L2 este comun pentru servicii, marginea este pentru conținut public.

2) Redis vs Memcached - Scurt

CriteriulRedisMemcached
Tipuri de dateȘiruri, hash-uri, liste, seturi, zset, bitmaps, HyperLogLog, fluxuri, Bloom/CF (prin module)Cheie valoare (siruri de caractere)
PersistenţăAOF/RDB, fără pierderi de fsync la configurareNu, nu este
ClusterRedis Cluster (sharding, failover )/SentinelCiobul de client, nici un eșec nativ
Tranzacții/ScripturiMULTI/Ï, EVAL (Lua), operaţii atomiceNu, nu este
TTL/evacuarePolitici de reglaj finDe bază
Latenţă/memorieCeva mai mult deasupra capuluiFoarte ușor, previzibil

Regulă: dacă aveți nevoie de structuri complexe de date, persistență, pub/sub/streams/scripts - ia Redis. În cazul în care stratul de cache KV super-simplu, rapid, ieftin, fără durabilitate este Memcached.

3) Modele de caching

3. 1 Cache-deoparte (leneș)

Aplicația citește din memoria cache → o miss → citește din baza de date → o pune în memoria cache cu TTL.

Controlul TTL simplu, independența cache. − Posibil „furtună” în caz de ratări.

3. 2 Read-through

Clientul/proxy-ul în sine trage de la origine la o ratare și o pune în memoria cache.

Logică centralizată, − infrastructură mai complexă.

3. 3 Scriere/Scriere în spate

Scrieți: scrieți mai întâi la memoria cache, apoi la baza de date.
Write-back: scrierea la coadă, flash asincron în baza de date (pierdere potențială atunci când se prăbușește - aveți nevoie de un jurnal).

3. 4 Două niveluri (L1 + L2)

L1 (în proces) cu TTL scurt și TTL moale, L2 (Redis/Memcached) - "adevărul cache. "Handicap prin pub/sub.

4) TTL, furtuni și consistență

TTL-Set aproape de frecvența schimbării datelor. Pentru tastele fierbinți, utilizați randomizarea TTL (jitter): 'ttl = base ± rand (0.. base0. 1) "- elimină ieșirile sincrone.

Dogpile (turmă tunătoare): protejați ratările:
  • Singleflight: doar un singur proces suprasaturează valoarea (vezi exemplul Lua).
  • Soft-TTL + refresh fundal: după 'soft _ ttl', da-l vechi și actualiza cu fundalul.
  • Semaphore/lock: 'SET cheie: valoare de blocare NX PX = 2000'.
  • Near-stale: „stale-în timp ce-revalidate” pentru API-uri de răspuns (vezi pct. 8).

5) Chei, namespace, serializare

5. 1 Denumire cheie

Template: '{domeniu}: {entitate}: {id}: {câmp}'

Exemple:
  • 'utilizator: profil: 42' 'catalog: produs: 1001: v2' 'psp: rate: 2025-11-03'

Adăugați o versiune schemă („: v2”) - acest lucru facilitează dizabilitatea în masă.

5. 2 Neimspaces prin „versiune spațială”

Țineți apăsată tasta 'ns: catalog = 17'. Chei reale: 'catalog: 17: produs: 1001'. Pentru handicap director global, pur și simplu increment 'ns: catalog'.

5. 3 Serializare/Compresie

JSON este convenabil, dar greu. Utilizaţi MessagePack/CBOR.
Activați compresia (LZ4/ZSTD) pentru sarcină utilă mare (> 1-2 KB). În Redis - pe partea de client.

6) chei fierbinți și sharding

Hot-chei: Monitor top-N de lovit/dor/octet. Pentru chei extrem de fierbinte:
  • Model de citire replicat: duplicați valoarea în mai multe taste cioburi "fierbinte: k: 1.. N ', alegeți aleatoriu atunci când citiți.
  • Local L1: Țineți cont de procesul de abonare pentru persoanele cu handicap.
Sharding:
  • Redis Cluster - nativ (16384 sloturi hash).
  • Memcached este un hash consistent client-side.
  • Hash-tag în Redis '{...}' fixează un slot pentru un set de taste: 'utilizator: {42}: profil' și 'utilizator: {42}: limite' va fi pe aceeași carte.

7) Politici de preempțiune și dimensiuni

Redis 'maxmemory-policy': 'allkeys-lru', 'volatile-lru', 'allkeys-lfu', 'noeviction' и т. д. Pentru memoria cache, de obicei „allkeys-lru ”/„ allkeys-lfu”.
Memcached - LRU на element-lespede.
Dimensiunea și valoarea cheii: urmăriți dimensiunea maximă a elementului (Memcached în mod implicit 1 MB, placă de tuning).
Depășirea memoriei ar trebui să se degradeze previzibil: nu „noevicție” pe calea activă.

Redis config (fragment):

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

8) Modele de protecție împotriva furtunilor - Cod

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 Nod. js cache-deoparte (simplificat)

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 și coerență

După eveniment: Atunci când schimbați în baza de date, publicați 'pub/sub' event 'invalidate: {ns}: {id}' → abonații șterg cheile.
Prin cronometru: scurt TTL pentru schimbarea frecventă a datelor.
Versioning: a se vedea „ns:” chei.
Outbox: garanție de livrare a dizabilității (eveniment jurnal/subiect, retrai).
Idempotența operațiunilor cache: utilizați 'SETXX/SETNX', versiunile ('etag') și câmpurile hash pentru increment.

10) Replicare, cluster, failover

10. 1 Redis

Sentinel: automat failover master-replica (stateFUL IP/nume).
Cluster: sharding + failover automat; clienții trebuie să sprijine redirecționările 'MOVED/ASK'.
AOF/RDB: pentru memoria cache de obicei „appendfsync everysec”, este posibil fără persistență (ca o memorie cache pură).

10. 2 Memcached

Nici o replicare din cutie. Fiabilitate - prin cioburi multi-server + repetare 'n' (client-side).
Când nodurile cad, există o creștere a ratărilor și a „recalificării” memoriei cache.

10. 3 K8s și Networking

Redis/Memcached nu le place recrearea frecventă a păstăilor; utilizați StatefulSet + AZ antipozi, fixe PVC/POD IP.
Setați PodDisruptionBudget și TopologySpreadConstricts.

11) Tranzacții, script-uri și atomicitate (Redis)

INCR/DECR, HINCRBY - contoare, cote, limite de rată (luați în considerare persista).
MULTI/Ï - un pachet de comenzi atomice.
Lua (EVAL) - citire-modificare-scriere fără curse.
Conducte - reduce RTT (în special în hamei de rețea).

Un exemplu de limită de rată (cupă token, simplificată):
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) Cozi, pub/sub și fluxuri (Redis)

Pub/Sub: handicap, semnale. Fără salvare, doar ascultători online.
Fluxuri: Cozi de evenimente de confirmare (ACK), Consumer Group, Retrai - la îndemână pentru write-back/fan-out.
Liste („BRPOP”): cozi simple.
Nu utilizați Redis ca un „autobuz unic de tot” fără o copie de rezervă - acesta este un cache/autobuz rapid, nu Kafka.

13) Securitate și acces

Izolarea rețelei/VPC, mTLS la nivel de intrare, ACL/parole ("requirement pass'/ACL în Redis 6 +).
Dezactivați comenzile periculoase din Redis ('CONFIG', 'FLUSHALL', 'KEYS') prin ACL.
Pentru Memcached - nu ascultați interfețe publice, „-U 0” (fără UDP), doar rețele private.
A nu se păstra PII; dacă este necesar - criptare TTL + scurtă la nivelul aplicației.

14) Observabilitate și întreținere

Valori cheie:
  • Raportul lovit/raportul Miss (prin namespace/traseu).
  • Latență p95/p99 „GET/SET/MGET” comenzi, timeout.
  • Evacuări и erori OOM.
  • Replicarea lag (Redis), starea clusterului, migrează/rehash evenimente.
  • Top-N chei de trafic/octeți (eșantionare).
  • Jurnale: comenzi lente ('slowlog'), erori de rețea.
  • Tablouri de bord: general (CPU/RAM/conexiuni), comenzi, sloturi de cluster, santine, care trec prin exportatorii Prometheus.

15) Configurări și implementări - exemple

15. 1 Redis Sentinel (fragment)


port 6379 protected-mode yes appendonly yes appendfsync everysec maxmemory-policy allkeys-lfu

'sentinel. conf. univ. dr


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 (valori ale cârmei, simplificate)

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

15. 3 Memcached (implementare)

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

15. 4 NGINX ca proxy read-through (buclă 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) Testarea și porțile

Profile de încărcare cache rece/cald/cald.
Injecția de ratări (purge en masse) - originea trebuie să reziste la „recalificare”.
Alerte: scădere bruscă a raportului hit, creștere a latenței miss, avalanșă de evacuări, creștere a termenelor.

17) Anti-modele

Stocați „adevărul” în Redis fără AOF/RDB și fără redundanță.
TTL = 0 (perpetuu) pentru date volatile → inconsecvență perpetuă.
Mass' KEYS' in prod.
Absența jitter/soft-TTL → întreruperi sincrone și furtuni.
Un exemplu pentru toate comenzile fără shardings/replicas.
Utilizați Memcached pentru sarcini care necesită atomicitate/scripturi.

18) Lista de verificare a implementării (0-45 zile)

0-10 zile

Selectați un șablon (cache-deoparte + L1/L2), descrieți tastele, TTL, namespaces.
Activați jitter/soft-TTL, singleflight; alerte de bază/tablouri de bord.
Pentru Redis - configurați ACL, modul protejat, slowlog, politica maxmemory.

11-25 zile

Comutare la sharding (Redis Cluster sau client hash), replici.
Handicap prin pub/sub sau versiunea neimspace; outbox în baza de date.
cache „recalificare” încercări de sarcină; limitarea originii.

26-45 zile

Autopromo/canar TTL, warm-up înainte de lansare.
Fluxuri pentru redistribuire în spate/fundal.
Rapoarte săptămânale despre raportul de succes, tastele de top, costul memoriei.

19) Valorile maturității

Hit-ratio L2 ≥ 80% (statistici privind rutele/namespaces).
P95 GET <2-3 ms (in-DC), ratează <originea SLO.
0 furtuni în handicap în masă (dovedit prin teste).
Invaliditate automată și versioning nymspace.
Sharding/replicare acoperă 1 eșec nod fără degradare apreciabilă.

20) Concluzie

Arhitectura cache puternică este disciplina cheilor și TTL, protecția împotriva furtunii, timiditatea adecvată și preempțiunea previzibilă. Redis dă semantică bogată, persistență și atomicitate; Memcached - simplitate maximă și viteză. Adăugați observabilitate, handicap eveniment, L1 + L2, iar memoria cache devine un accelerator platformă, nu o sursă de picături accidentale și bug-uri „mistice”.

Contact

Contactați-ne

Scrieți-ne pentru orice întrebare sau solicitare de suport.Suntem mereu gata să ajutăm!

Telegram
@Gamble_GC
Pornește integrarea

Email-ul este obligatoriu. Telegram sau WhatsApp sunt opționale.

Numele dumneavoastră opțional
Email opțional
Subiect opțional
Mesaj opțional
Telegram opțional
@
Dacă indicați Telegram — vă vom răspunde și acolo, pe lângă Email.
WhatsApp opțional
Format: cod de țară și număr (de exemplu, +40XXXXXXXXX).

Apăsând butonul, sunteți de acord cu prelucrarea datelor dumneavoastră.