文章目錄
- 緩存全景圖
- Pre
- 緩存讀寫模式概述
- 1. Cache Aside(旁路緩存)
- 工作流程
- 優缺點
- 2. Read/Write Through(讀寫穿透)
- 工作流程
- 優缺點
- 典型場景
- 3. Write Behind Caching(異步寫回)
- 工作流程
- 優缺點
- 典型場景
- 緩存分類及常用組件
- 1. 按宿主層次分類
- 2. 按存儲介質分類
- 場景對比與權衡
- 小結
緩存全景圖
Pre
每日一博 - 圖解5種Cache策略
架構思維:緩存層場景實戰_讀緩存(下)
緩存讀寫模式概述
在業務系統中,引入緩存主要為了降低數據庫壓力、提升響應性能,但也帶來了數據一致性和維護成本的挑戰。
根據緩存和數據庫的更新策略,常見有三種讀寫模式:
-
Cache Aside(旁路緩存)
-
Read/Write Through(讀寫穿透)
-
Write Behind Caching(異步緩存寫入)
下面逐一詳細介紹。
1. Cache Aside(旁路緩存)
工作流程
-
寫操作:
- 應用先更新數據庫
- 刪除 Cache 中對應的 key
- 由數據庫變更日志或下游 Trigger 驅動重新計算并回寫緩存
-
讀操作:
- 應用先查詢 Cache
- 若未命中,則加載數據庫數據
- 將結果寫入 Cache,并返回給調用方
寫 ? Update DB ? DEL cache[key]
讀 ? GET cache[key] ? Miss ? Query DB ? SET cache[key] ? Return
優缺點
-
優點
- 以數據庫為準,強一致性風險低
- 緩存回寫采用延遲(Lazy)計算,可靈活處理復雜業務
-
缺點
- 業務端需同時維護 Cache 和 DB 訪問邏輯,代碼復雜度高
- 觸發緩存回寫依賴日志或 Trigger,增加組件依賴
2. Read/Write Through(讀寫穿透)
工作流程
由緩存存儲服務(Cache Service)統一代理讀寫,業務應用只與存儲服務交互。
如上圖,對于 Cache Aside 模式,業務應用需要同時維護 cache 和 DB 兩個數據存儲方,過于繁瑣,于是就有了 Read/Write Through 模式。在這種模式下,業務應用只關注一個存儲服務即可,業務方的讀寫 cache 和 DB 的操作,都由存儲服務代理。存儲服務收到業務應用的寫請求時,會首先查 cache,如果數據在 cache 中不存在,則只更新 DB,如果數據在 cache 中存在,則先更新 cache,然后更新 DB。而存儲服務收到讀請求時,如果命中 cache 直接返回,否則先從 DB 加載,回種到 cache 后返回響應。
-
寫操作:
- 存儲服務查 Cache
- 若命中,先更新 Cache,再同步寫入 DB
- 若未命中,僅更新 DB
-
讀操作:
- 存儲服務查 Cache
- 命中則直接返回
- 未命中則加載 DB,然后回寫 Cache,再返回
寫 ? 存儲服務(GET cache) ? Hit: SET cache + Update DB? Miss: Update DB
讀 ? 存儲服務(GET cache) ? Miss ? Load DB ? SET cache ? Return
優缺點
-
優點
- 業務端代碼只關注存儲服務,隔離性好
- 僅為“熱”數據更新緩存,內存利用率高
-
缺點
- 寫路徑較 Cache Aside 更同步,寫延遲略高
典型場景
- 有明顯“熱”與“冷”數據區分的業務
3. Write Behind Caching(異步寫回)
工作流程
由緩存存儲服務(Cache Service)統一代理讀寫,業務應用只與存儲服務交互。
Write Behind Caching 模式與 Read/Write Through 模式類似,也由數據存儲服務來管理 cache 和 DB 的讀寫。不同點是,數據更新時,Read/write Through 是同步更新 cache 和 DB,而 Write Behind Caching 則是只更新緩存,不直接更新 DB,而是改為異步批量的方式來更新 DB。該模式的特點是,數據存儲的寫性能最高,非常適合一些變更特別頻繁的業務,特別是可以合并寫請求的業務,比如對一些計數業務,一條 Feed 被點贊 1萬 次,如果更新 1萬 次 DB 代價很大,而合并成一次請求直接加 1萬,則是一個非常輕量的操作。但這種模型有個顯著的缺點,即數據的一致性變差,甚至在一些極端場景下可能會丟失數據。比如系統 Crash、機器宕機時,如果有數據還沒保存到 DB,則會存在丟失的風險。所以這種讀寫模式適合變更頻率特別高,但對一致性要求不太高的業務,這樣寫操作可以異步批量寫入 DB,減小 DB 壓力。
與 Read/Write Through 相似,均由存儲服務管理:
-
寫操作:
- 只更新 Cache
- 存儲服務后臺異步批量合并寫 DB
-
讀操作:
同 Read/Write Through 模式
寫 ? 存儲服務(SET cache) ? Async Batch Write → DB
讀 ? GET cache ? Miss ? Load DB ? SET cache ? Return
優缺點
-
優點
- 寫性能最高,適合超高并發、可合并請求的場景
- 如計數類業務,將多次加操作合并為一次 DB 更新
-
缺點
- 數據一致性最差,且在崩潰/宕機時可能丟失未刷盤的數據
典型場景
- 對一致性要求不高,但寫入頻率極高的業務
- 如熱點計數、流量統計等
我們可以看到緩存的三種讀寫模式各有優劣,不存在最佳模式。實際上,我們也不可能設計出一個最佳的完美模式出來,如同空間換時間、訪問延遲換低成本一樣,高性能和強一致性從來都是有沖突的,系統設計從來就是取舍,隨處需要 trade-off。
如何根據業務場景,更好的做 trade-off,從而設計出更好的服務系統。
緩存分類及常用組件
1. 按宿主層次分類
-
本地 Cache(進程內):
- 組件:Guava Cache、Ehcache(嵌入模式)
- 優勢:極低延遲、零網絡開銷;
- 劣勢:隨進程重啟丟失、容量受限。
-
進程間 Cache(同機獨立進程):
- 組件:獨立部署的 Redis/Memcached 實例(與業務進程同機)
- 優勢:重啟不丟數據、減少部分網絡延遲;
- 劣勢:本機資源競爭,運維較復雜。
-
遠程 Cache(跨機部署):
- 組件:集群化的 Redis/Memcached/Pika
- 優勢:容量與擴展性最佳;
- 劣勢:網絡延遲與帶寬瓶頸。
2. 按存儲介質分類
-
內存型緩存:
- 數據駐留內存,讀寫延遲微秒級;
- 重啟或崩潰后數據丟失。
- 典型:Memcached、Redis(無 AOF/RDB 時)。
-
持久化型緩存:
- 數據寫入 SSD/RocksDB 等介質,容量大一個量級;
- 重啟不丟失,但讀寫延遲高出 1–2 個數量級。
- 典型:Pika、基于 RocksDB 的緩存方案。
場景對比與權衡
-
一致性 vs. 性能:
- Cache Aside 最強一致性,Read/Write Through 次之,Write Behind 最弱;
-
開發與運維成本:
- Cache Aside 代碼最復雜,Read/Write Through 與 Write Behind 降低業務端復雜度;
-
響應延遲與吞吐:
- Write Behind 寫性能最高,Read/Write Through 讀寫均衡,Cache Aside 讀性能最佳。
根據業務特性(訪問熱點、更新頻度、一致性需求),在三種模式與不同部署/存儲選型中做權衡,才能打造符合需求的緩存架構。
小結
我們樹立了三種緩存讀寫模式——Cache Aside、Read/Write Through、Write Behind Caching
——及其適用場景;
- Cache Aside:業務先讀寫數據庫、刪除緩存,通過懶加載方式在下一次讀時回填緩存,確保以數據庫為準。
- Read/Write Through:所有讀寫請求都由緩存服務統一代理,緩存命中則讀寫緩存并同步數據庫,未命中則回源數據庫并回填緩存。
- Write Behind Caching:寫操作只更新緩存,后臺異步批量合并寫入數據庫,以最高寫吞吐換取可容忍的數據一致性降低。