您的位置:  首頁 > 技術 > 中間件 > 正文

聊一聊Redis熱點key存儲問題

2022-05-17 12:00 https://my.oschina.net/bruceqiqi/blog/5526921 7small7 次閱讀 條評論

說明

緩存穿透、緩存擊穿和緩存雪崩是Redis面試當中和實際開發中,經常需要考慮的一個問題。很多人對該問題的產生、原因和解決方案還是不夠清晰。其實大家針對該三種情況,去仔細分析一個產生的原理就能很好的找到一個好的解決方案。

本文通過定義、案例、危害和解決方案的幾個角度,來幫助你快速了解該三個問題。

相信大家在網上也看到很多解決這三種問題的解決方案,其中的一些方案是否是一個正確的方案呢?本文也將一一分析此類方案的優缺點。

下圖為本文的內容大綱,文章也是圍繞這幾點進行分析與總結。

三者比較

  1. 緩存穿透、緩存擊穿和緩存雪崩都是因為緩存中數據不存在,導致走數據庫去查詢數據。

  2. 由于緩存數據不存在,所有的請求都會走到數據庫,因此會導致數據庫的壓力過大甚至出現服務崩潰,導致整個系統無法使用。

緩存穿透

定義:緩存穿透是由于客戶端求的數據在緩存中不存在,然后去查詢數據庫,然而數據庫沒有客戶端要查詢的數據,導致每一次請求都會走數據庫查詢操作。真正的問題在于該數據本身就是不存在的。

舉例:客戶端請求商品詳情信息時,攜帶一個商品ID,此時該商品ID是不存在的(不管是緩存中還是數據庫中)。導致每一次請求該ID商品的數據信息都會走數據庫。

危害:由于請求的參數對應的數據根本不存在,會導致每一次都會請求數據庫,增加數據庫的壓力或者服務崩潰,更有甚至影響到其他的業務模塊。經常發生在用戶惡意請求的情況下會發生。

解決方案:

  1. 根據請求的參數緩存一個null值。并且為該值設置一個過期時間,可以將時間設置短暫一點。

  2. 使用布隆過濾器,首先通過布隆過濾器進行篩選,如果在過濾器中存在則去查詢數據庫,然后添加到緩存中。如果不存在則直接返回客戶端數據不存在。

  3. 由于緩存穿透可能是用戶發起惡意請求,可以將用戶ip給記錄下來,針對惡意的ip請求進行封禁。

方案分析:

  1. 第一種方案,針對不存在的key,會緩存一個空的值。假設這樣的請求特別多,是否都會一一去設置一個空值的緩存,此時Redis中就存在大量無效的緩存空值。假設這樣的key是商品或者文章類的ID,我們在設置空值之后,如果后臺添加數據應該去更新ID對應的緩存值,并設置一個合理的過期時間。

  2. 第二種方案,也是業界使用最多的一種方案。布隆過濾器的優點在于基于Redis實現,內存操作并且底層的實現也是非常節約內存。關于布隆過濾器的介紹,可以參考該文章。 當后臺添加數據成功時,將該數據的ID添加到布隆過濾器中,前端在請求時先走布隆過濾器進行驗證是否存在。但布隆過濾器也存在一個弊端,就是hash沖突問題。這里的hash沖突是什么意思呢?就是說多個ID在進行hash計算時,得到的hash位都是同一個值,這就導致在驗證是否存在時誤判。本身是有的,得到的結果是沒有。布隆過濾器的一個弊端就是,它說有并不一定有,它說沒有就一點是沒有的。

  3. 第三種方案,針對同一用戶一段時間內發起大量的請求,觸發緩存穿透機制,此時我們可以顯示該客戶端的訪問。但攻擊者如果是發起DDOS這樣的攻擊,是沒法完全的避免此類攻擊,因此這種方案不是一個很好的解決方案。

方案總結:

  1. 我們首先在請求層面增加第3中方案,做一個限流機制、IP黑名單機制,控制一些惡意的請求,如果是誤判我們可以實現IP解封這樣的操作。在緩存層則使用第1中方案實現。設置一個合理的緩存時間。

  2. 對于能容忍誤判的業務場景,可以直接才用第2中方案實現。完全基于Redis,減少了系統的復雜度。

緩存擊穿

定義:緩存擊穿是因為某個熱點key不存在,導致走數據庫查詢。增加了數據庫的壓力。這種壓力可能是瞬間的,也可能是比較持久的。真正的問題在于該key是存在,只是緩存中不存在,導致走數據庫操作。

舉例:有一個熱門的商品,用戶查看商品詳情時攜帶商品的ID以獲取到商品的詳情信息。此時緩存中的數據已經過期了,因此來的所有請求都要走數據庫去查詢。

危害:相對緩存穿透而言,該數據在數據庫中是存在的,只是因為緩存過期了,導致要走一次數據庫,然后在添加到緩存中,下次請求就能正常走緩存。所謂的危害同樣的還是針對數據庫層面的危害。

解決方案:

  1. 加互斥鎖。針對第一個請求,發現緩存中沒有數據,此時查詢數據庫添加到緩存里面。這樣后面的請求就不需要走數據庫查詢。

  2. 增加業務邏輯過期時間。在設置緩存時,我們可以添加一個緩存過期時間。每次去讀取的時候,做一個判斷,如果這個過期時間與當前時間小于一個范圍,觸發一個后臺線程,去數據庫拉取一下數據,接著更新一下緩存數據和緩存的過期時間。其實原理就是代碼層面給緩存延長緩存時長。

  3. 數據預熱。實現通過后臺把數據添加到緩存里面。例如秒殺場景開始前,就把商品的庫存添加到緩存里面,這樣用戶請求來了之后,就直接走緩存。

  4. 永久不過期。在給緩存設置過期時間時,讓它永久不過期。后臺單獨開啟一個線程,來維護這些緩存的過期時間和數據更新。

方案分析:

  1. 互斥鎖保證了只有一個請求走數據庫,這是一個優點。但是對于分布式的系統,得才用分布式鎖實現,分布式鎖的實現本身就有一定的難點,這樣提升了系統的復雜度。關于Redis分布式的介紹,可以參考該文章。

  2. 第2種方案,利用Redis不過期,業務過期的方案實現。保證了每一次請求都能拿到數據,同時也可以做到一個后臺線程去更新數據。缺點在于后臺線程沒有更新完數據,此時請求拿到的數據是舊數據,可能對應實時性要求高的業務場景存在弊端。

  3. 第3種方案,使用緩存預熱每次加載都走緩存,與第2種方案差不多。不過也存在熱點數據更新問題,因此該方案適合數據實時性要求不高的數據。

  4. 第4中方案,和第2、3種方案類似,在此基礎上進行了一定優化,使用后臺異步線程主動去更新緩存數據。難點在于更新的頻率控制。

方案總結:

  1. 對于實時性要求高的數據,推薦使用第1種方案,雖然在技術上有一定的難度但是能做到數據的實時性處理。如果發生某些請求等待時間久,可以返回異常,讓客戶端重新發送一次請求。

  2. 對于實時性要求不高的數據,可以使用第4種方案。

緩存雪崩

定義:前面在說到緩存擊穿,是因為緩存中的某個熱點key失效,導致大量請求走數據庫。然而緩存雪崩其實也是同樣的道理,只不過這個更嚴重而已,是大部分緩存的key失效,而不是一個或者兩個key失效。

舉例:在一個電商系統中,某一個分類下的商品數據在緩存中都失效了。然而當前系統的很多請求都是該分類下面的商品數據。這樣就導致所有的請求都走數據庫查詢。

危害:由于一瞬間大量的請求涌入,每一個請求都要走數據庫進行查詢。數據庫瞬間流量涌入,嚴重增加數據庫負擔,很容易導致數據庫直接癱瘓。

解決方案:

  1. 緩存時間隨機。因為某一時間,大量的緩存失效,說明緩存的過期時間比較集中。我們直接將過期的時間設置為不集中,隨機打亂。這樣緩存過期時間相對不會很集中,就不會出現同一時刻大量請求走數據庫進行查詢操作。

  2. 多級緩存。不單純的靠Redis來做緩存,我們也可以使用memcached來做緩存(這里只是舉一個例子,其他的緩存服務也可以)。緩存數據時,對Redis做一個緩存,對memcached做一個緩存。如果Redis失效了,我們可以走memcached。

  3. 互斥鎖。緩存擊穿中我們提到了使用互斥鎖來實現,同樣我們也可以用在雪崩的情況下。

  4. 設置過期標志。其實也可以用到緩存擊穿中講到的永久不過期。當請求時,判斷過期時間,如果臨近過期時間則設置一個過期標志,觸發一個獨立的線程去對這個緩存進行更新。

方案分析:

  1. 第1種方案采用隨機數緩存時間,能保證key的失效時間分散。難點在于如何設置緩存時間,如果對于一些需要設置短緩存時間并數據量非常大的數據,該方案就需要合理的控制時間。

  2. 第2種方案使用多級緩存,可以保證請求全部走緩存數據。但這樣增加了系統的架構難度,以及其他的各種問題,例如緩存多級更新。

  3. 第3種方案使用互斥鎖,在緩存擊穿中我們提到了互斥鎖,在雪崩的場景中我們雖然能使用,但是這樣會產生大量的分布式鎖。

  4. 第4種方案使用邏輯緩存時間,很好的保證了系統的緩存壓力。

方案總結: 在實際的項目中推薦使用第1、2和4種方案試下會更好一些。

總結

  1. 緩存穿透是因為數據庫本身沒有該數據。

  2. 緩存擊穿和緩存雪崩是數據庫中存在該數據,只是緩存中的數據失效了,導致重新要查詢一次數據庫再添加到緩存中去。

  3. 緩存擊穿是針對部分熱點key,而緩存雪崩是大面積緩存失效。兩則原理上其實是一樣的,無非就是針對緩存的key的劃分不同而已。

展開閱讀全文
  • 0
    感動
  • 0
    路過
  • 0
    高興
  • 0
    難過
  • 0
    搞笑
  • 0
    無聊
  • 0
    憤怒
  • 0
    同情
熱度排行
友情鏈接
18禁高潮出水呻吟娇喘mp3,日本熟妇乱人伦A片免费高清,成人午夜精品无码区,狠狠色噜噜色狠狠狠综合久久,麻豆一区二区99久久久久,年轻的妈妈4,少妇被又大又粗又爽毛片,护士张开腿让我爽了一夜,男男互攻互受h啪肉np文,你好神枪手电视剧免费观看啊,97人妻一区二区精品免费,久久久婷婷五月亚洲97号色,freegaysexvideos男男中国,国产精品国产三级国av麻豆,国产精品又黄又爽又色无遮挡网站,亚洲av无码一区二区三区网站,亚洲国产精品久久久久蜜桃,国产真人无码作爱视频免费,国产成人精品亚洲一区二区三区,亚洲欧洲日产最新,老司机带带我精彩免费,国产成人久久精品激情,日本最新av免费一区二区三区,边摸边吃奶又黄又激烈视频
<蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <文本链> <文本链> <文本链> <文本链> <文本链> <文本链>