GH GambleHub

Architektura buforowania: Redis, Memcached

Architektura buforowania: Redis, Memcached

1) Kiedy i dlaczego pamięć podręczna

Cele: zmniejszenie opóźnień, odciążenie DB/PSP/zewnętrznych API i złagodzenie pików.
Warstwy pamięci podręcznej są często wielopoziomowe: in-process (L1) → service-level (Redis/Memcached L2) → edge/CDN. Wewnętrzna pamięć podręczna przyspiesza gorące odczyty, L2 jest powszechne dla usług, krawędź jest dla treści publicznych.

2) Redis vs Memcached - krótki

KryteriumRedisMemcached
Typy danychŁańcuchy, hashes, listy, zestawy, zset, bitmaps, HyperLogLog, Streams, Bloom/CF (za pośrednictwem modułów)Klucz wartości (ciągi)
UporczywośćAOF/RDB, no-fsync-loss podczas konfiguracjiNie, nie jest
KlasterKlaster Redis (shading, failover )/SentinelOdłamek klienta, brak natywnej awarii
Transakcje/skryptyMULTI/EXEC, EVAL (Lua), operacje atomoweNie, nie jest
TTL/eksmisjaPolityka dostrajaniaPodstawowy
Opóźnienie/pamięćNieco więcej napowietrznychBardzo lekki, przewidywalny

Zasada: jeśli potrzebujesz złożonych struktur danych, trwałości, pub/sub/streams/scripts - weź Redis. Jeśli super-prosta, szybka, tania warstwa pamięci podręcznej KV bez trwałości jest Memcached.

3) Wzory buforowania

3. 1 Cache-off (leniwy)

Aplikacja czyta z pamięci podręcznej → miss → czyta z bazy → umieszcza ją w pamięci podręcznej z TTL.

Proste sterowanie TTL, niezależność pamięci podręcznej. − Możliwe „burza” w przypadku braków.

3. 2 Czytanie

Klient/serwer proxy sam wyciąga z pochodzenia na miss i umieszcza go w pamięci podręcznej.

Scentralizowana logika. − Bardziej złożona infrastruktura.

3. 3 Odpis/odpis

Zapis: pisanie najpierw do pamięci podręcznej, a następnie do bazy danych.
Zapis: pisanie do kolejki, asynchroniczny błysk w bazie danych (potencjalna strata podczas awarii - potrzebujesz dziennika).

3. 4 Dwupoziomowe (L1 + L2)

L1 (w procesie) z krótkim TTL i miękkim TTL, L2 (Redis/Memcached) - "cache truth. "Niepełnosprawność przez pub/sub.

4) TTL, burze i spójność

TTL-Set blisko częstotliwości zmiany danych. W przypadku kluczy gorących należy użyć randomizacji TTL (jitter): 'ttl = base ± rand (0.. base0. 1) "- usuwa odpływ synchroniczny.

Dogpile (grzmące stado): chronić braki:
  • Singleflight: tylko jeden proces nadrzędnie generuje wartość (patrz przykład Lua).
  • Soft-TTL + tło odświeżyć: po 'soft _ ttl', dać go stale i zaktualizować z tłem.
  • Semahore/lock: 'SET key: lock value NX PX = 2000'.
  • Near-stale: „stale-while-revalidate” dla API odpowiedzi (patrz punkt 8).

5) Klucze, obszary nazw, serializacja

5. 1 Nazwa klucza

Szablon: '{domain}: {entity}: {id}: {field}'

Przykłady:
  • „użytkownik: profil: 42” „katalog: produkt: 1001: v2” „psp: stawki: 2025-11-03”

Dodaj wersję schematu (': v2') - ułatwia to masową niepełnosprawność.

5. 2 Neimspaces poprzez „wersja kosmiczna”

Przytrzymaj klucz 'ns: catalog = 17'. Prawdziwe klucze: 'katalog: 17: produkt: 1001'. Dla niepełnosprawności katalogu globalnego, po prostu przyrost 'ns: catalog'.

5. 3 Serializacja/kompresja

JSON jest wygodny, ale ciężki. Należy użyć opakowania/CBOR.
Włącz kompresję (LZ4/ZSTD) dla dużego ładunku użytkowego (> 1-2 KB). W Redis - po stronie klienta.

6) Gorące klucze i shading

Hot-keys: Monitor top-N przez hit/miss/byte. Dla niezwykle gorących kluczy:
  • Replikowany wzór odczytu: powielanie wartości w kilku klawiszach odłamkowych 'hot: k: 1.. N', wybierz losowo podczas czytania.
  • Lokalne L1: Pamiętaj o procesie subskrypcji niepełnosprawności.
Shading:
  • Redis Cluster - rodzime (16384 sloty skrótu).
  • Memcached jest konsekwentnym skrótem po stronie klienta.
  • Hash-tag w Redis '{...}' naprawia slot dla zestawu kluczy: 'user: {42}: profile' i 'user: {42}: limits' będzie na tej samej karcie.

7) Zasady i rozmiary preempcji

Redis "maxmemory-policy": "allkeys-lru", "volatile-lru", "allkeys-lfu", "noeviction", "ма. д. W przypadku pamięci podręcznej zwykle 'allkeys-lru '/' allkeys-lfu'.
Memcached - LRU на pozycja-płyta.
Rozmiar i wartość klucza: zegarek dla maksymalnego rozmiaru elementu (domyślnie Memcached 1 MB, płyta dostrajająca).
Przekroczenie pamięci powinno być przewidywalne: nie „noeksmisja” na aktywnej ścieżce.

Redis config (fragment):

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

8) Wzory ochrony przed burzą - Kod

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 Węzeł. js cache-off (uproszczony)

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) Niepełnosprawność i spójność

Przez zdarzenie: Podczas zmiany w bazie danych, opublikować 'pub/sub' event 'unieważnić: {ns}: {id}' → abonenci usunąć klucze.
Przez timer: krótki TTL dla często zmieniających się danych.
Wersioning: patrz 'ns:' klucze.
Outbox: gwarancja dostawy niepełnosprawności (log/topic event, retrai).
Operacje pamięci podręcznej: użyć 'SETXX/SETNX', wersji ('etag') i pola skrótu do przyrostu.

10) Replikacja, klaster, awaria

10. 1 Redis

Sentinel: automatyczna master-replika awaryjna („FUL IP/name”).
Klaster: shading + automatyczna awaria; klienci muszą obsługiwać przekierowania „MOVED/ASK”.
AOF/RDB: dla pamięci podręcznej zwykle „appendix sync everysec” jest możliwe bez trwałości (jak czysty pamięć podręczna).

10. 2 Memcached

Nie ma replikacji z pudełka. Niezawodność - poprzez odłamek wielozadaniowy + powtarzanie 'n' (po stronie klienta).
Gdy węzły spadają, następuje wzrost braków i „przekwalifikowania” pamięci podręcznej.

10. 3 K8s i tworzenie sieci

Redis/Memcached nie podoba się częste ponowne tworzenie strąków; używać antypodów Stat Set + AZ, stałych PVC/POD IP.
Ustaw budżet PodDis i Maksymalne Ograniczenia.

11) Transakcje, skrypty i atomowość (Redis)

INCR/DECR, HINCRBY - liczniki, kwoty, limity stawek (po prostu rozważyć utrzymać).
MULTI/EXEC - pakiet poleceń atomowych.
Lua (EVAL) - read-modify-write bez wyścigów.
Rurociąg - zmniejsza RTT (zwłaszcza w chmielu sieciowym).

Przykład limitu stawki (wiadro tokenowe, uproszczone):
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) Kolejki, pub/sub i strumienie (Redis)

Pub/Sub: niepełnosprawność, sygnały. Nie oszczędzaj, tylko słuchacze online.
Strumienie: Kolejki zdarzeń potwierdzających (ACK), Grupa konsumencka, Retrai - przydatne do odpisów/wentylatorów.
Listy ('BRPOP'): proste kolejki.
Nie używaj Redis jako „pojedynczego autobusu wszystkiego” bez kopii zapasowej - jest to pamięć podręczna/szybki autobus, nie Kafka.

13) Bezpieczeństwo i dostęp

Izolacja sieci/VPC, mTLS na poziomie wejścia, ACL/hasła ('default '/ACL w Redis 6 +).
Wyłączanie niebezpiecznych poleceń w Redis ('CONFIG', 'FLUSHALL', 'KEYS') poprzez ACL.
Dla Memcached - nie słuchaj interfejsów publicznych, '-U 0' (bez UDP), tylko sieci prywatne.
Nie przechowywać PII; w razie potrzeby - krótkie szyfrowanie TTL + na poziomie aplikacji.

14) Obserwowalność i konserwacja

Kluczowe wskaźniki:
  • Współczynnik trafienia/stosunek Miss (według przestrzeni nazw/trasy).
  • Latency p95/p99 'GET/SET/MGET' polecenia, timeouts.
  • Evictions - błędy OOM.
  • Opóźnienie replikacji (Redis), stan klastra, migracja/rehash zdarzeń.
  • Klucze top-N przez ruch/bajty (pobieranie próbek).
  • Dzienniki: powolne polecenia ('slowlog'), błędy sieciowe.
  • Deski rozdzielcze: ogólne (CPU/RAM/connections), polecenia, gniazda klastra, czujniki, przechodzące przez eksporterów Prometheusa.

15) Konfiguracje i rozmieszczenia - przykłady

15. 1 Redis Sentinel (snippet)


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 Klaster Redis (wartości steru, uproszczone)

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

15. 3 Memcached (rozmieszczenie)

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

15. 4 NGINX jako serwer proxy (pętla 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) Badania i bramy

Profile obciążenia pamięci podręcznej zimnej/ciepłej/gorącej.
Wstrzyknięcie braków (masowo oczyszczonych) - pochodzenie musi wytrzymać „przekwalifikowanie”.
Ostrzeżenia: gwałtowny spadek współczynnika trafienia, wzrost opóźnienia, lawina eksmisji, wzrost czasu.

17) Anty-wzory

Przechowywać „prawdę” w leku Redis bez AOF/RDB i bez redundancji.
TTL = 0 (wieczyste) dla danych lotnych → niekonsekwencja wieczysta.
Mass 'KEYS' w prod.
Brak jitter/soft-TTL → synchroniczne przerwy i burze.
Jeden przykład dla wszystkich poleceń bez odłamków/replik.
Użyj Memcached do zadań wymagających atomowości/skryptów.

18) Lista kontrolna wdrażania (0-45 dni)

0-10 dni

Wybierz szablon (cache-aside + L1/L2), opisz klucze, TTL, obszary nazw.
Włącz jitter/soft-TTL, single flight; podstawowe alerty/deski rozdzielcze.
Dla Redis - konfiguracja ACL, tryb chroniony, slowlog, maxmemory-policy.

11-25 dni

Przełącz na shading (klaster Redis lub hash klienta), repliki.
Niepełnosprawność za pośrednictwem wersji pub/sub lub neimspace; outbox w bazie danych.
badania obciążenia „przekwalifikowania” pamięci podręcznej; ograniczenie pochodzenia.

26-45 dni

Autopromo/kanarka TTL, rozgrzewka przed zwolnieniem.
Strumienie do odpisu/reasekuracji tła.
Cotygodniowe raporty na temat wskaźnika trafień, najlepszych kluczy, kosztów pamięci.

19) Wskaźniki zapadalności

Współczynnik trafienia L2 ≥ 80% (dane statystyczne dotyczące tras/obszarów nazw).
P95 GET <2-3 ms (in-DC), brakuje <pochodzenia SLO.
0 burz w masowej niepełnosprawności (potwierdzonych testami).
Automatyczna niepełnosprawność i niymprzestrzeń wersioning.
Powielanie/replikacja obejmuje 1 awarię węzła bez znacznej degradacji.

20) Wniosek

Silna architektura pamięci podręcznej to dyscyplina kluczy i TTL, ochrona przed burzą, właściwa sztywność i przewidywalne uprzedzenie. Redis daje bogatą semantykę, trwałość i atomowość; Memcached - maksymalna prostota i prędkość. Dodaj obserwowalność, niepełnosprawność zdarzeń, L1 + L2, a pamięć podręczna staje się przyspieszeniem platformy, a nie źródłem przypadkowych kropli i „mistycznych” błędów.

Contact

Skontaktuj się z nami

Napisz do nas w każdej sprawie — pytania, wsparcie, konsultacje.Zawsze jesteśmy gotowi pomóc!

Telegram
@Gamble_GC
Rozpocznij integrację

Email jest wymagany. Telegram lub WhatsApp są opcjonalne.

Twoje imię opcjonalne
Email opcjonalne
Temat opcjonalne
Wiadomość opcjonalne
Telegram opcjonalne
@
Jeśli podasz Telegram — odpowiemy także tam, oprócz emaila.
WhatsApp opcjonalne
Format: kod kraju i numer (np. +48XXXXXXXXX).

Klikając przycisk, wyrażasz zgodę na przetwarzanie swoich danych.