重修Redis之三:到底什麼是緩存穿透,擊穿,雪崩?(有圖有文字)

在面試Redsi過成中,經常會談及緩存穿透、緩存擊穿、緩存雪崩這三種使用緩存遇到的問題。而這三種現象的本質都是服務跳過緩存直接訪問db,對db造成一定的衝擊,嚴重會直接崩掉。究竟該如何形象的描述出這三個問題以及預防發生呢?帶着疑問開始思考。

一、什麼是緩存穿透?

緩存穿透:Redis作爲緩存服務器主要是用來緩存數據庫中查詢頻率高但是修改頻率低的數據。數據庫中不存在的數據,緩存中自然也沒有。用戶每次發起請求,先查詢緩存,緩存沒有直接查詢數據庫,數據中也不存在也不會更新緩存。這樣一來就相當於經過了兩次次請求緩存時無效的,也可以理解爲讓過了緩存直接查詢數據庫。而這一情況如果被非發請求不停攻擊,請求都打到數據庫上,會對數據庫造成壓力,甚至會打崩數據庫。

解決方案:

 (1)增加參數校驗,不合法的數據直接return;

 (2)緩存空值,如果數據庫中不存在時返回一個默認值更新到緩存,設置較短的失效時間,比如5分鐘;

 (3)布隆過濾器BloomFilter:

           布隆過濾器的優點:佔用內存空間很小,位存儲;性能特別高。

           使用key的hash判斷key存不存在將所有可能存在的數據哈希到一個足夠大的bitmap中,一個一定不存在的數據會被這個bitmap攔截掉,從而避免了對底層存儲系統的查詢壓力。在緩存之前在加一層BloomFilter,在查詢的時候先去BloomFilter去查詢key是否存在,如果不存在就直接返回,存在再去查詢緩存,緩存中沒有再去查詢數據庫。

二、什麼是緩存擊穿?

緩存擊穿:緩存擊穿是指一個key非常熱點,一個key扛住了大量請求,當這個key失效時,請求會擊穿緩存打到DB上,造成某一時刻數據庫壓力增加。

解決方案:

(1)如果這個key是非常熱點的數據,可以設置爲用久有效,定時根據需求去更新緩存

(2)併發場景下,用戶互斥鎖來控制,當緩存失效時,查詢數據庫時更新緩存時加上鎖。這樣其他線程請求時,緩存已經更新。

三、什麼是緩存雪崩?

緩存雪崩:可以說是緩存擊穿的升級版本,緩存擊穿是一個key失效,大量請求打到數據庫,而緩存雪崩是在一個時間段內大量可key失效,也就是發生多個緩存擊穿事件,這對於數據庫來說是災難級別的影響。

解決方案:

(1)最簡單的做法:設置的不同的過期時間,讓緩存失效的時間點均勻分佈;

(2)加鎖排隊:mutex互斥鎖解決,Redis的SETNX去set一個mutex key,當操作返回成功時,再進行加載數據庫的操作並回設緩存,否則,就重試整個get緩存的方法;

(3)數據預熱:緩存預熱就是系統上線後,將相關的緩存數據直接加載到緩存系統。這樣就可以避免在用戶請求的時候,先查詢數據庫,然後再將數據緩存,用戶直接查詢事先被預熱的緩存數據。可以通過緩存reload機制,預先去更新緩存,在即將發生大併發訪問前手動觸發加載緩存不同的key,類似mysql中innodb 的預熱機制;

(4)多級緩存策略:C1爲原始緩存,C2爲拷貝緩存,C1失效時,可以訪問C2,C1緩存失效時間設置爲短期,C2設置爲長期;

(5)定時更新緩存策略,實效性要求不高的緩存,容器啓動初始化加載,採用定時任務更新或移除緩存。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章