前面幾篇關于緩存的文章主要介紹了相關原理,本篇從業務應用角度講述相關的使用政策。
有興趣朋友可以關注公衆号“架構之道與術”, 擷取最新文章。
或掃描如下二維碼:
緩存更新政策
被動更新
設定key過期的時間,讓其自動失效。
主動更新
更新DB的時候,同時更新緩存。一般業務都是主動更新和被動更新結合使用。
先更新DB,後更新緩存
對于主動更新來說,存在一個問題:你是先更新緩存,後更新DB;還是反過來?
下面分别分析以下2個場景,假設有2個線程,t1, t2:
(1) 先更新緩存,後更新DB。假設有如下的執行系列:
t1更新緩存;
t2讀緩存,因為t1把緩存更新了,導緻t2沒讀到。從db中讀,然後更新緩存;
t1更新DB。
上述操作系列會導緻緩存髒資料。
(2)先更新DB,後更新緩存。假設有如下操作序列:
t1更新DB;
t2更新DB;
t2更新緩存;
t1更新緩存。
上述操作系列同樣會導緻緩存髒資料。
一句話,無論誰先誰後,隻要更新緩存和更新DB不是原子的,就可能導緻不一緻。隻是從實際業務來講,一般緩存也都是保持“最終一緻性“,而不是和DB的強一緻性。
并且一般建議先更新DB,再更新緩存,優先保證DB資料正确。
但如果一定要“強一緻性“,就不能用上面的解決方案了。有一個解決辦法就是不要更新緩存,而是直接删除緩存(讓緩存過期),但這會增加緩存的miss率。
緩存更新的實作政策
政策1:業務方(調用者)更新
傳統上,更新緩存都是由業務方來做,也就是由調用者負責更新DB和緩存。
政策2:DB中間件監聽DB變化,更新緩存
現在有種新的辦法就是利用DB中間件監聽DB變化(比如阿裡的Canal中間件,點評的Puma),進而對緩存進行更新。
這種辦法的一個好處就是:把緩存的更新邏輯,和業務邏輯解藕。業務隻更新DB,緩存的更新被放在另外一個專門的系統裡面。
緩存穿透
所謂“緩存穿透“,就是指某個key,先查cache沒查到,再查db也沒有查到。
這種key的存在,會導緻cache一直沒辦法命中,壓力一直打在db上面。如果通路很高頻,可能會壓垮DB。
解決辦法其實也很簡單:當查詢DB沒查到時,往緩存中寫入一個空值(預設值),這樣第2次再查,就不會打到DB上了。
緩存雪崩
所謂“緩存雪崩“,是指緩存的機器挂了,所有請求直接打到DB上面,進而導緻DB也挂掉。
這種問題的解決政策,一般有以下2個方面:
(1)提高緩存的HA。比如緩存的主從複制。
(2)對DB的通路實行限流、降級。
關于限流、降級的做法,參見分布式序列的另外一篇文章“服務熔斷、降級、限流、異步RPC – HyStrix“。