今天小編給大家分享一下redis中熱點(diǎn)key存儲(chǔ)問題怎么解決的相關(guān)知識(shí)點(diǎn),內(nèi)容詳細(xì),邏輯清晰,相信大部分人都還太了解這方面的知識(shí),所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。
成都創(chuàng)新互聯(lián)網(wǎng)站建設(shè)公司提供網(wǎng)站設(shè)計(jì)和自適應(yīng)建站服務(wù)。團(tuán)隊(duì)由有經(jīng)驗(yàn)的網(wǎng)頁設(shè)計(jì)師、程序員和市場專家組成,能夠提供從H5網(wǎng)站設(shè)計(jì),網(wǎng)站制作,一元廣告,模板建站到重慶小程序開發(fā)公司等全方位服務(wù)。 以客戶為中心,致力于為客戶提供創(chuàng)新、高效的解決方案,幫助您打造成功的企業(yè)網(wǎng)站。
緩存穿透、緩存擊穿和緩存雪崩都是因?yàn)榫彺嬷袛?shù)據(jù)不存在,導(dǎo)致走數(shù)據(jù)庫去查詢數(shù)據(jù)。
由于緩存數(shù)據(jù)不存在,所有的請(qǐng)求都會(huì)走到數(shù)據(jù)庫,因此會(huì)導(dǎo)致數(shù)據(jù)庫的壓力過大甚至出現(xiàn)服務(wù)崩潰,導(dǎo)致整個(gè)系統(tǒng)無法使用。
定義:緩存穿透是由于客戶端求的數(shù)據(jù)在緩存中不存在,然后去查詢數(shù)據(jù)庫,然而數(shù)據(jù)庫沒有客戶端要查詢的數(shù)據(jù),導(dǎo)致每一次請(qǐng)求都會(huì)走數(shù)據(jù)庫查詢操作。真正的問題在于該數(shù)據(jù)本身就是不存在的
。
舉例:客戶端請(qǐng)求商品詳情信息時(shí),攜帶一個(gè)商品ID,此時(shí)該商品ID是不存在的(不管是緩存中還是數(shù)據(jù)庫中)。導(dǎo)致每一次請(qǐng)求該ID商品的數(shù)據(jù)信息都會(huì)走數(shù)據(jù)庫。
危害:由于請(qǐng)求的參數(shù)對(duì)應(yīng)的數(shù)據(jù)根本不存在,會(huì)導(dǎo)致每一次都會(huì)請(qǐng)求數(shù)據(jù)庫,增加數(shù)據(jù)庫的壓力或者服務(wù)崩潰,更有甚至影響到其他的業(yè)務(wù)模塊。經(jīng)常發(fā)生在用戶惡意請(qǐng)求
的情況下會(huì)發(fā)生。
解決方案:
1、根據(jù)請(qǐng)求的參數(shù)緩存一個(gè)null值。并且為該值設(shè)置一個(gè)過期時(shí)間,可以將時(shí)間設(shè)置短暫一點(diǎn)。
2、使用布隆過濾器,首先通過布隆過濾器進(jìn)行篩選,如果在過濾器中存在則去查詢數(shù)據(jù)庫,然后添加到緩存中。如果不存在則直接返回客戶端數(shù)據(jù)不存在。
3、由于緩存穿透可能是用戶發(fā)起惡意請(qǐng)求,可以將用戶ip給記錄下來,針對(duì)惡意的ip請(qǐng)求進(jìn)行封禁。
方案分析:
第一種方案,針對(duì)不存在的key,會(huì)緩存一個(gè)空的值。假設(shè)這樣的請(qǐng)求特別多,是否都會(huì)一一去設(shè)置一個(gè)空值的緩存,此時(shí)Redis中就存在大量無效的緩存空值。假設(shè)這樣的key是商品或者文章類的ID,我們?cè)谠O(shè)置空值之后,如果后臺(tái)添加數(shù)據(jù)應(yīng)該去更新ID對(duì)應(yīng)的緩存值,并設(shè)置一個(gè)合理的過期時(shí)間。
第二種方案,也是業(yè)界使用最多的一種方案。布隆過濾器的優(yōu)點(diǎn)在于基于Redis實(shí)現(xiàn),內(nèi)存操作并且底層的實(shí)現(xiàn)也是非常節(jié)約內(nèi)存。 當(dāng)后臺(tái)添加數(shù)據(jù)成功時(shí),將該數(shù)據(jù)的ID添加到布隆過濾器中,前端在請(qǐng)求時(shí)先走布隆過濾器進(jìn)行驗(yàn)證是否存在。但布隆過濾器也存在一個(gè)弊端,就是hash沖突問題。這里的hash沖突是什么意思呢?就是說多個(gè)ID在進(jìn)行hash計(jì)算時(shí),得到的hash位都是同一個(gè)值,這就導(dǎo)致在驗(yàn)證是否存在時(shí)誤判。本身是有的,得到的結(jié)果是沒有。布隆過濾器的一個(gè)弊端就是,它說有并不一定有,它說沒有就一點(diǎn)是沒有的。
第三種方案,針對(duì)同一用戶一段時(shí)間內(nèi)發(fā)起大量的請(qǐng)求,觸發(fā)緩存穿透機(jī)制,此時(shí)我們可以顯示該客戶端的訪問。但攻擊者如果是發(fā)起DDOS這樣的攻擊,是沒法完全的避免此類攻擊,因此這種方案不是一個(gè)很好的解決方案。
方案總結(jié):
我們首先在請(qǐng)求層面增加第3中方案,做一個(gè)限流機(jī)制、IP黑名單機(jī)制,控制一些惡意的請(qǐng)求,如果是誤判我們可以實(shí)現(xiàn)IP解封這樣的操作。在緩存層則使用第1中方案實(shí)現(xiàn)。設(shè)置一個(gè)合理的緩存時(shí)間。
對(duì)于能容忍誤判的業(yè)務(wù)場景,可以直接才用第2中方案實(shí)現(xiàn)。完全基于Redis,減少了系統(tǒng)的復(fù)雜度。
定義:緩存擊穿是因?yàn)槟硞€(gè)熱點(diǎn)key不存在,導(dǎo)致走數(shù)據(jù)庫查詢。增加了數(shù)據(jù)庫的壓力。這種壓力可能是瞬間的,也可能是比較持久的。真正的問題在于該key是存在,只是緩存中不存在,導(dǎo)致走數(shù)據(jù)庫操作
。
舉例:有一個(gè)熱門的商品,用戶查看商品詳情時(shí)攜帶商品的ID以獲取到商品的詳情信息。此時(shí)緩存中的數(shù)據(jù)已經(jīng)過期了,因此來的所有請(qǐng)求都要走數(shù)據(jù)庫去查詢。
危害:相對(duì)緩存穿透而言,該數(shù)據(jù)在數(shù)據(jù)庫中是存在的,只是因?yàn)榫彺孢^期了,導(dǎo)致要走一次數(shù)據(jù)庫,然后在添加到緩存中,下次請(qǐng)求就能正常走緩存。所謂的危害同樣的還是針對(duì)數(shù)據(jù)庫層面的危害。
解決方案:
1、加互斥鎖。針對(duì)第一個(gè)請(qǐng)求,發(fā)現(xiàn)緩存中沒有數(shù)據(jù),此時(shí)查詢數(shù)據(jù)庫添加到緩存里面。這樣后面的請(qǐng)求就不需要走數(shù)據(jù)庫查詢。
2、增加業(yè)務(wù)邏輯過期時(shí)間。在設(shè)置緩存時(shí),我們可以添加一個(gè)緩存過期時(shí)間。每次去讀取的時(shí)候,做一個(gè)判斷,如果這個(gè)過期時(shí)間與當(dāng)前時(shí)間小于一個(gè)范圍,觸發(fā)一個(gè)后臺(tái)線程,去數(shù)據(jù)庫拉取一下數(shù)據(jù),接著更新一下緩存數(shù)據(jù)和緩存的過期時(shí)間。其實(shí)原理就是代碼層面給緩存延長緩存時(shí)長。
3、數(shù)據(jù)預(yù)熱。實(shí)現(xiàn)通過后臺(tái)把數(shù)據(jù)添加到緩存里面。例如秒殺場景開始前,就把商品的庫存添加到緩存里面,這樣用戶請(qǐng)求來了之后,就直接走緩存。
4、永久不過期。在給緩存設(shè)置過期時(shí)間時(shí),讓它永久不過期。后臺(tái)單獨(dú)開啟一個(gè)線程,來維護(hù)這些緩存的過期時(shí)間和數(shù)據(jù)更新。
方案分析:
互斥鎖保證了只有一個(gè)請(qǐng)求走數(shù)據(jù)庫,這是一個(gè)優(yōu)點(diǎn)。但是對(duì)于分布式的系統(tǒng),得才用分布式鎖實(shí)現(xiàn),分布式鎖的實(shí)現(xiàn)本身就有一定的難點(diǎn),這樣提升了系統(tǒng)的復(fù)雜度。
第2種方案,利用Redis不過期,業(yè)務(wù)過期的方案實(shí)現(xiàn)。保證了每一次請(qǐng)求都能拿到數(shù)據(jù),同時(shí)也可以做到一個(gè)后臺(tái)線程去更新數(shù)據(jù)。缺點(diǎn)在于后臺(tái)線程沒有更新完數(shù)據(jù),此時(shí)請(qǐng)求拿到的數(shù)據(jù)是舊數(shù)據(jù),可能對(duì)應(yīng)實(shí)時(shí)性要求高的業(yè)務(wù)場景存在弊端。
第3種方案,使用緩存預(yù)熱每次加載都走緩存,與第2種方案差不多。不過也存在熱點(diǎn)數(shù)據(jù)更新問題,因此該方案適合數(shù)據(jù)實(shí)時(shí)性要求不高的數(shù)據(jù)。
第4中方案,和第2、3種方案類似,在此基礎(chǔ)上進(jìn)行了一定優(yōu)化,使用后臺(tái)異步線程主動(dòng)去更新緩存數(shù)據(jù)。難點(diǎn)在于更新的頻率控制。
方案總結(jié):
對(duì)于實(shí)時(shí)性要求高的數(shù)據(jù),推薦使用第1種方案,雖然在技術(shù)上有一定的難度但是能做到數(shù)據(jù)的實(shí)時(shí)性處理。如果發(fā)生某些請(qǐng)求等待時(shí)間久,可以返回異常,讓客戶端重新發(fā)送一次請(qǐng)求。
對(duì)于實(shí)時(shí)性要求不高的數(shù)據(jù),可以使用第4種方案。
定義:前面在說到緩存擊穿,是因?yàn)榫彺嬷械哪硞€(gè)熱點(diǎn)key失效,導(dǎo)致大量請(qǐng)求走數(shù)據(jù)庫。然而緩存雪崩其實(shí)也是同樣的道理,只不過這個(gè)更嚴(yán)重而已,是大部分緩存的key失效,而不是一個(gè)或者兩個(gè)key失效。
舉例:在一個(gè)電商系統(tǒng)中,某一個(gè)分類下的商品數(shù)據(jù)在緩存中都失效了。然而當(dāng)前系統(tǒng)的很多請(qǐng)求都是該分類下面的商品數(shù)據(jù)。這樣就導(dǎo)致所有的請(qǐng)求都走數(shù)據(jù)庫查詢。
危害:由于一瞬間大量的請(qǐng)求涌入,每一個(gè)請(qǐng)求都要走數(shù)據(jù)庫進(jìn)行查詢。數(shù)據(jù)庫瞬間流量涌入,嚴(yán)重增加數(shù)據(jù)庫負(fù)擔(dān),很容易導(dǎo)致數(shù)據(jù)庫直接癱瘓。
解決方案:
1、緩存時(shí)間隨機(jī)。因?yàn)槟骋粫r(shí)間,大量的緩存失效,說明緩存的過期時(shí)間比較集中。我們直接將過期的時(shí)間設(shè)置為不集中,隨機(jī)打亂。這樣緩存過期時(shí)間相對(duì)不會(huì)很集中,就不會(huì)出現(xiàn)同一時(shí)刻大量請(qǐng)求走數(shù)據(jù)庫進(jìn)行查詢操作。
2、多級(jí)緩存。不單純的靠Redis來做緩存,我們也可以使用memcached來做緩存(這里只是舉一個(gè)例子,其他的緩存服務(wù)也可以)。緩存數(shù)據(jù)時(shí),對(duì)Redis做一個(gè)緩存,對(duì)memcached做一個(gè)緩存。如果Redis失效了,我們可以走memcached。
3、互斥鎖。緩存擊穿中我們提到了使用互斥鎖來實(shí)現(xiàn),同樣我們也可以用在雪崩的情況下。
4、設(shè)置過期標(biāo)志。其實(shí)也可以用到緩存擊穿中講到的永久不過期。當(dāng)請(qǐng)求時(shí),判斷過期時(shí)間,如果臨近過期時(shí)間則設(shè)置一個(gè)過期標(biāo)志,觸發(fā)一個(gè)獨(dú)立的線程去對(duì)這個(gè)緩存進(jìn)行更新。
方案分析:
第1種方案采用隨機(jī)數(shù)緩存時(shí)間,能保證key的失效時(shí)間分散。難點(diǎn)在于如何設(shè)置緩存時(shí)間,如果對(duì)于一些需要設(shè)置短緩存時(shí)間并數(shù)據(jù)量非常大的數(shù)據(jù),該方案就需要合理的控制時(shí)間。
第2種方案使用多級(jí)緩存,可以保證請(qǐng)求全部走緩存數(shù)據(jù)。但這樣增加了系統(tǒng)的架構(gòu)難度,以及其他的各種問題,例如緩存多級(jí)更新。
第3種方案使用互斥鎖,在緩存擊穿中我們提到了互斥鎖,在雪崩的場景中我們雖然能使用,但是這樣會(huì)產(chǎn)生大量的分布式鎖。
第4種方案使用邏輯緩存時(shí)間,很好的保證了系統(tǒng)的緩存壓力。
方案總結(jié):
在實(shí)際的項(xiàng)目中推薦使用第1、2和4種方案試下會(huì)更好一些。
以上就是“Redis中熱點(diǎn)key存儲(chǔ)問題怎么解決”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會(huì)為大家更新不同的知識(shí),如果還想學(xué)習(xí)更多的知識(shí),請(qǐng)關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。