當資料庫成為瓶頸時,比如高併發、讀多寫少等場景,我們首先會想到的就是利用快取來提高整個系統的效能。
快取雖然能夠大大提升整個系統的效能,但同時也引入了更多複雜性。
如果沒有針對快取進行比較好的處理,某些場景下甚至會導致整個系統崩潰。
這次我們要聊的就是:快取雪崩。
快取雪崩
快取雪崩是指當快取失效或過期後引起系統效能急劇下降的情況。
當快取失效或過期被清除後,系統需要再次訪問資料庫,再次進行運算重新生成快取,這個處理步驟耗時比較長,上百毫秒甚至更長時間。而對於一個高併發的系統來說,幾百毫秒內可能會接到幾百個請求。
由於舊的快取已經被清除,新的快取還未生成,並且處理這些請求的執行緒都不知道另外有一個執行緒正在生成快取,所以所有的請求都會去重新生成快取,都會去訪問資料庫,對資料庫造成巨大的壓力和不必要的效能損耗。
這些對資料庫的訪問壓力又會拖慢整個系統,嚴重的會造成資料庫當機,形成一系列連鎖反應,造成整個系統崩潰。
解決辦法
快取雪崩的常用解決方法有兩種:更新鎖機制和後臺更新機制。接下來我們詳細瞭解一下這兩種方法:
更新鎖機制
對快取更新操作加入鎖的保護,保證只有一個執行緒能夠進行快取更新的操作,沒有獲取更新鎖的執行緒要麼等待鎖釋放後重新讀取快取,要麼直接返回空值或者預設值。
對於採用分散式叢集的系統,一個系統中可能存在幾十上百臺伺服器,即使單臺伺服器只有一個執行緒更新快取,但幾十上百臺伺服器一起算下來也會有幾十上百個執行緒同時進行快取更新的操作,同樣存在快取雪崩的問題。
所以分散式叢集的系統要實現更新鎖機制,需要用到分散式鎖,比如:Redis、ZooKeeper等。
後臺更新機制
在系統中,由後臺執行緒來進行快取更新的操作,而不是由業務執行緒來進行快取更新的操作,快取本身的有效期可以設定為永久或者足夠長的時間,後臺執行緒定時進行快取更新的操作。
後臺更新機制不僅適用於單機多執行緒的場景,也適用於分散式叢集的場景,相比更新鎖機制要簡單一些。
後臺更新機制還適用於業務剛上線的時候進行快取預熱。
快取預熱指系統上線後,將相關的快取資料直接載入到快取系統,而不是等待使用者訪問才來觸發快取載入。
還用一種比較特殊的場景:當快取系統記憶體不夠時,會清除一些快取資料,從快取被清除到下一次定時更新快取的這段時間內,業務執行緒讀取快取返回空值,而業務執行緒本身又不會去更新快取,因此從使用者角度看到就是資料沒有了。
對應上面這種特殊場景,我們可以使用後臺更新機制和更新鎖機制結合使用進行避免。
總結
快取雪崩是指當快取失效或過期後引起系統效能急劇下降的情況。
常用的解決方法有兩種:更新鎖機制和後臺更新機制。
微信公眾號:萬貓學社
微信掃描二維碼
關注後回覆「電子書」
獲取12本Java必讀技術書籍
最後,感謝你的點贊和關注,帥氣又美麗。