旁路緩存模式的核心思想是:將緩存視為一個獨(dú)立的、速度更快的輔助系統(tǒng),應(yīng)用程序直接負(fù)責(zé)與緩存和數(shù)據(jù)庫進(jìn)行交互。 緩存是數(shù)據(jù)庫的“旁路”,而不是數(shù)據(jù)庫的代理。
其基本原則是:
- 讀取時,先讀緩存,緩存未命中再讀數(shù)據(jù)庫。
- 寫入時,直接更新數(shù)據(jù)庫,然后使緩存中的舊數(shù)據(jù)失效。
詳細(xì)流程分解
1. 讀請求流程
當(dāng)一個讀取請求到達(dá)時,流程如下:

步驟解析:
- 接收讀請求:應(yīng)用程序接收到一個根據(jù)Key讀取數(shù)據(jù)的請求。
- 嘗試從緩存讀取:應(yīng)用程序首先查詢緩存(如 Redis, Memcached)中是否存在這個Key的數(shù)據(jù)。
- 緩存命中:如果緩存中存在該數(shù)據(jù),應(yīng)用程序直接返回緩存中的數(shù)據(jù)。流程結(jié)束。
- 緩存未命中:查詢主數(shù)據(jù)庫,把從數(shù)據(jù)庫中查到的數(shù)據(jù)寫入緩存中。
為什么要在緩存未命中后寫入緩存?
這是一種“懶加載”思想,只有被實際請求的數(shù)據(jù)才會被加載到緩存中,避免了冷數(shù)據(jù)占用寶貴的緩存空間。
2. 寫請求流程
當(dāng)一個寫入請求到達(dá)時,流程如下:

步驟解析:
- 接收寫請求:應(yīng)用程序接收到一個寫入數(shù)據(jù)的請求。
- 更新主數(shù)據(jù)庫:應(yīng)用程序直接更新主數(shù)據(jù)庫中的數(shù)據(jù)。這是唯一的事實來源。
- 刪除緩存數(shù)據(jù):在成功更新數(shù)據(jù)庫之后,應(yīng)用程序刪除緩存中對應(yīng)的Key。
為什么是“刪除”而不是“更新”緩存?主要為了避免數(shù)據(jù)競爭和浪費(fèi):
- 數(shù)據(jù)競爭:在高并發(fā)場景下,兩個并發(fā)的寫操作可能以不同的順序完成“更新數(shù)據(jù)庫”和“更新緩存”這兩個步驟,導(dǎo)致緩存中最終留下的是舊數(shù)據(jù)。例如:請求A和B同時更新同一條數(shù)據(jù)。A先更新緩存,B先更新數(shù)據(jù)庫。最終數(shù)據(jù)庫是B的值,但緩存是A的值,數(shù)據(jù)不一致。
- 浪費(fèi):如果一次寫入后,該數(shù)據(jù)很長時間不被讀取,那么這次“更新緩存”的操作就是浪費(fèi)資源的。直接刪除它,等到下次需要時再加載(懶加載),更高效。
旁路緩存模式的優(yōu)缺點(diǎn)
優(yōu)點(diǎn)
- 簡單直觀:邏輯清晰,易于理解和實現(xiàn)。
- 緩存命中率高:通過“懶加載”,緩存中存放的都是真正被請求的熱點(diǎn)數(shù)據(jù)。
- 容錯性好:如果緩存集群完全崩潰,系統(tǒng)仍然可以通過直接訪問數(shù)據(jù)庫來繼續(xù)工作(盡管性能會下降)。數(shù)據(jù)庫是系統(tǒng)的“壓艙石”。
- 避免寫操作的復(fù)雜性:寫操作只需要處理數(shù)據(jù)庫和刪除緩存,避免了同時更新緩存和數(shù)據(jù)庫可能帶來的復(fù)雜一致性問題。
缺點(diǎn)與挑戰(zhàn)
-
緩存不一致窗口期:在寫操作中,從“更新數(shù)據(jù)庫”到“刪除緩存”之間有一個極短的時間窗口,在這期間緩存是舊數(shù)據(jù),數(shù)據(jù)庫是新數(shù)據(jù)。如果此時有讀請求,會讀到舊數(shù)據(jù)。
- 解決方案:可以通過設(shè)置較短的緩存過期時間作為兜底策略,或者使用更復(fù)雜的機(jī)制(如訂閱數(shù)據(jù)庫binlog來刪除緩存)。
-
緩存穿透:當(dāng)一個數(shù)據(jù)在數(shù)據(jù)庫和緩存中都不存在時,每次請求都會穿透到數(shù)據(jù)庫,可能導(dǎo)致數(shù)據(jù)庫壓力過大。
-
解決方案:對于不存在的數(shù)據(jù),也在緩存中設(shè)置一個空值(如
NULL)并設(shè)置一個較短的過期時間。
-
解決方案:對于不存在的數(shù)據(jù),也在緩存中設(shè)置一個空值(如
-
緩存擊穿:某個熱點(diǎn)Key在緩存過期的瞬間,有大量請求同時涌入,全部穿透到數(shù)據(jù)庫。
- 解決方案:使用互斥鎖(分布式鎖),只讓一個請求去數(shù)據(jù)庫加載數(shù)據(jù),其他請求等待。
-
緩存雪崩:在同一時間大量緩存Key過期,導(dǎo)致所有請求都涌向數(shù)據(jù)庫。
- 解決方案:給緩存Key設(shè)置隨機(jī)的過期時間,避免同時大量失效。
總結(jié)
旁路緩存模式是一種非常經(jīng)典和實用的緩存設(shè)計模式。它的核心在于 “讀時懶加載,寫時刪緩存” 。雖然它無法實現(xiàn)絕對的強(qiáng)一致性,存在一個短暫的不一致窗口,但其簡單性、高容錯性和高命中率使其成為絕大多數(shù)業(yè)務(wù)場景的首選方案。在實際應(yīng)用中,需要結(jié)合緩存穿透、擊穿、雪崩等問題的解決方案來構(gòu)建一個健壯的緩存系統(tǒng)。