快取與儲存練習題 (Practice - Caching & Storage)
Blob Storage、Distributed Cache、Redis 等其他主題將在後續 PDF 處理時補入此檔。
答案採 >
Related Concepts
- 07-Caching-Storage/01-Caching
- 02-Distributed-Systems/04-Consistent-Hashing
- 02-Distributed-Systems/05-Numbers-to-Know
- 05-Database-Advanced/03-Replication
| 關鍵字/場景 | 對應答案 |
|---|---|
| 預設快取模式 | Cache-Aside |
| 預設淘汰策略 | LRU + TTL |
| 熱門 key 過期,DB 被打垮 | Cache Stampede → Request Coalescing |
| 名人個人資料快取被打爆 | Hot Key → 複製 + in-process + rate limit |
| 靜態圖片放哪 | CDN |
| feature flag / 設定值 | In-Process Cache |
| 寫入後讀到舊值 | 寫入時 invalidate / 短 TTL / 接受最終一致 |
Caching(Q1–Q12)
Question 1 - 為什麼用快取 [recall]
從 PostgreSQL 讀一個用戶資料約需 50ms,從 Redis 讀只需 1ms。這個差距背後的根本原因是什麼?
資料庫把資料存在磁碟上,每次查詢都要付磁碟存取的代價(seek、IO)。
Redis 把資料放記憶體裡,離 CPU 近得多,繞過了磁碟瓶頸。
量級差距約 50×,這就是為什麼讀取密集系統 cache 是預設答案。
Question 2 - Latency 排序 [recall]
將以下快取位置依延遲由低到高排序:External Cache (Redis)、CDN、In-Process Cache。
In-Process Cache < External Cache (Redis) < CDN
- In-Process:零網路開銷,直接讀行程記憶體(奈秒級)
- Redis(同區):< 1ms,但仍有網路 hop
- CDN:20–40ms(已比直連源站 250–300ms 快很多)
Question 3 - Cache-Aside vs Write-Through [analysis]
Cache-Aside 和 Write-Through 的核心差異是什麼?為什麼面試預設選 Cache-Aside?
- Cache-Aside:Application 自己管理快取。讀取時先查 cache,miss 就查 DB 並寫入 cache。Cache 和 DB 分開管理。
- Write-Through:Application 寫入 cache → cache 同步寫入 DB。兩者都完成才算寫入成功。
預設 Cache-Aside 的原因:
- 不依賴特殊的快取基礎設施(Redis 原生不支援 Write-Through)
- 程式碼明確,容易追蹤錯誤
- Write-Through 仍有 dual-write 問題(cache 成功 / DB 失敗,反之亦然)
Question 4 - Write-Behind 風險 [recall]
Write-Behind(Write-Back)的主要風險是什麼?適合什麼場景?
風險:cache 在把資料 flush 到 DB 之前崩潰 → 資料永久遺失。
適合:高寫入吞吐量、可接受最終一致性的場景。
- 分析 / metrics pipeline
- 計數器(按讚數、播放數的非精確統計)
Question 5 - Cache Stampede [recall]
什麼是 Cache Stampede(快取雪崩)?最有效的解決方案是什麼?
Cache Stampede:熱門快取項目過期時,大量請求同時 miss,直接打到 DB,可能把 DB 打垮。
最有效解:Request Coalescing(請求合併 / Single Flight) —— 只讓一個請求去重建快取,其他請求等待那個結果。
其他解:cache warming(過期前主動刷新)—— 只在 TTL 過期模式有效。
Question 6 - Eviction Policy 錯誤敘述 [recall]
以下關於 eviction policy 的敘述,何者錯誤?
(A) LRU 移除最久沒被存取的資料
(B) LFU 移除存取次數最少的資料
(C) FIFO 是生產環境最常用的策略
(D) TTL 通常搭配 LRU 或 LFU 一起使用
答案:(C)
FIFO 很少在生產環境使用,因為它完全忽略使用模式,可能移除正在被頻繁存取的項目。
LRU 才是最常用的預設策略(90% 工作負載適合)。
Question 7 - Hot Key 問題 [application]
如果你的系統有一個極端熱門的快取 key(例如名人的個人資料),可能造成什麼問題?列舉三個解決方案。
問題:Hot Key —— 單一 key 收到大量流量,可能讓某個 Redis 節點過載成為瓶頸。整體 hit rate 高也救不了。
解法:
- 複製熱 key:把同樣的值存在多個快取節點上,分散讀取負載
⚠️ 各副本 TTL 錯開,否則同時過期會觸發 Stampede - 加行程內備援快取:把極端熱門的值存在 application 行程內,避免一直打 Redis
- Rate Limiting:對特定 key 的異常流量踩煞車
Question 8 - 五步驟面試話術 [recall]
面試中介紹快取策略的五個步驟是什麼?
- 確認瓶頸:指出快取要解決的具體問題(DB CPU 高、查詢慢、計算貴)
- 決定快取什麼:選讀取頻繁、不常變動、取得成本高的資料
- 選擇快取架構:預設 Cache-Aside;靜態資源加 CDN;極端熱 key 加 in-process
- 設定淘汰策略:預設 LRU + TTL
- 說明缺點:失效策略、故障降級(circuit breaker)、Stampede 應對
Question 9 - 何時用 CDN [application]
系統設計面試中,引入 CDN 最穩妥的理由是什麼?什麼時候不該用 CDN 當第一個答案?
最穩妥:系統需要大規模傳遞靜態媒體資源(.png、.jpg、.svg、.mp4)。
CDN 邊緣節點 20–40ms vs 跨洲源站 250–300ms,差距明顯。
不該當第一個答案:純 API / 動態內容為主的系統。雖然現代 CDN 也能快取 API 回應,但這會被面試官追問一堆問題(cache key 設計、invalidation、edge logic)。先講 Redis 外部快取,CDN 視題目再加。
Question 10 - 一致性策略選擇 [application]
你正在設計一個社群媒體 App 的用戶 profile cache。用戶可以隨時更新自己的暱稱和大頭照。請選擇並說明一個 cache invalidation 策略,包含取捨。
建議:寫入時失效(Cache-Aside + delete)+ 適度 TTL
更新 profile:
1. UPDATE users SET ... WHERE id = ?
2. cache.delete("user:{id}:profile")
讀取 profile:
1. 查 cache,hit 就回
2. miss → 查 DB → set cache (TTL 10 分鐘)
取捨:
- ✅ 用戶自己馬上看到變更(cache.delete 之後下次讀填新值)
- ⚠️ Dual-write race:DB 更新成功但 cache.delete 失敗 → 別人看到舊值最多 10 分鐘(TTL 自然刷新)
- 💡 對社群 profile,短暫不一致可接受,不需要分散式 transaction
Question 11 - Cache + DB 一致性根本問題 [analysis]
「Cache 和 DB 兩個儲存系統永遠不會 100% 一致」——這個說法對嗎?為什麼?
基本正確。
Cache 和 DB 是兩個獨立系統,沒有跨系統的分散式 transaction。任何寫入路徑都有一個窗口可能不一致:
- 先寫 DB 再 delete cache:兩步之間有人讀到舊 cache
- 先 delete cache 再寫 DB:兩步之間有 cache miss → 寫入舊值到 cache
- 同步 write-through:cache 成功 / DB 失敗 → 兩邊不一致
沒有完美解,只能根據業務選策略:
- 用 TTL 把不一致窗口限制在可接受時間內
- 用 CDC(Change Data Capture) 監聽 DB 變更非同步更新 cache
- 對強一致需求的資料乾脆不快取
Question 12 - Redis 掛了 [application]
你的系統重度依賴 Redis 快取,DB 在尖峰時被快取擋掉 80% 流量。如果 Redis 掛了,會發生什麼?怎麼設計才能撐住?
沒處理會發生:所有讀取突然打到 DB(流量 5×),DB CPU 100%,連鎖故障 → cascading failure。
設計:
- 降級直連 DB + Circuit Breaker:偵測 Redis 不可用,請求改走 DB;但 circuit breaker 限制流量,避免暴流壓垮 DB
- In-Process Cache 當最後防線:極熱 key 同時放行程內,Redis 掛了也能擋一部分
- Redis 本身做高可用:sentinel / cluster + replica + automatic failover(這是預防,不是降級)
- Graceful degradation:非核心功能(推薦、related items)失敗時返回降級結果,核心讀寫優先
💡 面試話術:「Cache 是性能優化,不是業務必需。Cache 故障時系統應該變慢但不該崩潰。」