文章已收錄Github精選,歡迎Star: https://github.com/yehongzhi
前言
Redis作為目前使用最廣泛的緩存,相信大家都不陌生。但是使用緩存并沒有這麼簡單,還要考慮緩存雪崩,緩存擊穿,緩存穿透的問題,什麼是緩存雪崩,擊穿,穿透呢,出現這些問題又怎麼解決呢,接下來學習一下吧。
緩存雪崩
什麼是緩存雪崩?
當某一個時刻出現大規模的緩存失效的情況,那麼就會導緻大量的請求直接打在資料庫上面,導緻資料庫壓力巨大,如果在高并發的情況下,可能瞬間就會導緻資料庫當機。這時候如果運維馬上又重新開機資料庫,馬上又會有新的流量把資料庫打死。這就是緩存雪崩。

分析:
造成緩存雪崩的關鍵在于在同一時間大規模的key失效。為什麼會出現這個問題呢,有幾種可能,第一種可能是Redis當機,第二種可能是采用了相同的過期時間。搞清楚原因之後,那麼有什麼解決方案呢?
解決方案:
1、在原有的失效時間上加上一個随機值,比如1-5分鐘随機。這樣就避免了因為采用相同的過期時間導緻的緩存雪崩。
如果真的發生了緩存雪崩,有沒有什麼兜底的措施?
2、使用熔斷機制。當流量到達一定的門檻值時,就直接傳回“系統擁擠”之類的提示,防止過多的請求打在資料庫上。至少能保證一部分使用者是可以正常使用,其他使用者多重新整理幾次也能得到結果。
3、提高資料庫的容災能力,可以使用分庫分表,讀寫分離的政策。
4、為了防止Redis當機導緻緩存雪崩的問題,可以搭建Redis叢集,提高Redis的容災性。
緩存擊穿
什麼是緩存擊穿?
其實跟緩存雪崩有點類似,緩存雪崩是大規模的key失效,而緩存擊穿是一個熱點的Key,有大并發集中對其進行通路,突然間這個Key失效了,導緻大并發全部打在資料庫上,導緻資料庫壓力劇增。這種現象就叫做緩存擊穿。
關鍵在于某個熱點的key失效了,導緻大并發集中打在資料庫上。是以要從兩個方面解決,第一是否可以考慮熱點key不設定過期時間,第二是否可以考慮降低打在資料庫上的請求數量。
1、上面說過了,如果業務允許的話,對于熱點的key可以設定永不過期的key。
2、使用互斥鎖。如果緩存失效的情況,隻有拿到鎖才可以查詢資料庫,降低了在同一時刻打在資料庫上的請求,防止資料庫打死。當然這樣會導緻系統的性能變差。
緩存穿透
什麼是緩存穿透?
我們使用Redis大部分情況都是通過Key查詢對應的值,假如發送的請求傳進來的key是不存在Redis中的,那麼就查不到緩存,查不到緩存就會去資料庫查詢。假如有大量這樣的請求,這些請求像“穿透”了緩存一樣直接打在資料庫上,這種現象就叫做緩存穿透。
關鍵在于在Redis查不到key值,這和緩存擊穿有根本的差別,差別在于緩存穿透的情況是傳進來的key在Redis中是不存在的。假如有黑客傳進大量的不存在的key,那麼大量的請求打在資料庫上是很緻命的問題,是以在日常開發中要對參數做好校驗,一些非法的參數,不可能存在的key就直接傳回錯誤提示,要對調用方保持這種“不信任”的心态。
1、把無效的Key存進Redis中。如果Redis查不到資料,資料庫也查不到,我們把這個Key值儲存進Redis,設定value="null",當下次再通過這個Key查詢時就不需要再查詢資料庫。這種處理方式肯定是有問題的,假如傳進來的這個不存在的Key值每次都是随機的,那存進Redis也沒有意義。
2、使用布隆過濾器。布隆過濾器的作用是某個 key 不存在,那麼就一定不存在,它說某個 key 存在,那麼很大可能是存在(存在一定的誤判率)。于是我們可以在緩存之前再加一層布隆過濾器,在查詢的時候先去布隆過濾器查詢 key 是否存在,如果不存在就直接傳回。
總結
這三個問題在使用Redis的時候是肯定會遇到的,而且是非常緻命性的問題,是以在日常開發中一定要注意,每次使用Redis時,都要對其保持嚴謹的态度。還有一個需要注意的是要做好熔斷,一旦出現緩存雪崩,擊穿,穿透這種情況,至少還有熔斷機制保護資料庫不會被打死。
那麼這篇文章就講到這裡了,感謝大家的閱讀,希望看完之後能有所收獲。
覺得有用就點個贊吧,你的點贊是我創作的最大動力~
我是一個努力讓大家記住的程式員。我們下期再見!!!
能力有限,如果有什麼錯誤或者不當之處,請大家批評指正,一起學習交流!