Stories

Detail Return Return

藍易雲:Redis緩存滿了怎麼辦? - Stories Detail

以下回答面向“滿容告警→止血→根因治理”的企業級處置閉環,強調可執行與可驗證。🔥

一、先斷後治:三步走(建議作為標準Runbook)

  1. 快速止血:啓用/優化淘汰策略、釋放大Key、限峯。
  2. 精準定位:識別大Key/熱Key/高碎片/持久化放大。
  3. 系統治理:TTL體系、數據結構瘦身、分片/集羣、預留Fork空間。

二、應急動作(命令 + 解釋)🧯

# 1. 快速查看內存與淘汰態
INFO memory
MEMORY STATS
MEMORY DOCTOR

解釋INFO memory 用於總覽,MEMORY STATS 看細粒度分佈,MEMORY DOCTOR 給出官方建議;若顯示 <span style="color:red">used\_memory</span> 接近 <span style="color:red">maxmemory</span>,需立即進入止血。

# 2. 啓用更穩健的淘汰策略(LFU 更抗抖)
CONFIG SET maxmemory-policy allkeys-lfu
CONFIG SET maxmemory-samples 10

解釋allkeys-lfu 基於<span style="color:red">訪問頻率</span>淘汰,熱點穩定;maxmemory-samples 提升採樣,減少誤淘汰。如僅緩存有 TTL,可用 volatile-lfu/ttl

# 3. 釋放大Key:避免阻塞主線程
redis-cli --bigkeys
redis-cli --memkeys
# 針對某類鍵名的異步刪除(避免 DEL 阻塞)
redis-cli --scan --pattern "session:*" | xargs -r -n 100 redis-cli UNLINK

解釋--bigkeys/--memkeys 快速定位大Key;UNLINK 走<span style="color:red">異步釋放</span>,降低阻塞風險。批量用 xargs -n 100 控制節奏。

# 4. 打開惰性釋放與主動碎片整理
CONFIG SET lazyfree-lazy-eviction yes
CONFIG SET lazyfree-lazy-expire  yes
CONFIG SET lazyfree-lazy-server-del yes
CONFIG SET activedefrag yes

解釋:啓用一系列 <span style="color:red">lazyfree</span> 選項後,淘汰/過期/刪除改為後台線程回收內存;activedefrag 持續降低<span style="color:red">碎片率</span>,避免“看着空但用不了”。

# 5. 臨時降峯:限制寫入與過期加速(應急期使用)
CONFIG SET hz 50
CONFIG SET proto-max-bulk-len 512mb

解釋:適度提升 hz 改善過期處理頻率;proto-max-bulk-len 防止極端大包衝擊(按需調整)。應急期亦可在業務側限流/降級,保護核心鍵空間。


三、策略—適用—副作用對照表(落地速查)📋

策略 適用場景 關鍵配置/動作 預期收益 副作用/注意
<span style="color:red">allkeys-lfu</span> 緩存無TTL或TTL不均 CONFIG SET maxmemory-policy allkeys-lfu 更公平淘汰冷鍵 頻率統計需冷啓動期
<span style="color:red">UNLINK</span> 大Key清理 UNLINK key 批量異步 降低主線程阻塞 回收延遲、需監控
<span style="color:red">lazyfree*</span> 刪除/過期量大 多項 lazyfree 開關 平滑釋放內存 後台線程佔用CPU
<span style="color:red">activedefrag</span> 碎片率高 CONFIG SET activedefrag yes 降碎片、回收可用 輕微CPU開銷
<span style="color:red">隨機TTL</span> 同批迴填 SETEX key $((600+RANDOM%120)) 抗雪崩 需統一策略
<span style="color:red">分片/集羣</span> 單機頂不住 Cluster / 水平擴容 容量線性放大 遷移與熱點重分佈
<span style="color:red">預留Fork空間</span> AOF/RDB重寫 內存預留 30–50% 避免寫時複製崩潰 成本增加

四、根因治理清單(防止復發)🧰

  1. TTL 體系化:所有可緩存數據必須設置 <span style="color:red">TTL</span>,並做<span style="color:red">隨機抖動</span>;禁止永久Key擠佔。
  2. 數據結構瘦身
  • 小對象優先 HASH(Redis 7 採用 <span style="color:red">listpack</span> 編碼,對小字段更省內存);
  • 序列化對象做<span style="color:red">字段拆分</span>,避免整塊 JSON;
  • 大集合做分片與<span style="color:red">分層留存</span>(熱Top在Redis,冷尾在外存)。
  1. 壓縮與裁剪:客户端壓縮(如 zstd/snappy)後再寫入;對排行榜/歷史值做歸檔與<span style="color:red">抽樣</span>。
  2. 分片與就近:按業務維度哈希分片或啓用 Cluster;結合 L1 本地緩存 + L2 Redis,降低中心庫壓力與<span style="color:red">熱鍵放大</span>。
  3. 持久化評估:AOF 重寫/RDB fork 會引發<span style="color:red">COW內存放大</span>,生產建議預留 30–50% headroom,並在低峯觸發重寫。

五、容量與閾值的可解釋模型 🧪

容量估算(保守值):

$$ N_{\text{keys}} \approx \frac{\text{maxmemory} \times (1-\text{headroom})}{\text{avg\_key\_bytes}} $$

示例:maxmemory=32GB,預留 headroom=0.4,平均 Key+Value≈2KB,則

$$ N \approx \frac{32\times(1-0.4)\times 1024^3}{2048} \approx 10\ \text{百萬級} $$

解釋:為重寫與流量抖動留出<span style="color:red">headroom</span>,並以“平均字節”評估可承載Key數,指導擴容/精簡優先級。


六、決策流程(vditor/mermaid)🧭

flowchart TD
A[內存告警 or OOM風險] --> B{淘汰策略生效?}
B -- 否 --> C[CONFIG SET maxmemory-policy allkeys-lfu]
B -- 是 --> D{碎片率 > 1.5?}
D -- 是 --> E[CONFIG SET activedefrag yes]
D -- 否 --> F{存在大Key/熱Key?}
F -- 是 --> G[bigkeys/memkeys & UNLINK 批量清理]
F -- 否 --> H{持久化重寫臨近?}
H -- 是 --> I[預留空間/調整重寫時機]
H -- 否 --> J{業務峯值未控?}
J -- 是 --> K[限流/降級/隨機TTL]
K --> L[穩定後執行結構化治理與容量評估]
G --> L
E --> L
C --> L

七、示例:統一TTL與回填策略(可直接落地)⚙️

# 讀未命中回填並設置抖動TTL,避免同刻雪崩
SETEX cache:product:123 $((900 + RANDOM%180)) "json"

解釋:將 15 分鐘 TTL 加 0–180 秒抖動,保障過期分散;鍵名前綴規範化,便於批量維護。


結論:把“應急止血”做成標準化開關(<span style="color:red">LFU、UNLINK、lazyfree、activedefrag</span>),把“容量與結構”做成長期工程(<span style="color:red">TTL 體系、結構瘦身、分片與預留</span>)。當你能量化可承載鍵數與 headroom,並建立固定巡檢與演練,Redis 在滿容場景依舊可交付穩定的業務SLA。📈

user avatar u_16502039 Avatar cafebabe Avatar jianqiu Avatar aipaobudehoutao Avatar kubeexplorer Avatar winfacter Avatar renzhendezicai Avatar guaiguaidedoujiang_cmg5bc Avatar
Favorites 8 users favorite the story!
Favorites

Add a new Comments

Some HTML is okay.