redis緩存雪崩、緩存穿透和緩存擊穿等總結

redis作爲緩存

互聯網高併發請求數據的情況,可能出現頻繁訪問MySQL的情況,但是MySQL由於自身的特性,可能無法抗住這麼大的壓力,因此我們想利用redis存儲一些MySQL中的數據,redis作爲緩存時,一般有以下幾個場景:

  • 數據的一致性不是強制的
    比如查詢UV的次數,允許和數據庫有一些不一致,更新redis是異步的。而像支付等,是強一致性的,則不能使用緩存(只是舉個例子),redis更新是異步執行的。
  • 數據經常被訪問
    如果數據訪問頻率不高,則數據庫就能解決了,使用redis就是浪費了。

這樣,利用redis作爲緩存,利用redis的高QPS特點,使得客戶端先訪問redis,命中的數據直接返回給客戶端,未找到的再去數據庫中查詢,返回給用戶最終的結果。

緩存雪崩

問題現象:短時間內存在大量的key過期,而新的key還沒有寫入內存,訪問這些key的請求會直接訪問SQL,造成服務崩潰。
問題的本質原因:同時過期的key數量太多,請求越過了redis,直接訪問了SQL
解決方案

  • 服務器訪問SQL的地方,限流操作
  • 設置過期時間時,添加隨機策略,不要統一過期
  • 建立緩存備份,在一個出現大量過期且新key沒有寫入時,訪問備份緩存,確保至少一個可用。

緩存穿透

問題現象:客戶端高併發獲取redis的數據如果獲取不到,則會高併發查詢數據庫,如果數據庫中的數據也不存在,而且訪問持續進行,則會打垮數據庫。一般是惡意攻擊的情況

問題的本質原因:數據不存在的請求沒有被redis過濾掉,而且不存在的值也不會再加入redis中,等效成直接訪問SQL

解決方案:限制不存在值訪問SQL的頻率即可,不同的業務場景有不同的方案,給幾個常用的方式:

  • 客戶端對不存在的訪問進行限流處理,比如時間戳限流、漏斗限流和令牌桶等。這種模式的優勢在於,對接客戶端的時候,就能直接限制次數,而且可以通知不存在的數據
  • 布隆過濾器,把常見的數據加入到布隆過濾器中,如果布隆顯示存在則查找redis,並返回數據;因爲布隆過濾器可能會誤判,誤判的情況去找MySQL,這種概率比較小。
  • 服務器端,需要對訪問SQL的請求限流

緩存擊穿

  • 問題現象:某個key是一個熱點的key,即有大量併發的請求會訪問這個key。如果此時key過期了,那麼這些服務會直接請求到SQL上,導致SQL壓力過大而崩掉。注意,這不是雪崩,雪崩是大量的key過期,而這個是特別熱點的一個或者幾個key過期
  • 問題的本質原因:這種屬於正常的業務訪問,整個訪問流程也是沒有問題的,只是瞬間過期的key把承受的壓力轉移到了SQL端
  • 解決方案
    • SQL端首先要有自己的保護機制,保證最壞的情況下,不會被打垮
    • 對於熱點key,可以設置永不過期的策略,只有主動更新的時候去更改

緩存預熱

概念:服務啓動時,把相關的數據一次性加入redis中
解決問題:避免了用戶初始化頻繁訪問不存在的數據,導致直接請求SQL和頻繁加載。
一些限制

  • 需要手動操作
  • 數據量不能太大,否則無法全量加載

緩存更新

緩存中的數據不是一成不變的,需要定期更新,比如置換掉不經常查詢的數據,選擇出常用的數據重新加入redis中。可以使用LRU等方式來解決這種場景的問題。

注意,更新的時候,如果用到了防止擊穿的布隆過濾器,需要一併更新布隆過濾器的數據

緩存降級

redis緩存如果掛掉,則需要執行降級策略:

  • 重試機制:不斷重試訪問,同時日誌報錯,提示服務監控應該報警
  • 限流訪問機制:此時仍然要給客服服務,應該限流訪問MySQL,犧牲部分的性能來換取可用性
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章