溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Redis中三大緩存現(xiàn)象緩存擊穿、緩存穿透、緩存雪崩的解決方法

發(fā)布時間:2021-09-10 09:21:32 來源:億速云 閱讀:137 作者:chen 欄目:數(shù)據(jù)庫

這篇文章主要介紹“Redis中三大緩存現(xiàn)象緩存擊穿、緩存穿透、緩存雪崩的解決方法”,在日常操作中,相信很多人在Redis中三大緩存現(xiàn)象緩存擊穿、緩存穿透、緩存雪崩的解決方法問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Redis中三大緩存現(xiàn)象緩存擊穿、緩存穿透、緩存雪崩的解決方法”的疑惑有所幫助!接下來,請跟著小編一起來學(xué)習(xí)吧!

本篇文章主要談?wù)凴edis中很容易出現(xiàn)的三大問題現(xiàn)象:緩存擊穿、緩存穿透以及緩存雪崩。不過在介紹這三個問題現(xiàn)象之前,我們首先需要先來了解下Redis中key的過期淘汰機制。眾所周知,Redis可以對存儲在Redis中的緩存數(shù)據(jù)設(shè)置過期時間,比如我們獲取的短信驗證碼一般十分鐘過期,我們這時候就需要在驗證碼存進Redis時添加一個key的過期時間,但是這里有一個需要格外注意的問題就是:并非key過期時間到了就一定會被Redis給刪除。那么Redis是如何做到對過期key進行刪除呢?Redis中對于過期key的刪除分為兩種策略:定期刪除和惰性刪除。

  • 定期刪除:Redis  默認是每隔 100ms 就隨機抽取一些設(shè)置了過期時間的  Key,檢查其是否過期,如果過期就刪除。為什么是隨機抽取而不是檢查所有key?因為你如果設(shè)置的key成千上萬,每100毫秒都將所有存在的key檢查一遍,會給CPU帶來比較大的壓力。

  • 惰性刪除 :定期刪除由于是隨機抽取可能會導(dǎo)致很多過期 Key 到了過期時間并沒有被刪除。所以用戶在從緩存獲取數(shù)據(jù)的時候,redis會檢查這個key是否過期了,如果過期就刪除這個key。這時候就會在查詢的時候?qū)⑦^期key從緩存中清除。

但是如果僅僅使用定期刪除  +  惰性刪除機制還是會留下一個嚴重的隱患:如果定期刪除留下了很多已經(jīng)過期的key,而且用戶長時間都沒有使用過這些過期key,導(dǎo)致過期key無法被惰性刪除,從而導(dǎo)致過期key一直堆積在內(nèi)存里,最終造成Redis內(nèi)存塊被消耗殆盡。那這個問題如何解決呢?這個時候Redis內(nèi)存淘汰機制應(yīng)運而生了。Redis內(nèi)存淘汰機制提供了6種數(shù)據(jù)淘汰策略:

  • volatile-lru:從已設(shè)置過期時間的數(shù)據(jù)集中挑選最近最少使用的數(shù)據(jù)淘汰。

  • volatile-ttl:從已設(shè)置過期時間的數(shù)據(jù)集中挑選將要過期的數(shù)據(jù)淘汰。

  • volatile-random:從已設(shè)置過期時間的數(shù)據(jù)集中任意選擇數(shù)據(jù)淘汰。

  • allkeys-lru:當(dāng)內(nèi)存不足以容納新寫入數(shù)據(jù)時移除最近最少使用的key。

  • allkeys-random:從數(shù)據(jù)集中任意選擇數(shù)據(jù)淘汰。

  • no-enviction:當(dāng)內(nèi)存不足以容納新寫入數(shù)據(jù)時,新寫入操作會報錯。

一般情況下,推薦使用volatile-lru策略,對于配置信息等重要數(shù)據(jù),不應(yīng)該設(shè)置過期時間,這樣Redis就永遠不會淘汰這些重要數(shù)據(jù)。對于一般數(shù)據(jù)可以添加一個緩存時間,當(dāng)數(shù)據(jù)失效則請求會從DB中獲取并重新存入Redis中。

緩存擊穿

講完了Redis的key的過期淘汰機制,接下我們可以進入正題:為什么會出現(xiàn)緩存擊穿、緩存穿透和緩存雪崩現(xiàn)象呢?首先我們來看下請求是如何取到數(shù)據(jù)的:當(dāng)接收到用戶請求,首先先嘗試從Redis緩存中獲取到數(shù)據(jù),如果緩存中能取到數(shù)據(jù)則直接返回結(jié)果,當(dāng)緩存中不存在數(shù)據(jù)時從DB獲取數(shù)據(jù),如果數(shù)據(jù)庫成功取到數(shù)據(jù),則更新Redis,然后返回數(shù)據(jù),如果DB無數(shù)據(jù),則返回空結(jié)果。那什么情況下會出現(xiàn)三大問題現(xiàn)象呢?我們先來看下緩存擊穿的情況:

定義:高并發(fā)的情況下,某個熱門key突然過期,導(dǎo)致大量請求在Redis未找到緩存數(shù)據(jù),進而全部去訪問DB請求數(shù)據(jù),引起DB壓力瞬間增大。

解決方案:緩存擊穿的情況下一般不容易造成DB的宕機,只是會造成對DB的周期性壓力。對緩存擊穿的解決方案一般可以這樣:Redis中的數(shù)據(jù)不設(shè)置過期時間,然后在緩存的對象上添加一個屬性標(biāo)識過期時間,每次獲取到數(shù)據(jù)時,校驗對象中的過期時間屬性,如果數(shù)據(jù)即將過期,則異步發(fā)起一個線程主動更新緩存中的數(shù)據(jù)。但是這種方案可能會導(dǎo)致有些請求會拿到過期的值,就得看業(yè)務(wù)能否可以接受,如果要求數(shù)據(jù)必須是新數(shù)據(jù),則最好的方案則為熱點數(shù)據(jù)設(shè)置為永不過期,然后加一個互斥鎖保證緩存的單線程寫。

緩存穿透

定義:緩存穿透是指查詢緩存和DB中都不存在的數(shù)據(jù)。比如通過id查詢商品信息,id一般大于0,攻擊者會故意傳id為-1去查詢,由于緩存是不命中則從DB中獲取數(shù)據(jù),這將會導(dǎo)致每次緩存都不命中數(shù)據(jù)導(dǎo)致每個請求都訪問DB,造成緩存穿透。

解決方案:緩存穿透的解決方案可以分成兩個部分:首先在API層增加基本校驗:用戶鑒權(quán)校驗,id校驗。比如用戶鑒權(quán)失敗或者id  < 0的請求直接進行攔截。其次在緩存和DB都取不到數(shù)據(jù)的時候?qū)ey-value存儲成key-null存儲到Redis,  過期時間可以存儲的短點比如60S,防止短時間內(nèi)攻擊者不斷發(fā)起請求導(dǎo)致數(shù)據(jù)庫壓力過大出現(xiàn)宕機。

緩存雪崩

定義:緩存中如果大量緩存在一段時間內(nèi)集中過期了,這時候會發(fā)生大量的緩存擊穿現(xiàn)象,所有的請求都落在了DB上,由于查詢數(shù)據(jù)量巨大,引起DB壓力過大甚至導(dǎo)致DB宕機。

解決方案:緩存雪崩一般沒有完美解決的方法,但是我們可以盡量分析用戶行為,盡量保證key的失效時間比較平均,防止同一時間出現(xiàn)大量緩存數(shù)據(jù)同時過期的現(xiàn)象,并且設(shè)置熱點數(shù)據(jù)永不過期。同時如果為分布式環(huán)境下,使用分布式鎖來保證緩存的單線程寫,這樣可以避免同一時間大量緩存失效導(dǎo)致請求全部落在DB上。而我覺得如果可以接受有些請求拿到過期值,最合理的方案實際上就是使用緩存擊穿的方案:Redis中的數(shù)據(jù)不設(shè)置過期時間,然后在緩存的對象上添加一個屬性標(biāo)識過期時間,每次獲取到數(shù)據(jù)時,校驗對象中的過期時間屬性,如果數(shù)據(jù)即將過期,則異步發(fā)起一個線程主動更新緩存中的數(shù)據(jù)。

到此,關(guān)于“Redis中三大緩存現(xiàn)象緩存擊穿、緩存穿透、緩存雪崩的解決方法”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識,請繼續(xù)關(guān)注億速云網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬嵱玫奈恼拢?/p>

向AI問一下細節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI