天天看點

Redis面試必問的緩存穿透、緩存雪崩、緩存擊穿問題一、緩存穿透二、緩存雪崩三、緩存擊穿四、個人公衆号

程式設計界的國小生

  • 一、緩存穿透
    • 1、概念
    • 2、解決方案
  • 二、緩存雪崩
    • 1、概念
      • 1.1、情況一
      • 1.2、情況二
    • 2、解決方案
      • 2.1、情況一的解決方案
      • 2.2、情況二的解決方案
  • 三、緩存擊穿
    • 1、概念
    • 2、解決方案
  • 四、個人公衆号

一、緩存穿透

1、概念

比如電商網站,有以下商品在redis裡和mysql裡。且Redis裡隻存放熱點商品, 而不是全部。

蘋果、香蕉、鴨梨等,但是使用者搜了個我這電商網站裡沒有賣的商品,這時候redis裡肯定沒有搜的資料,就去請求db了。db也不一定有(有可能有有可能沒有),如果沒有的話那白白浪費性能了。這就是緩存穿透。量少的話就别說了,量少都沒必要redis緩存。大量的話會很恐怖,比如淘寶,他無所不賣,萬一真找到一個不賣的東西去搜,然後redis沒有,結果都去請求mysql了。那不GG了嘛?

2、解決方案

解決Redis緩存穿透的利器之布隆過濾器

二、緩存雪崩

1、概念

1.1、情況一

大批量熱點資料過期後,高并發請求,直接請求到db,引起db壓力造成查詢阻塞甚至當機。

1.2、情況二

Redis挂了。導緻請求都到db了。假設高并發5000個請求,本來緩存再高峰期可以抗住每秒4000個請求,但是Redis挂了,5000個請求直接幹到了資料庫層,這可能又把資料庫給打死了。

2、解決方案

2.1、情況一的解決方案

  • 簡單粗暴,設定熱點資料永不過期(具體還看業務是否允許)
  • 将緩存失效的時間分散開,比如每個熱點key的過期時間是随機的,而不是每個key都一樣是固定的。這樣不會遇到同時大量熱點資料過期的情況,分批過期,将高并發大流量變成一部分一部分的小流量打給資料庫,這樣就沒問題了。

2.2、情況二的解決方案

  • 加一層本地ehcache緩存。也就是請求進來先查ehcache緩存,ehcache沒有的話去查redis,redis也沒有再去db。這時候redis挂了,但是我們本地ehcache還有,是以不會打到db層。
  • 限流元件,可以設定每秒最大請求數,超過最大請求數的那些請求怎麼辦?走降級!可以傳回一些預設值,或者友情提示啥的。
限流的好處是資料庫絕對不會死,因為限流元件保證了有多少請求能進來。隻要資料庫不死,就能對外繼續提供請求。雖然有部分使用者請求走降級,但不是全部,會有大部分請求得到執行。

三、緩存擊穿

1、概念

某個 key 非常非常熱點,通路非常的頻繁,高并發通路的情況下,當這個 key在失效(可能expire過期了,也可能LRU淘汰了)的瞬間,大量的請求進來,這時候就擊穿了緩存,直接請求到了資料庫,一下子來這麼多,資料庫肯定受不了,這就叫緩存擊穿。某個key突然失效,然後這時候高并發來通路這個key,結果緩存裡沒有,都跑到db了。

2、解決方案

  • 熱點資料永不過期(看業務需求。不過很少有這種場景,一般都是比如搞活動或者大促的時候才會存這些熱點資料,活動過後就需要到期,不會設定永不過期。),此方法簡單粗暴,不過還看具體需求。
  • 分布式鎖。來個請求後先鎖住,然後去db查,查到後再将資料set到redis裡。隻有當redis裡getKey沒拿到資料需要請求db的時候才加鎖。不影響Redis裡有資料的時候處理高并發請求,也能保證db不會被打垮。

四、個人公衆号

微信公衆号【Java碼農社群】

Redis面試必問的緩存穿透、緩存雪崩、緩存擊穿問題一、緩存穿透二、緩存雪崩三、緩存擊穿四、個人公衆号