天天看點

緩存失效、穿透、并發、雪崩問題及解決方法

1 緩存失效

  引起這個原因的主要因素是高并發下,一般設定一個緩存的過期時間時,并發很高時可能會出在某一個時間同時生成很多的緩存,并且過期時間在同一時刻,這個時候就可能引發——當過期時間到後,這些緩存同時失效,請求全部轉發到DB,DB可能會壓力過重。

  處理方法: 将緩存失效時間分散開,不要是以緩存時間長度都設定成特定時長;比如在原有的失效時間基礎上增加一個随機值,比如1-5分鐘随機,這樣每一個緩存的過期時間的重複率就會降低,就很難引發集體失效的事件。 緩存失效時産生的雪崩效應,将所有請求全部放在資料庫上,這樣很容易就達到資料庫的瓶頸,導緻服務無法正常提供。盡量避免這種場景的發生。

2 緩存穿透

  出現場景:指查詢一個一定不存在的資料,由于緩存是不命中時被動寫的,并且出于容錯考慮,如果從存儲層查不到資料則不寫入緩存,這将導緻這個不存在的資料每次請求都要到存儲層去查詢,失去了緩存的意義。

  當在流量較大時,出現這樣的情況,一直請求DB,很容易導緻服務挂掉。

  處理方法:

  方法1.在封裝的緩存SET和GET部分增加個步驟,如果查詢一個KEY不存在,就已這個KEY為字首設定一個辨別KEY;以後再查詢該KEY的時候,先查詢辨別KEY,如果辨別KEY存在,就傳回一個協定好的非false或者NULL值,然後APP做相應的處理,這樣緩存層就不會被穿透。當然這個驗證KEY的失效時間不能太長,當db有值時,利用消息服務清除緩存空資料。

  方法2.如果一個查詢傳回的資料為空(不管是資料不存在,還是系統故障),我們仍然把這個空結果進行緩存,但它的過期時間會很短,一般隻有幾分鐘。

  方法3.采用布隆過濾器,将所有可能存在的資料哈希到一個足夠大的bitmap中,一個一定不存在的資料會被這個bitmap攔截掉,進而避免了對底層存儲系統的查詢壓力。

3 緩存并發

  出現場景:當網站并發通路高,一個緩存如果失效,可能出現多個程序同時查詢DB,同時設定緩存的情況,如果并發确實很大,這也可能造成DB壓力過大,還有緩存頻繁更新的問題。

  處理方法:對緩存查詢加鎖,如果KEY不存在,就加鎖,然後查DB入緩存,然後解鎖;其他程序如果發現有鎖就等待,然後等解鎖後傳回資料或者進入DB查詢。

4 緩存雪崩

  出現場景:由于緩存層承載着大量請求,有效的保護了存儲層,但是如果緩存層由于某些原因整體不能提供服務,于是所有的請求都會達到存儲層,存儲層的調用量會暴增,造成存儲層也會挂掉的情況。 緩存雪崩的英文原意是 stampeding herd(奔逃的野牛),指的是緩存層宕掉後,流量會像奔逃的野牛一樣,打向後端存儲。

  處理方法:緩存高可用,Redis Sentinel 和 Redis Cluster 實作

參考文檔

http://mp.weixin.qq.com/s/jy1q3OnbANEmQR750f0S6Q

https://mp.weixin.qq.com/s/TBCEwLVAXdsTszRVpXhVug

繼續閱讀