Önbelleğe alma mimarisi: Redis, Memcached
Önbelleğe alma mimarisi: Redis, Memcached
1) Ne zaman ve neden önbellek
Hedefler: Gecikmeyi azaltmak, DB/PSP/harici API'leri boşaltmak ve tepe noktalarını azaltmak.
Önbellek katmanları genellikle çok düzeylidir: işlem içi (L1)> servis düzeyi (Redis/Memcached L2) - edge/CDN. Dahili önbellek sıcak okumaları hızlandırır, L2 hizmetler için yaygındır, kenar genel içerik içindir.
2) Redis vs Memcached - Özet
Kural: Karmaşık veri yapılarına, kalıcılığa, pub/sub/streams/scriptlere ihtiyacınız varsa - Redis'i alın. Süper basit, hızlı, ucuz ve dayanıklılığı olmayan KV önbellek katmanı Memcached ise.
3) Önbelleğe alma desenleri
3. 1 Önbellek-kenara (tembel)
Uygulama önbellekten okur - bir bayan - veritabanından okur - TTL ile önbelleğe koyar.
Basit TTL kontrolü, önbellek bağımsızlığı. − Kaçırma durumunda olası "fırtına".
3. 2 Okuma
İstemci/proxy kendisi bir ıskalamada orijinden çeker ve önbelleğe koyar.
Merkezi mantık. − Daha karmaşık altyapı.
3. 3 Yazma/Write-behind
Yazma: önce önbelleğe, sonra veritabanına yazma.
Write-behind: kuyruğa yazma, veritabanında asenkron flaş (çökerken potansiyel kayıp - bir günlüğe ihtiyacınız var).
3. 4 İki katmanlı (L1 + L2)
Kısa TTL ve yumuşak TTL ile L1 (işlem içi), L2 (Redis/Memcached) - "önbellek gerçeği. "Pub/sub yoluyla engellilik.
4) TTL, fırtınalar ve tutarlılık
TTL-Set veri değişim sıklığına yakın. Kısayol tuşları için TTL (jitter) randomizasyonu kullanın:'tl = base ± rand (0.. base0. 1) '- eşzamanlı çıkışları kaldırır.
Dogpile (gürleyen sürü): korumak özlüyor:- Singleflight: sadece bir işlem değeri aşırı genleştirir (bkz. Lua örneği).
- Soft-TTL + arka plan yenileme: 'soft _ tl'den sonra bayatlayın ve arka planla güncelleyin.
- Semafor/kilit: 'SET tuşu: kilit değeri NX PX = 2000'.
- Near-stale: Yanıt API'leri için 'stale-while-revalidate' (bakınız bölüm 8).
5) Anahtarlar, ad alanları, serileştirme
5. 1 Anahtar adlandırma
Şablon: '{domain}: {entity}: {id}: {field}'
Örnekler:- 'kullanıcı: profil: 42' 'katalog: ürün: 1001: v2' 'psp: oranlar: 2025-11-03'
Bir şema sürümü ekleyin (': v2') - bu kitlesel engelliliği kolaylaştırır.
5. 2 "uzay sürümü'ile Neimspaces
'Ns: catalog = 17' tuşunu basılı tutun. Gerçek anahtarlar: 'katalog: 17: ürün: 1001'. Global dizin sakatlığı için sadece 'ns: catalog' değerini artırın.
5. 3 Serileştirme/Sıkıştırma
JSON uygun, ama ağır. MessagePack/CBOR kullanın.
Büyük yük (> 1-2 KB) için sıkıştırmayı (LZ4/ZSTD) etkinleştirin. Redis'te - müşteri tarafında.
6) Sıcak tuşlar ve sharding
Kısayol tuşları: Top-N'yi hit/miss/byte ile izleyin. Son derece sıcak tuşlar için:- Çoğaltılmış okuma deseni: değeri birkaç parça anahtarında çoğaltın 'sıcak: k: 1.. N ', okurken rastgele seçin.
- Yerel L1: Engellilik abonelik sürecini aklınızda bulundurun.
- Redis Cluster - native (16384 karma yuvası).
- Memcached, istemci tarafı tutarlı bir karma.
- Redis'teki hash-tag '{...}'bir anahtar kümesi için bir yuvayı düzeltir:' user: {42}: profile've 'user: {42}: limits' aynı kartta olacaktır.
7) Önleme politikaları ve boyutları
Redis 'maxmemory-policy': 'Allkeys-lru', 'volatile-lru', 'allkeys-lfu', 'noeviction' и т. д. Önbellek için, genellikle 'allkeys-lru'/' allkeys-lfu'.
Memcached - LRU на item-slab.
Anahtar boyutu ve değeri: Maksimum öğe boyutunu izleyin (varsayılan olarak 1 MB olarak önbelleğe alınmış, ayar levhası).
Aşırı bellek öngörülebilir şekilde bozulmalıdır: etkin yolda 'noeviction'değil.
maxmemory 32gb maxmemory-policy allkeys-lfu hz 50 tcp-keepalive 60
8) Fırtına Koruma Desenleri - Kod
8. 1 Redis Lua singleflight (sözde)
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 Düğüm. js önbellek-kenara (basitleştirilmiş)
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) Engellilik ve tutarlılık
Olaya göre: Veritabanında değiştirirken, yayınla 'pub/sub' event 'invalidate: {ns}: {id}' - aboneler anahtarları siler.
Zamanlayıcıya göre: Sık değişen veriler için kısa TTL.
Sürüm oluşturma: 'ns:' tuşlarına bakın.
Giden kutusu: engelli teslimat garantisi (günlük/konu olay, retrai).
Önbellek işlemleri idempotency: artırmak için 'SETXX/SETNX', sürümleri ('etag') ve karma alanları kullanın.
10) Çoğaltma, küme, yük devretme
10. 1 Redis
Sentinel: otomatik yük devretme master-replica (stateFUL IP/name).
Küme: sharding + otomatik yük devretme; Müşteriler 'MOVED/ASK' yönlendirmelerini desteklemelidir.
AOF/RDB: Önbellek için genellikle 'appendfsync everysec', (saf önbellek gibi) kalıcılık olmadan mümkündür.
10. 2 Memcached
Kutunun dışında çoğaltma yok. Güvenilirlik - çoklu sunucu parçası + tekrar'n '(istemci tarafı) aracılığıyla.
Düğümler düştüğünde, özleme ve önbelleğin "yeniden eğitilmesi'nde bir artış olur.
10. 3 K8s ve Ağ Oluşturma
Redis/Memcached, bölmelerin sık sık yeniden oluşturulmasını sevmez; Kullanım StatefulSet + AZ antipodları, sabit PVC/POD IP.
PodDisruptionBudget ve TopologySpreadRestrictions öğelerini ayarlayın.
11) İşlemler, komut dosyaları ve atomisite (Redis)
INCR/DECR, HINCRBY - sayaçlar, kotalar, oran limitleri (sadece devam etmeyi düşünün).
MULTI/EXEC - bir atom komutları paketi.
Lua (EVAL) - yarış olmadan oku-değiştir-yaz.
Boru hattı - RTT'yi azaltır (özellikle ağ şerbetçiotu).
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) Kuyruklar, pub/sub ve Akışlar (Redis)
Pub/Sub: sakatlık, sinyaller. Kaydetme yok, yalnızca çevrimiçi dinleyiciler.
Akışlar: Onay Olay Kuyrukları (ACK), Tüketici Grubu, Retrai - yazma arkası/fan çıkışları için kullanışlı.
Listeler ('BRPOP'): basit kuyruklar.
Redis'i yedekleme olmadan'her şeyin tek veri yolu'olarak kullanmayın - bu bir önbellek/hızlı veri yolu, Kafka değil.
13) Güvenlik ve erişim
Ağ izolasyonu/VPC, giriş seviyesinde mTLS, ACL/parolalar (Redis 6 +'da 'requirempass'/ACL).
ACL aracılığıyla Redis'teki ('CONFIG', 'FLUSHALL', 'KEYS') tehlikeli komutları devre dışı bırakın.
Memcached için - genel arayüzleri dinlemeyin, '-U 0' (UDP olmadan), sadece özel ağlar.
PII saklamayın; Gerekirse - uygulama düzeyinde kısa TTL + şifreleme.
14) Gözlemlenebilirlik ve bakım
Temel metrikler:- Vuruş oranı/Miss oranı (ad alanına/rotaya göre).
- Gecikme p95/p99 'GET/SET/MGET' komutları, zaman aşımları.
- Tahliye и OOM hataları.
- Çoğaltma gecikmesi (Redis), küme durumu, migrate/rehash olayları.
- Trafik/baytlara göre Üst-N tuşları (örnekleme).
- Günlükler: yavaş komutlar ('yavaş'), ağ hataları.
- Panolar: genel (CPU/RAM/bağlantılar), komutlar, küme yuvaları, sentineller, Prometheus ihracatçılarından geçiyor.
15) Yapılandırmalar ve dağıtımlar - örnekler
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 Redis Cluster (dümen değerleri, basitleştirilmiş)
yaml cluster:
enabled: true nodes: 6 # 3 masters + 3 replicas persistence:
size: 100Gi resources:
requests: { cpu: "500m", memory: "2Gi" }
15. 3 Memcached (dağıtım)
yaml containers:
- image: memcached:1. 6 args: ["-m", "32768", "-I", "2m", "-v", "-t", "8", "-o", "modern"]
ports: [{ containerPort: 11211 }]
15. 4 Okunabilir proxy olarak NGINX (API döngüsü)
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) Test ve kapılar
Soğuk/sıcak/sıcak önbellek yükleme profilleri.
Kaçırmaların enjeksiyonu (toplu olarak tasfiye) - köken "yeniden eğitime" dayanmalıdır.
Uyarılar: isabet oranındaki keskin düşüş, bayan gecikmesindeki artış, tahliye çığ, zaman aşımlarında artış.
17) Anti-desenler
"Gerçeği" Redis'te AOF/RDB olmadan ve fazlalık olmadan saklayın.
Geçici veriler için TTL = 0 (sürekli) - sürekli tutarsızlık.
Kitle 'KEYS' prod.
Jitter/soft-TTL yokluğu - senkron kesintiler ve fırtınalar.
Parçalama/çoğaltma olmadan tüm komutlar için bir örnek.
Atomiklik/komut dosyaları gerektiren görevler için Memcached kullanın.
18) Uygulama kontrol listesi (0-45 gün)
0-10 gün
Bir şablon seçin (önbellek-kenara + L1/L2), anahtarları, TTL, ad alanlarını açıklayın.
Jitter/soft-TTL, singleflight etkinleştirin; temel uyarılar/panolar.
Redis için - ACL, protected-mode, slowlog, maxmemory-policy yapılandırın.
11-25 gün
Parçalama (Redis Cluster veya client hash), kopyalara geçin.
Pub/sub veya neimspace versiyonu ile engellilik; Veritabanındaki giden kutusu.
Önbellek "yeniden eğitim" yük testleri; Kaynağı sınırlamak.
26-45 gün
Autopromo/kanarya TTL, serbest bırakılmadan önce ısınma.
Write-behind/background yeniden birleştirme için akışlar.
Vuruş oranı, üst anahtarlar, bellek maliyeti hakkında haftalık raporlar.
19) Olgunluk metrikleri
Vuruş oranı L2 ≥ %80 (rotalar/ad alanları istatistikleri).
P95 GET <2-3 ms (in-DC), <SLO orijinini özlüyor.
Kitlesel sakatlıkta 0 fırtına (testlerle kanıtlanmıştır).
Otomatik engellilik ve nymspace sürüm oluşturma.
Sharding/replication, kayda değer bir bozulma olmadan 1 düğüm arızasını kapsar.
20) Sonuç
Güçlü önbellek mimarisi, anahtarların ve TTL'nin, fırtına korumasının, uygun parçalanmanın ve öngörülebilir önsezinin disiplinidir. Redis zengin semantik, sebat ve atomiklik verir; Memcached - maksimum basitlik ve hız. Gözlemlenebilirlik, olay sakatlığı, L1 + L2 ekleyin ve önbellek yanlışlıkla düşme ve "mistik" böcek kaynağı değil, bir platform hızlandırıcısı haline gelir.