快取穿透
什麼是快取穿透
正常情況下,查詢的資料都存在,如果請求一個不存在的資料,也就是快取和資料庫都查不到這個資料,每次都會去資料庫查詢,這種查詢不存在資料的現象我們稱為快取穿透
穿透帶來的問題
如果每次都拿一個不存在的id去查詢資料庫,可能會導致你的資料庫壓力增大
解決辦法
- 快取空值
之所以發生穿透,是因為快取中沒有儲存這些資料的key,從而每次都查詢資料庫
我們可以為這些key在快取中設定對應的值為null,後面查詢這個key的時候就不用查詢資料庫了
當然為了健壯性,我們要對這些key設定過期時間,以防止真的有資料 - BloomFilter
BloomFilter 類似於一個hbase set 用來判斷某個元素(key)是否存在於某個集合中
我們把有資料的key都放到BloomFilter中,每次查詢的時候都先去BloomFilter判斷,如果沒有就直接返回null
注意BloomFilter沒有刪除操作,對於刪除的key,查詢就會經過BloomFilter然後查詢快取再查詢資料庫,所以BloomFilter可以結合快取空值用,對於刪除的key,可以在快取中快取null
快取擊穿
什麼是快取擊穿
在高併發的情況下,大量的請求同時查詢同一個key時,此時這個key正好失效了,就會導致同一時間,這些請求都會去查詢資料庫,這樣的現象我們稱為快取擊穿
擊穿帶來的問題
會造成某一時刻資料庫請求量過大
解決辦法
採用分散式鎖,只有拿到鎖的第一個執行緒去請求資料庫,然後插入快取,當然每次拿到鎖的時候都要去查詢一下快取有沒有
快取雪崩
什麼是快取雪崩
當某一時刻發生大規模的快取失效的情況,比如你的快取服務當機了
解決辦法
- 採用叢集,降低服務當機的概率
- ehcache本地快取 + Hystrix限流&降級
ehcache 本地快取的目的也是考慮在 Redis Cluster 完全不可用的時候,ehcache 本地快取還能夠支撐一陣
使用 Hystrix進行限流 & 降級 ,比如一秒來了5000個請求,我們可以設定假設只能有一秒 2000個請求能通過這個元件,那麼其他剩餘的 3000 請求就會走限流邏輯
解決熱點資料集中失效問題
我們在設定快取的時候,一般會給快取設定一個失效時間,過了這個時間,快取就失效了。
對於一些熱點的資料來說,當快取失效以後會存在大量的請求過來,然後打到資料庫去,從而可能導致資料庫崩潰的情況
解決辦法
- 設定不同的失效時間
- 採用快取擊穿的解決辦法,加鎖
- 永不失效,就是採用定時任務對快要失效的快取進行更新快取和失效時間