1. 程式人生 > 實用技巧 >快取穿透、雪崩、擊穿產生的原因和解決方式

快取穿透、雪崩、擊穿產生的原因和解決方式

1.快取穿透、雪崩、擊穿產生的原因

(1)快取穿透
     <1>查詢一個不存在的資料
     <2>從快取redis沒有命中,需要從mysql資料庫查詢,查不到資料則不寫入快取
     <3>這將導致這個不存在的資料每次請求都要到資料庫去查詢,造成快取穿透
(2)快取雪崩    
     <1>設定快取時採用了相同的過期時間,導致快取在某一時刻同時失效
     <2>請求全部轉發到DB,DB瞬時壓力過重雪崩
(3)快取擊穿(也成為快取併發)
     <1>單個key在快取中查不到或者過期時間的key,去資料庫查詢
     <2>若資料庫資料量大並且是高併發的情況下可能會造成資料庫壓力過大而崩潰
     <3>這裡指的是單個key發生高併發!!!
(4)快取擊穿和快取雪崩區別     
     <1>快取擊穿針對某一key快取
     <2>快取雪崩針對的是很多key
     <3>都是因為key值過期導致

2.快取穿透、雪崩、擊穿解決方案

(1)快取穿透解決方案(2種)
    第一種:採用布隆過濾器(推薦)
    <1>將所有可能存在的資料雜湊到一個足夠大的bitmap中
    <2>一個一定不存在的資料會被 這個bitmap攔截掉
    <3>從而避免了對底層儲存系統的查詢壓力
    第二種:快取空值並設定一個短的過期時間
    <1>一個查詢返回的資料為空,直接設定一個預設值存放到快取
    <2>第二次到緩衝中獲取就有值了,而不會繼續訪問資料庫
    <3>它的過期時間會很短,最長不超過五分鐘
    <4>具體實現雙重驗證鎖解決高併發環境下的快取穿透問題
(2)擴充套件:布隆過濾器
    <1>本質上布隆過濾器是一種set資料結構,比較巧妙的概率型資料結構
    <2>當使用它的 contains 方法判斷某個物件是否存在時,它可能會誤判   
    <3>布隆過濾器說某個值存在時,這個值可能不存在;當說不存在時,那就肯定不存在 
    <4>特點是高效地插入和查詢,佔用空間更少
    <5>缺點是其返回的結果是概率性的,而不是確切的  
(3)快取雪崩解決方案(4種)    
    <1>在快取失效後,通過加鎖或者佇列來控制讀資料庫寫快取的執行緒數量(幾乎不用)
    <2>可以通過快取reload機制,預先去更新快取,再即將發生大併發訪問前手動觸發載入快取
    <3>不同的key,設定不同的過期時間,具體值可以根據業務決定,讓快取失效的時間點儘量均勻
    <4>做二級快取,或者雙快取策略(這種方式複雜點可忽略)
(4)快取擊穿解決方案(3種)
    <1>通過synchronized+雙重檢查機制:某個key只讓一個執行緒查詢,阻塞其它執行緒
       1.1.缺點: 會阻塞其它執行緒
       1.2.在同步塊中,繼續判斷檢查,保證不存在,才去查DB    
    <2> 設定value永不過期
    <3> 使用互斥鎖(mutex key)
       3.1. 業界比較常用的做法,是使用mutex