1. 程式人生 > >緩存擊穿、緩存穿透和緩存雪崩

緩存擊穿、緩存穿透和緩存雪崩

進行 自然 tex 隊列 方案 不同的 不同 雪崩 hash

緩存擊穿

定義: 緩存中的key一般設有過期時間,如果某個key過期了,恰在這個時候,有大量的並發請求訪問這個key,則這些請求都會到達DB,導致DB瞬間壓力過大,壓垮DB。

解決方案: 1.設置互斥鎖,mutex。當緩存失效時不時立即去訪問數據庫,而是使用緩存工具的操作成功帶返回值的操作,比如redis的setnx(set if not exit),memcache的add,利用setnx實現鎖的效果。

缺點:可能造成死鎖,或線程池阻塞

2.提前使用互斥鎖

redist的超時時間是timeout1,value的超時時間是timeout2,timeout2 < timeout1。 當timeout2超時時,延長timeout2的時間。並重新設置到redis中。

3.永遠不過期

不設置過期時間。

把過期時間設到value裏,如果快要過期了,通過一個後臺異步線程進行緩存的構建,也就是邏輯過期。

緩存穿透

定義: 指有人用數據庫中不存在的某個key訪問,數據庫中沒有該key值,自然緩存中也不會有,該請求會直接到數據庫。如果對該key的並發訪問量過大,則會壓垮數據庫。

解決方案:

1. 采用過濾器,把所有數據庫中不可能存在的數據hash到一張大的bitmap中,如果key在數據庫中不存在,將會被bitmap攔截。

2. 對查出為空的key,也在緩存中簡歷key value對,只是過期時間設的短一點,比如5minetes。

緩存雪崩

定義: 指緩存中大量的數據在同一時間失效,這時有大量的請求會被直接轉到數據庫,造成數據庫的壓力過大。

解決方案:1. 加鎖,加隊列,如mq,保證緩存的單線程寫,避免key失效時,大量並發到達數據庫。

2.把緩存失效時間錯開。比如在原有失效時間上加一個隨機值,比如1-5分鐘,這樣失效時間的重復率降低,降低集體失效的概率。

總結

緩存雪崩是大量key同時失效事件,而緩存擊穿和緩存穿透都是都是單個key失效,大量請求訪問該key;不同的是緩存擊穿,key對應的value值存在於數據庫中,而緩存穿透的key, value不存在數據庫中,可能被用來惡意攻擊。

緩存擊穿、緩存穿透和緩存雪崩