腰帶體系結構:Redis,Memcached
腰帶體系結構: Redis,Memcached
1) kesh的時間和原因
目標:降低潛伏期,卸載DB/PSP/外部 API,軟化峰值。
腰果層通常是多層的:進程(L1)→服務級別(Redis/Memcached L2)→ 邊緣/CDN。內部kesh加速了「熱」閱讀,L2(服務共享)和edge(公共內容)。
2)Redis vs Memcached-簡述
規則:如果需要復雜的數據結構,持久性,pub/sub/stream/script-采取Redis。如果超簡單,快速,便宜的KV-kesh層沒有可重復性-Memcached。
3)積壓模板
3.1 Cache-aside (lazy)
該應用程序從kesh →錯誤中讀取→從DB讀取→與TTL一起放入kesh。
TTL的簡單控制,獨立於腰果。−錯過時可能會出現「風暴」。
3.2 Read-through
客戶端/代理本身會在錯過時從起源中拉出,然後放入kesh中。
集中邏輯.−更復雜的基礎架構。
3.3 Write-through / Write-behind
寫作:首先在kesh中錄制,然後在DB中錄制。
寫在後面:寫入隊列,異步flash到DB(潛在的崩潰損失-需要日誌)。
3.4 Two-tier (L1+L2)
L1(過程)具有短TTL和軟TTL,L2(Redis/Memcached)是「腰果真相」。通過pub/sub致殘。
4)TTL,風暴和一致性
TTL:設置接近數據更改頻率。對於熱鍵,請使用TTL(jitter)隨機:'ttl=base ± rand(0.. base0。1)'-消除同步過期。
Dogpile (thundering herd):保護失誤:- Singleflight:只有一個過程會重新生成值(請參見Lua示例)。
- Soft-TTL+background refresh:在「soft_ttl」之後放棄過時的(stale)並更新背景。
- Semaphore/lock: `SET key:lock value NX PX=2000`.
- Near-stale:答案的API的「stale-while-revalidate」(見第8節)。
5)鍵,neyspaces,序列化
5.1鍵命名
Template: {domain}:{entity}:{id}:{field}
示例:- `user:profile:42` `catalog:product:1001:v2` `psp:rates:2025-11-03`
添加方案版本(':v2')-這有助於大規模殘疾。
5.2 Nijspeiss通過「空間版本」
保持鑰匙'ns: catalog=17'。Real keys: 'catalog: 17: product: 1001'。對於全球目錄失效,只需內置「ns: catalog」。
5.3序列化/加壓
JSON很舒服,但很沈重。使用MessagePack/CBOR。
包括用於大型付費的壓縮(LZ4/ZSTD)(>1-2 KB)。在Redis-客戶端。
6)熱鍵和碎片
熱鍵:通過hit/miss/byte監視top-N。對於極端熱鍵:- Replicated read pattern:將值復制到多個shard鍵中「hot: k:1.. N」,在閱讀時選擇隨機值。
- Local L1:使用殘疾訂閱保存過程內存。
- Redis Cluster是本機的(16384 hash插槽)。
- Memcached是客戶端一致哈希。
- Redis中的hash-tag"{……}'捕獲鍵集的插槽:'user: {42}:profile'和'user: {42}:limits'將處於同一階段。
7)排擠政策和規模
Redis `maxmemory-policy`: `allkeys-lru`, `volatile-lru`, `allkeys-lfu`, `noeviction` и т. д.對於腰果,通常是「allkeys-lru」/「allkeys-lfu」。
Memcached — LRU на item-slab.
密鑰大小和價值:請註意最大小尺寸(Memcached默認值為1 MB,調音板)。
內存過多應該可以預見地降解:在活動路徑上不是「未實現」。
maxmemory 32gb maxmemory-policy allkeys-lfu hz 50 tcp-keepalive 60
8)防暴模式-代碼
8.1 Redis Lua singleflight(偽)
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(簡化)
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)殘疾與連貫性
根據事件:如果更改為DB,則發布'pub/sub'事件'invalidate: {ns}:{id} '→訂戶刪除密鑰。
按計時器:用於頻繁變化的數據的短TTL。
轉化:參見'ns: 'keys。
Outbox:殘障送貨保證(活動log/topic, retrai)。
腰果操作的相等性:使用「SETXX/SETNX」,版本(「etag」)和哈希字段進行填充。
10)復制,群集,failover
10.1 Redis
Sentinel:自動故障切換主副本(stateFUL IP/名稱)。
集群:sharding+auto failover;客戶必須支持「MOVED/ASK」重定向。
AOF/RDB:對於通常為「appendfsync everysec」的腰果,可以沒有持久性。
10.2 Memcached
沒有開箱即用的復制。可靠性-通過多服務器shard+replay 'n' (client-side)。
當腳趾下降時,腳趾會增加錯誤和「重新訓練」腰果。
10.3個K8s和網絡方面
Redis/Memcached不喜歡pod's的頻繁療養;使用固定的PVC/POD IP AZ上的StatefulSet+反代碼。
放置PodDisruptionBudget和TopologySpreadConstraints。
11)交易、腳本和原子性(Redis)
INCR/DECR,HINCRBY-計數器,配額,限額限制(僅考慮persist)。
MULTI/EXEC是一組原子命令。
Lua(EVAL)是沒有比賽的閱讀修改寫作。
管道-減少RTT(尤其是在網絡跳躍中)。
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)隊列、pub/sub和Streams (Redis)
Pub/Sub:殘疾,信號。沒有保存,只有在線聽眾。
Streams:確認事件隊列(ACK),消費者組,retrai-方便寫作/粉絲外出。
Lists(「BRPOP」):簡單的隊列。
不要將Redis用作沒有back的「單一總線」-它是kesh/快速總線,不是Kafka。
13)安全和訪問
隔離網絡/VPC,ingress級別的mTLS,ACL/密碼(Redis 6+中的「requirepass」/ACL)。
通過ACL在Redis(「CONFIG」,「FLUSHALL」,「KEYS」)中破壞危險。
對於Memcached,不聽公共接口,「-U 0」(沒有UDP),只有私有網絡。
PII不存儲;如果需要-應用程序級別的短TTL+加密。
14)可觀察性和維護
關鍵指標:- Hit ratio/Miss ratio(通過namespace/路線)。
- Latency p95/p99命令「GET/SET/MGET」,時間軸。
- Evictions и OOM errors.
- Replication lag (Redis), cluster state, migrate/rehash events.
- 按流量/字節排列的Top-N鍵。
- Logs:慢命令(「slowlog」),網絡錯誤。
- Dashbords:通用(CPU/RAM/connections),命令,群集插槽,sentinels,通過Prometheus出口商。
15)Configs和部署-示例
15.1 Redis Sentinel(片段)
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 (helm values,簡化)
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作為讀取代理(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)測試和門戶
「冷/熱/熱kesh」負載配置文件。
註射失誤(大量)-起源必須經受「再培訓」。
Alerts:命中率的急劇下降,小姐的上升,雪崩的變化,時間的增長。
17)反模式
在沒有AOF/RDB且沒有冗余的情況下將「真相」存儲在Redis中。
對於波動數據,TTL=0(無限)→永久性非約束性。
大量銷售「KEYS」。
缺少jitter/soft-TTL →同步過期和暴風雨。
每個團隊只有一個實例,沒有硬化/復制副本。
將Memcached用於需要原子性/腳本的任務。
18)實施清單(0-45天)
0-10天
選擇一個模板(cache-aside+L1/L2),描述鍵、TTL、nijspace。
包括jitter/soft-TTL,單飛;基本Alerta/dashbords。
對於Redis-自定義ACL,保護模式,slowlog, maxmemory-policy.
11-25天
轉至副本(Redis Cluster或客戶端哈希)。
通過pub/sub或neimspace版本致殘;DB的outbox。
腰果「再培訓」負載測試;limiting origin.
26-45天
Autopromo/Canary TTL,在發布前加熱。
用於寫入/背景對接的流。
每周報告最高,最高密鑰,內存成本。
19)成熟度量標準
Hit-ratio L2 ≥ 80%(路線/航線間統計)。
P95 GET <2-3 ms (in-DC),錯誤<SLO起源。
0暴風雨大規模殘疾(通過測試證明)。
自動失效和重置。
硬化/復制覆蓋1個節點的故障,而沒有明顯的降級。
20)結論
強大的腰果體系結構是鑰匙和TTL學科,防暴保護,適當的硬化和可預測的排出。Redis提供了豐富的語義,持續性和原子性;Memcached-最大限度的簡單性和速度。添加可觀察性,事件障礙,L1+L2,kesh將成為平臺加速器而不是隨機下降和「神秘」錯誤的來源。