高效能快取實踐-快取擊穿

2020-10-01 13:00:10

目標

快取擊穿

快取擊穿: 某一個熱點資料(key),在某一瞬間失效,導致大量的請求存取這一個熱點資料,擊穿快取,直接查詢資料庫。

wsupi6.png

解決方法:

熱點key永不過期

對於一個非常熱點的資料(key),直接設定快取永久不過期。

參照其他部落格的:「我們對主打商品都是早早的做好了準備,讓快取永不過期。即便某些商品自己發酵成了爆款,也是直接設為永不過期就好了。」

優點:方式簡單粗暴。

缺點:僅適用於基本不變化的資料。

定時更新或者檢查更新

參考 應對快取擊穿的解決方法

定時更新:

後臺定義一個job(定時任務)專門主動更新快取資料.比如,一個快取中的資料過期時間是30分鐘,那麼job每隔29分鐘定時重新整理資料(將從資料庫中查到的資料更新到快取中)。

不足:增加系統複雜度。比較適合那些 key 相對固定,cache 粒度較大的業務,key 比較分散的則不太適合,實現起來也比較複雜。

檢查更新:

將快取key的過期時間(絕對時間)一起儲存到快取中(可以拼接,可以新增新欄位,可以採用單獨的key儲存…不管用什麼方式,只要兩者建立好關聯關係就行).在每次執行get操作後,都將get出來的快取過期時間與當前系統時間做一個對比,如果快取過期時間-當前系統時間<=1分鐘(自定義的一個值),則主動更新快取.這樣就能保證快取中的資料始終是最新的(和方案一一樣,讓資料不過期.)

不足:假如在最後臨近的一分鐘沒有請求來獲取快取資料,有可能導致快取過期,並沒有重新載入。導致接下來的時間,大量請求到來,依然會出現快取擊穿。

互斥鎖

使用互斥鎖就已經預設會出現,大量請求在同一時間,存取一個失效的熱點資料的情況。通過互斥鎖,只允許第一個執行緒獲得鎖,存取資料庫獲得資料再設定到快取中,其他執行緒等待,從更新的快取中獲得熱點資料。

單體應用可以使用(ReentrantLock)來實現互斥鎖。分散式系統可以使用分散式鎖(Redis setnx)(ZooKeeper) 等。

綜上

在閱讀一些部落格中,也提到了使用 hystrix 來實現資源隔離,還沒有研究,等研究了再實踐。

大道至簡,對於解決方法的選擇,不一定越複雜的越好,黑貓白貓逮到wsnzIx.png就是wsnxd1.png

在這裡插入圖片描述