Redis緩存的雪崩,穿透,擊穿總結

  • 緩存在大併發系統中的重要做用不言而喻。緩存屬於內存操做,微秒或毫秒級別。在互聯網公司絕對繞不過這個緩存。緩存有不少mc,redis等。這裏描述的是redis.由於redis能夠持久化,而mc純內存,重啓機器數據就沒法找回。redis則還能夠從新從磁盤中導入數據。緩存則又有繞不開的問題。那就是雪崩,擊穿,穿透問題。

緩存雪崩:

    1. 現象:
      影響輕則,查詢變慢,重則當請求併發更高時,出來大面積服務不可用。
    1. 緣由:
      同一時間緩存大面積失效,就像沒有緩存同樣,全部的請求直接打到數據庫上來,DB扛不住掛了,若是是重要的庫,例如用戶庫,那牽聯就一大片了,瞬間倒一片。
    1. 案例:
      電商首頁緩存,若是首頁的key所有都在某一時刻失效,恰好在那一時刻有秒殺活動,那這樣的話就全部的請求都被打到了DB。併發大的狀況下DB必然扛不住,沒有其餘降級之類的方案的話,DBA也只能重啓DB,可是這樣又會被新的流量搞掛。
    1. 解決方案:
      批量往redis存數據的時候,把每一個key的失效時間加上個隨機數,這樣的話就能保證數據不會在同一個時間大面積失效。

緩存穿透:

    1. 現象與緣由:
      就是指用戶不斷髮起請求的數據,在緩存和DB中都沒有,好比DB中的用戶ID是自增的,可是用戶請求傳了-1,或者是一個特別大的數字,這個時候用戶頗有可能就是一個攻擊者,這樣的功擊會致使DB的壓力過大,嚴重的話就是把DB搞掛了。由於每次都繞開了緩存直接查詢DB
    1. 解決方案:
    • 方法一:在接口層增長校驗,不合法的參數直接返回。不相信任務調用方,根據本身提供的API接口規範來,做爲被調用方,要考慮可能任何的參數傳值。
    • 方法二:在緩存查不到,DB中也沒有的狀況,能夠將對應的key的value寫爲null,或者其餘特殊值寫入緩存,同時將過時失效時間設置短一點,以避免影響正常狀況。這樣是能夠防止反覆用同一個ID來暴力攻擊。
    • 方法三:正經常使用戶是不會這樣暴力功擊,只有是惡意者纔會這樣作,能夠在網關NG做一個配置項,爲每個IP設置訪問閥值。
    • 方法四:高級用戶布隆過濾器(Bloom Filter),這個也能很好地防止緩存穿透。原理就是利用高效的數據結構和算法快速判斷出你這個Key是否在DB中存在,不存在你return就行了,存在你就去查了DB刷新KV再return。

緩存擊穿:

    1. 現象與緣由:
      跟緩存雪崩相似,可是又有點不同。雪崩是由於大面積緩存失效,請求全打到DB;而緩存擊穿是指一個key是熱點,不停地扛住大併發請求,全都集中訪問此key,而當此key過時瞬間,持續的大併發就擊穿緩存,全都打在DB上。就又引起雪崩的問題。
    1. 解決方案:
      設置熱點key不過時。或者加上互斥鎖。

總結:

這就是三者的區別,差很少,但又有一些區別。由於緩存雪崩、穿透和擊穿,是緩存最大的問題,要麼不出現,一旦出現就是致命性的問題
通常避免以上狀況發生咱們從三個時間段去分析下:redis

  • 事前:Redis 高可用,主從+哨兵,Redis cluster,避免全盤崩潰。
  • 事中:本地 ehcache 緩存 + Hystrix 限流+降級,避免** MySQL** 被打死。
  • 過後:Redis 持久化 RDB+AOF,一旦重啓,自動從磁盤上加載數據,快速恢復緩存數據。

擴展知識:

能夠用限流組件,設置每秒的請求,有多少能經過組件,剩餘的未經過的請求,怎麼辦?走降級!能夠返回一些默認的值,或者友情提示,或者空白的值。
這樣的好處就是:數據庫絕對不會死,限流組件確保了每秒只有多少個請求能經過。 只要數據庫不死,就是說,對用戶來講,3/5 的請求都是能夠被處理的。 只要有 3/5 的請求能夠被處理,就意味着你的系統沒死,對用戶來講,可能就是點擊幾回刷不出來頁面,可是多點幾回,就能夠刷出來一次。
摘抄自網絡算法

相關文章
相關標籤/搜索