結論先講
Cache 出問題時比沒有 cache 更糟。 沒有 cache 頂多是慢,cache 出 bug 是「看到舊資料」「付了錢但顯示沒付」「庫存顯示有但下單說沒有」。這些 bug 比效能問題更難查、更難修、更讓用戶生氣。
誤用一:什麼都往 Redis 塞
症狀
// 每個 API endpoint 都加 cache
app.get('/api/users/:id', cache('user', 300), getUser);
app.get('/api/orders/:id', cache('order', 300), getOrder);
app.get('/api/products/:id', cache('product', 300), getProduct);
app.get('/api/cart/:id', cache('cart', 300), getCart);
app.get('/api/notifications', cache('notif', 60), getNotifications);看起來很勤勞。但 cart 和 notifications 每次都不一樣(用戶剛加了商品、剛收到通知),cache hit rate 趨近於零。你付出了 Redis roundtrip 的成本(每次查 Redis 再查 DB),效能反而更差。
怎麼修
只 cache 讀取頻繁 + 很少變動 的資料。上一篇 的表格是判斷依據。在加 cache 之前先問:「這個 endpoint 的 cache hit rate 預期是多少?」低於 50% 就不值得。
誤用二:Cache Key 沒有 Namespace
症狀
// Service A: cache user profile
redis.set(`user:${userId}`, profileData);
// Service B: cache user permissions
redis.set(`user:${userId}`, permissionData); // 覆蓋了 A 的資料!兩個 service 用了同一個 key pattern user:{id},互相覆蓋。
怎麼修
// 加 namespace
redis.set(`profile-service:user:${userId}`, profileData);
redis.set(`auth-service:user:${userId}`, permissionData);命名規則:{service}:{entity}:{id}:{field?}。
誤用三:部署後 Cache 是空的
症狀
部署新版本 → Redis 被 flush(或 key 結構改了)→ 所有請求都 cache miss → 全部打 DB → DB 扛不住 → 服務掛掉。
這就是 上一篇 講的 cache stampede,但觸發原因是「部署」而不是「TTL 過期」。
怎麼修
1. 部署時不要 flush Redis
除非 cache 的資料結構改了,否則讓舊 cache 慢慢過期,不要一次清空。
2. Cache Warmup Script
部署完成後,自動跑一次 warmup——查出熱門資料寫入 Redis,在真實流量進來之前把 cache 填好。
// warmup.js — 部署後自動執行
const hotProducts = await db.query('SELECT * FROM products ORDER BY views DESC LIMIT 1000');
for (const p of hotProducts) {
await redis.set(`product:${p.id}`, JSON.stringify(p), 'EX', 3600);
}3. 限流
部署後的前幾分鐘開啟更積極的 rate limiting,減少 DB 被 cache miss 打爆的風險。
誤用四:Cache 比 DB 還大
症狀
「為了效能」把每次查詢結果都 cache,包含帶有大量 JOIN 的查詢結果。一筆 cache entry 500KB,10 萬筆 = 50GB。Redis 的 RAM 用量超過 DB。
怎麼修
- 只 cache 必要的欄位,不是整個查詢結果
- 設合理的 TTL,不要永不過期
- 監控 Redis 記憶體使用:
redis-cli INFO memory - 設 maxmemory + eviction policy:
maxmemory 2gb+maxmemory-policy allkeys-lru
誤用五:不知道 Cache 在 Cache 什麼
症狀
系統慢 → 有人說「加 cache」→ 隨便包一層 Redis → 效能沒改善但沒人敢拆(怕拆了更慢)。
三個月後,沒人記得哪些 endpoint 有 cache、TTL 是多少、什麼時候 invalidate。新來的工程師改了資料但畫面不更新,查了兩天才發現「有一層不知道誰加的 cache」。
怎麼修
Cache 要有文件。 至少要紀錄:
| Key Pattern | TTL | Invalidation 時機 | 負責 Service |
|---|---|---|---|
product:{id} | 15min | 商品更新時刪 | product-service |
post-list:page:{n} | 5min | 新文章發布時刪 | post-service |
user-session:{token} | 60min | 登出時刪 | auth-service |
沒有文件的 cache = 技術債。
下一篇
Event-Driven 架構入門:為什麼微服務離不開它 — 單體用 function call,微服務用 event。不是因為潮,是因為你沒辦法跨服務做 transaction。從「為什麼需要」到「怎麼設計 event schema」。
本系列文章
完整 68 篇目錄見 系列首頁
← 上一篇:Cache 的正確用法:不是什麼都往 Redis 塞 → 下一篇:Event-Driven 架構入門:為什麼微服務離不開它