高併發快取面臨的問題

devilcry13發表於2019-03-08

1. 快取問題

a. 快取併發更新控制

場景:
一個共享快取失效後,接下來有多個執行緒嘗試從後臺資料庫伺服器獲取資料來更新快取時,因為只需要一個執行緒完成從資料庫中取資料然後在放在快取內即可,然後其他執行緒再去取這個快取,並需要併發的更新這個快取。

解決辦法:
使用鎖機制(快取伺服器叢集環境下,使用分散式鎖),在快取更新或者過期的情況下,先嚐試獲取到鎖,當更新或者從資料庫獲取完成後再釋放鎖,其他的請求只需要犧牲一定的等待時間,即可直接從快取中繼續獲取資料,效率較高。可在快取更新方法上加上sychronized修飾。

b. 快取擊穿

場景:
查詢一個資料庫中不存在的資料,比如商品詳情,查詢一個不存在的ID,每次都會訪問DB,造成資料庫高負載

解決辦法:

  1. 快取空物件,適合命中不高,但可能被頻繁更新的資料,當通過某一個key去查詢資料的時候,如果對應在資料庫中的資料都不存在,我們將此key對應的value設定為一個預設的值,比如“NULL”,並設定一個快取的失效時間,這時在快取失效之前,所有通過此key的訪問都被快取擋住了。後面如果此key對應的資料在DB中存在時,快取失效之後,通過此key再去訪問資料,就能拿到新的value了

  2. 單獨過濾處理, 適合命中不高,但是更新不頻繁的資料,對所有可能對應資料為空的key進行統一的存放,並在請求前做攔截,這樣避免請求穿透到後端資料庫

c. 快取顛簸

場景:
快取的顛簸問題,有時也會變成“快取抖動”,在一段時間內對系統造成衝擊和效能影響,一般是由於快取節點故障導致

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

d. 熱點Key

場景:
快取中的某些Key(如促銷商品或營銷活動)對應的value儲存在叢集中一臺機器,使得所有流量湧向同一機器,成為系統的瓶頸

解決辦法:

  1. 客戶端熱點key快取:將熱點key對應value並快取在客戶端本地,並且設定一個失效時間。對於每次讀請求,將首先檢查key是否存在於本地快取中,如果存在則直接返回,如果不存在再去訪問分散式快取的機器
  2. 服務端負載均衡:將熱點key複製多個副本,然後儲存到快取叢集的不同機器上。當通過熱點key去查詢資料時,通過某種hash演算法隨機選擇一個副本機器訪問快取,將熱點分散到了不同機器上
e. 快取雪崩

快取雪崩就是指由於快取的原因,導致大量請求到達後端資料庫,從而導致資料庫崩潰,整個系統崩潰,發生災難

場景1:“快取併發”,“快取穿透”,“快取顛簸”等問題,導致快取雪崩現象發生

解決辦法:使用鎖機制、快取空物件、一致性雜湊演算法等來解決

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

解決辦法:
為了解決冷啟動的問題,啟動時,先預熱快取,根據實際業務估算將資料從資料庫總load到快取中,注意要分批次load,防止DB崩潰。
為了避免這種週期性大量快取同時失效,可以通過設定不同的過期時間,來錯開快取過期,從而避免快取集中失效。

相關文章