快取擊穿、快取穿透和快取雪崩
快取擊穿
定義: 快取中的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不存在資料庫中,可能被用來惡意攻擊。