Redis快取穿透和雪崩
快取穿透
概念
使用者如果想查詢一個資料,會先在redis記憶體資料庫中進行查詢,redis中沒有,再向持久層資料庫中查詢。
快取穿透的概念很簡單,使用者想要查詢一個資料,發現redis記憶體資料庫沒有,也就是快取沒有命中,於是向持久層資料庫查詢。發現也沒有,於是本次查詢失敗。當使用者很多的時候,快取都沒有命中,於是都去請求了持久層資料庫。這會給持久層資料庫造成很大的壓力,甚至直接導致崩潰。這時候就相當於出現了快取穿透
。
解決方案
1.布隆過濾器
布隆過濾器是一種資料結構,對所有可能查詢的引數以hash形式儲存,在控制層先進行
校驗
,不符合則丟棄,從而避免了對底層儲存系統的查詢壓力;
2.快取空物件
當儲存層不命中後,即使返回的
空物件
也將其快取起來,同時會設定一個過期時間
,之後再訪問這個資料將會從快取中獲取,保護了後端資料來源;
但是這種方法會存在兩個問題:
- 如果空值能夠被快取起來,這就意味著快取需要更多的空間儲存更多的鍵,因為這當中可能會有很多的空值的鍵;
- 即使對空值設定了過期時間,還是會存在快取層和儲存層的資料會有一段時間視窗的不一致,這對於需要保持一致性的業務會有影響。
快取擊穿
概念
這裡需要注意和快取穿透
的區別:
快取擊穿,是指一個key非常熱點,大併發集中對這一個點進行訪問,當這個key在失效的瞬間,持續的大併發就穿破快取,直接請求資料庫,就像在一個屏障上鑿開了一個洞。由於快取過期,會同時訪問資料庫來查詢最新資料,並且回寫快取,會導使資料庫瞬間壓力過大。
解決方案
1.設定熱點資料永不過期
從快取層面來看,沒有設定過期時間,所以不會出現熱點key過期後產生的問題。
2.加互斥鎖
分散式鎖:使用分散式鎖,保證對於每個key同時只有一個執行緒去查詢後端服務,其他執行緒沒有獲得分散式鎖的許可權,因此只需要等待即可。這種方式將高併發的壓力轉移到了分散式鎖,因此對分散式鎖的考驗很大。
快取雪崩
概念
快取雪崩,是指在某一個時間段,快取集中過期失效。
產生雪崩的原因之一,有一部分東西在redis中集中過期了,而對這些東西的訪問查詢,都落到了資料庫上,對於資料庫而言,就會產生週期性的壓力波峰。於是所有的請求都會達到儲存層,儲存層的呼叫量會暴增,造成儲存層也會掛掉的情況。
其實集中過期,倒不是非常致命,比較致命的快取雪崩,是快取伺服器某個節點容機或斷網。
因為自然形成的快取雪崩,一定是在某個時間段集中建立快取,這個時候,資料庫也是可以頂住壓力的。無非就是對資料庫產生週期性的壓力而已。
而快取服務節點的當機,對資料庫伺服器造成的壓力是不可預知的,很有可能瞬間就把資料庫壓垮。
解決方案
1.redis高可用
這個思想的含義是,既然redis有可能掛掉,那可以多增設幾臺redis,這樣一臺掛掉之後其他的還可以繼續工作,其實就是搭建的叢集。
2.限流降級
這個解決方案的思想是,在快取失效後,通過加鎖或者佇列來控制讀資料庫寫快取的執行緒數量。比如對某個key只允許一個執行緒查詢資料和寫快取,其他執行緒等待。
3.資料預熱
資料加熱的含義就是在正式部署之前,我先把可能的資料先預先訪問一遍,這樣部分可能大量訪問的資料就會載入到快取中。在即將發生大併發訪問前手動觸發載入快取不同的key,設定不同的過期時間,讓快取失效的時間點儘量均勻。
個人部落格為:
MoYu's HomePage