Redis緩存雪崩、緩存穿透、緩存擊穿了,你該如何挽救


前言

在今天的互聯網里,高並發大數據量大流量已經成為了代言詞,那么我們的系統也承受着巨大的壓力,首當其沖的解決方案就是redis

那么redis使用不當就會產生雪崩穿透擊穿等問題,這也是考驗一個程序員技術能力的時刻。

當然面試的時候,這也是高頻面試題,幾乎大廠都會問到。下面跟着貼心老哥一起來看看這些技術吧。

緩存雪崩

舉例

雙十一期間,所有用戶一打開淘寶就是進入首頁,首頁的壓力非常大,為了提高並發,將網站首頁數據都緩存到redis里,所有的redis key失效時間都是3小時

雙十一當天大量用戶剁手狂歡,這時候3個小時過去了,redis里首頁的key緩存全部失效,這時候redis里查詢不到數據了,只能去數據庫中查詢,造成數據庫無法響應掛掉

用戶進不去首頁沒法剁手了,馬爸爸不開心了,把這個程序員外派到非洲了。

一句話總結

高並發下,大量緩存key在同一時間失效,大量請求直接落在數據庫上,導致數據庫宕機。

解決方案

  • 隨機設置key失效時間,避免大量key集體失效。
setRedis(Key,value,time + Math.random() * 10000); 復制代碼
  • 若是集群部署,可將熱點數據均勻分布在不同的Redis庫中也能夠避免key全部失效問題

  • 不設置過期時間

  • 跑定時任務,在緩存失效前刷進新的緩存

緩存穿透

舉例

老哥做了一個網站火了,動了別人的蛋糕,於是開始瘋狂攻擊老哥的網站,由於老哥網絡安全方面學藝不精被人鑽了空子。

某人用腳本瘋狂的給老哥發送請求,查詢 id = -1 的數據,redis並沒有這樣的數據,這時候就穿透redis,直接打到了數據庫上。

半夜老哥在睡覺並沒有察覺,他瘋狂攻擊老哥一晚上,結果把數據庫搞掛了,然后老哥的網站也掛了。

一句話總結

redis緩存數據庫中沒有相關數據(例用戶直接攜帶id<=0的參數不斷發起請求),redis中沒有這樣的數據,無法進行攔截,直接被穿透到數據庫,導致數據庫壓力過大宕機。

解決方案

  • 對不存在的數據緩存到redis中,設置key,value值為null(不管是數據未null還是系統bug問題),並設置一個短期過期時間段,避免過期時間過長影響正常用戶使用。

  • 拉黑該IP地址

  • 對參數進行校驗,不合法參數進行攔截

  • 布隆過濾器 將所有可能存在的數據哈希到一個足夠大的bitmap(位圖)中,一個一定不存在的數據會被 這個bitmap攔截掉,從而避免了對底層存儲系統的查詢壓力。

緩存擊穿

舉例

雙十一馬爸爸突發奇想,想拍賣自己穿了20年的老布鞋,並且附帶本人簽名,程序員將該鞋的信息存到了redis中,設置了3小時過期。尋思3小時夠他們搶了吧,但他低估了馬爸爸的魅力。

該商品引起了一千萬人關注,這些人不斷的競拍這雙鞋,價格越拍越高,馬爸爸樂開了花。

競拍了2小時59分,馬上要拍到一個億了,突然這雙鞋在redis里的key數據過期了,導致該key的大量請求,都打到了數據庫,直接導致數據庫掛掉了,服務無法響應。

競拍到此結束,鞋沒賣出去,馬爸爸又不開心了,把這個程序員也外派到非洲了。

一句話總結

某一個熱點key,在不停地扛着高並發,當這個熱點key在失效的一瞬間,持續的高並發訪問就擊破緩存直接訪問數據庫,導致數據庫宕機。

解決方案

  • 設置熱點數據"永不過期"

  • 加上互斥鎖:上面的現象是多個線程同時去查詢數據庫的這條數據,那么我們可以在第一個查詢數據的請求上使用一個互斥鎖來鎖住它

    其他的線程走到這一步拿不到鎖就等着,等第一個線程查詢到了數據,然后將數據放到redis緩存起來。后面的線程進來發現已經有緩存了,就直接走緩存

最后總結

雪崩是大面積的key緩存失效;穿透是redis里不存在這個緩存key;擊穿是redis某一個熱點key突然失效,最終的受害者都是數據庫。

思考

未雨綢繆:將redis、MySQL等搭建成高可用的集群,防止單點。

亡羊補牢:服務中進行限流 + 降級,防止MySQL被打崩潰。

重振旗鼓:Redis 持久化 RDB+AOF,宕機重啟,自動從磁盤上加載數據,快速恢復緩存數據。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM