一、問題
- 當前 key 是一個熱點 key( 同一個key,同一個時候有幾十萬請求),併發量非常
- 重建緩存不能在短時間完成,可能是一個複雜計算,例如複雜的 SQL、多次 IO、多個依賴等。
二、影響
在緩存失效的瞬間,有大量線程來重建緩存 ( 如下圖),造成後端負載加大,甚至可能會讓應用崩潰。
三、解決這些問題要實現的目標
減少重建緩存的次數
數據儘可能一致
較少的潛在危險
四、方案
4.1 分佈式鎖
只允許一個線程重建緩存,其他線程等待重建緩存的線程執行完,重新從緩存獲取數據即可
方案優缺點
- 建緩存過程出現問題或者時間較長,可能會存在死鎖和線程池阻塞的風
- 能夠較好的降低後端存儲負載
- 能夠較好的數據一致性
4.2 、讓熱鍵永遠不過期
- 緩存層面:不要設置key過期時間,不會出現熱點key過期後產生的問題
- 功能層面:要設置value過期時間,當發現value過期後,會使用單獨的線程去構建緩存
方案優缺點
- 有效杜絕了熱點 key 產生的問題
- 重構緩存期間,會出現數據不一致的情況,這取決於應用方是否容忍這種不一致。
- 同時代碼複雜度會增大。(下面是代碼邏輯)
- 通過key獲取value
- 通過value獲取timeOut
- timeOut過期(對比當前時間)
- 分佈式鎖
- 更新value值
五、兩種方案對比