緩存穿透與熱點緩存等問題的解決方案

不管我們使用的哪種緩存產品,基本上都會遇到緩存擊穿、緩存失效以及熱點key的問題。一旦出現上述問題,如洪水般的請求會涌向后臺DB服務器,輕則應用遲緩,重則整個應用系統癱瘓。

1- 緩存并發更新控制

一個共享緩存失效后,接下來有多個線程嘗試從后臺數據庫服務器獲取數據來更新緩存時,因為只需要一個線程完成從數據庫中取數據然后在放在緩存內即可,然后其他線程再去取這個緩存,并需要并發的更新這個緩存。

解決方案

使用鎖機制(緩存服務器集群環境下,使用分布式鎖),在緩存更新或者過期的情況下,先嘗試獲取到鎖,當更新或者從數據庫獲取完成后再釋放鎖,其他的請求只需要犧牲一定的等待時間,即可直接從緩存中繼續獲取數據,效率較高。可在緩存更新方法上加上sychronized修飾。

2- 緩存擊穿

也叫緩存穿透,查詢一個數據庫中不存在的數據,比如商品詳情,查詢一個不存在的ID,每次都會訪問DB,可能不會被關注,但是這個卻是造成數據庫高負載的元兇。

解決方案
  1. 緩存空對象
    當通過某一個key去查詢數據的時候,如果對應在數據庫中的數據都不存在,我們將此key對應的value設置為一個默認的值,比如“NULL”,并設置一個緩存的失效時間,這時在緩存失效之前,所有通過此key的訪問都被緩存擋住了。后面如果此key對應的數據在DB中存在時,緩存失效之后,通過此key再去訪問數據,就能拿到新的value了。這種方式實現起來成本較低,比較適合命中不高,但可能被頻繁更新的數

  2. 單獨過濾處理
    對所有可能對應數據為空的key進行統一的存放,并在請求前做攔截,這樣避免請求穿透到后端數據庫。這種方式實現起來相對復雜,比較適合命中不高,但是更新不頻繁的數據。

3- 緩存顛簸

緩存的顛簸問題,有些地方可能被成為“緩存抖動”,可以看做是一種比“雪崩”更輕微的故障,但是也會在一段時間內對系統造成沖擊和性能影響。一般是由于緩存節點故障導致。

解決方案

業內推薦的做法是通過一致性Hash算法來解決。

4- 熱點Key

緩存中的某些Key(可能對應用與某個促銷商品)對應的value存儲在集群中一臺機器,使得所有流量涌向同一機器,成為系統的瓶頸,該問題的挑戰在于它無法通過增加機器容量來解決。

解決方案
  1. 客戶端熱點key緩存:將熱點key對應value并緩存在客戶端本地,并且設置一個失效時間。對于每次讀請求,將首先檢查key是否存在于本地緩存中,如果存在則直接返回,如果不存在再去訪問分布式緩存的機器。
  2. 服務端負載均衡:將熱點key復制多個副本,然后存儲到緩存集群的不同機器上。當通過熱點key去查詢數據時,通過某種hash算法隨機選擇一個副本機器訪問緩存,將熱點分散到了不同機器上。

5- 緩存雪崩

緩存雪崩就是指由于緩存的原因,導致大量請求到達后端數據庫,從而導致數據庫崩潰,整個系統崩潰,發生災難。

解決方法

場景1:導致這種現象的原因有很多種,上面提到的“緩存并發”,“緩存穿透”,“緩存顛簸”等問題,其實都可能會導致緩存雪崩現象發生。

根據上面的解決方法來避免雪崩的發生

場景2: 緩存冷啟動或者大量緩存同時失效,例如某個時間點內,系統預加載的緩存周期性集中失效了,也可能會導致雪崩。

解決方案:

  1. 為了解決冷啟動的問題,啟動時,先預熱緩存,根據實際業務估算將數據從數據庫總load到緩存中,注意要分批次load,防止DB崩潰。
  2. 為了避免這種周期性大量緩存同時失效,可以通過設置不同的過期時間,來錯開緩存過期,從而避免緩存集中失效。
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容