快取穿透、快取擊穿、快取雪崩

你曾是少年就是我發表於2019-04-06

快取穿透

什麼是快取穿透

正常情況下,查詢的資料都存在,如果請求一個不存在的資料,也就是快取和資料庫都查不到這個資料,每次都會去資料庫查詢,這種查詢不存在資料的現象我們稱為快取穿透

穿透帶來的問題

如果每次都拿一個不存在的id去查詢資料庫,可能會導致你的資料庫壓力增大

解決辦法

  1. 快取空值
    之所以發生穿透,是因為快取中沒有儲存這些資料的key,從而每次都查詢資料庫
    我們可以為這些key在快取中設定對應的值為null,後面查詢這個key的時候就不用查詢資料庫了
    當然為了健壯性,我們要對這些key設定過期時間,以防止真的有資料
  2. BloomFilter
    BloomFilter 類似於一個hbase set 用來判斷某個元素(key)是否存在於某個集合中
    我們把有資料的key都放到BloomFilter中,每次查詢的時候都先去BloomFilter判斷,如果沒有就直接返回null
    注意BloomFilter沒有刪除操作,對於刪除的key,查詢就會經過BloomFilter然後查詢快取再查詢資料庫,所以BloomFilter可以結合快取空值用,對於刪除的key,可以在快取中快取null

快取擊穿

什麼是快取擊穿

在高併發的情況下,大量的請求同時查詢同一個key時,此時這個key正好失效了,就會導致同一時間,這些請求都會去查詢資料庫,這樣的現象我們稱為快取擊穿

擊穿帶來的問題

會造成某一時刻資料庫請求量過大

解決辦法

採用分散式鎖,只有拿到鎖的第一個執行緒去請求資料庫,然後插入快取,當然每次拿到鎖的時候都要去查詢一下快取有沒有

快取雪崩

什麼是快取雪崩

當某一時刻發生大規模的快取失效的情況,比如你的快取服務當機了

解決辦法

  1. 採用叢集,降低服務當機的概率
  2. ehcache本地快取 + Hystrix限流&降級
    ehcache 本地快取的目的也是考慮在 Redis Cluster 完全不可用的時候,ehcache 本地快取還能夠支撐一陣
    使用 Hystrix進行限流 & 降級 ,比如一秒來了5000個請求,我們可以設定假設只能有一秒 2000個請求能通過這個元件,那麼其他剩餘的 3000 請求就會走限流邏輯

解決熱點資料集中失效問題

我們在設定快取的時候,一般會給快取設定一個失效時間,過了這個時間,快取就失效了。
對於一些熱點的資料來說,當快取失效以後會存在大量的請求過來,然後打到資料庫去,從而可能導致資料庫崩潰的情況

解決辦法

  1. 設定不同的失效時間
  2. 採用快取擊穿的解決辦法,加鎖
  3. 永不失效,就是採用定時任務對快要失效的快取進行更新快取和失效時間

相關文章