欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

一篇吃透Redis緩存穿透、雪崩、擊穿問題

 更新時(shí)間:2023年05月22日 11:33:30   作者:地大第一渣男  
這篇文主要介紹了Redis緩存穿透,緩存雪崩,緩存擊穿的問題解決方法,文中有詳細(xì)的圖文介紹,對大家了解Redis有一定的幫助,需要的朋友可以參考下

前言:在學(xué)Redis之前我們查詢數(shù)據(jù)的時(shí)候都是直接查詢數(shù)據(jù)庫的,但是這樣會有一個(gè)潛在的問題:“如果用戶量很大,所有請求都去訪問數(shù)據(jù)庫,那么會使數(shù)據(jù)庫壓力過大,導(dǎo)致性能下降甚至宕機(jī)”。因此,我們需要把經(jīng)常訪問的數(shù)據(jù)放到緩存中,這里我們用Redis作為緩存。

但是,使用Redis作為緩存的過程中我們一般如下,如下圖:我們查詢某個(gè)數(shù)據(jù),前端發(fā)送請求到后端,后端根據(jù)請求去查詢數(shù)據(jù),一開始先去Redis中查有無這個(gè)數(shù)據(jù),如果有則直接返回,沒有則去數(shù)據(jù)庫中查找并且將查找到的結(jié)果返回,如果數(shù)據(jù)庫中沒有則返回錯(cuò)誤信息。

那么,在使用Redis作為緩存的過程中我們避免不了會遇到以下幾個(gè)常見的問題:①Redis與數(shù)據(jù)庫的數(shù)據(jù)一致性問題。②緩存穿透。③緩存雪崩。④緩存擊穿。

我們先來說①緩存與數(shù)據(jù)庫的數(shù)據(jù)庫一致性問題。

對于Redis作為緩存我們有以下用法:①只讀緩存。②讀寫緩存。

只讀緩存是指對于修改數(shù)據(jù)的時(shí)候,我們只對數(shù)據(jù)庫進(jìn)行修改,同時(shí)刪除緩存,這樣我們永遠(yuǎn)能保證數(shù)據(jù)庫中有最新的數(shù)據(jù),但是這樣每次修改數(shù)據(jù)的時(shí)候,我們查找該數(shù)據(jù)的時(shí)候都需要查找一次數(shù)據(jù)庫,因此性能會有所降低。

讀寫緩存是指我們修改數(shù)據(jù)的時(shí)候?qū)彺娴臄?shù)據(jù)也直接進(jìn)行修改,那么又可以分為兩種:①同步讀寫②異步讀寫。

同步讀寫是指修改數(shù)據(jù)的時(shí)候同時(shí)修改緩存和數(shù)據(jù)庫,并且通過事務(wù)的特性保證二者數(shù)據(jù)一致性,但是由于緩存的速度遠(yuǎn)快于數(shù)據(jù)庫的速度,因此性能還是會有一定的限制。

異步讀寫是指我們每次修改數(shù)據(jù)都是在緩存中修改,每隔一段時(shí)間將緩存中的數(shù)據(jù)導(dǎo)入數(shù)據(jù)庫中,這樣每次修改的時(shí)間只是修改緩存數(shù)據(jù)的時(shí)間,性能大大提高。但是這樣會存在一個(gè)隱患:“當(dāng)Redis突發(fā)情況宕機(jī)的時(shí)候,數(shù)據(jù)還沒來得及導(dǎo)入數(shù)據(jù)庫,那么這段時(shí)間還沒保存進(jìn)數(shù)據(jù)庫的數(shù)據(jù)就會丟失”,因此一致性無法保證。

然后我們來說說②緩存穿透。由我們Redis作為緩存的流程圖可以知道:我們每次查詢數(shù)據(jù)的時(shí)候都是先查詢緩存,查詢不到再查數(shù)據(jù)庫,如果數(shù)據(jù)庫中也查詢不到則返回錯(cuò)誤信息。

那么,對于一個(gè)查詢不到的數(shù)據(jù),如果有心懷不軌的人,寫一個(gè)程序,多線程并發(fā)的無限查詢這個(gè)數(shù)據(jù),那么我們每次都需要訪問數(shù)據(jù)庫,會導(dǎo)致數(shù)據(jù)庫性能下降甚至宕機(jī),這就是緩存穿透。

那么,我們?nèi)绾蝸斫鉀Q緩存穿透呢?這里我們說兩種方法:

方法一:Redis緩存中存儲空值。我們可以知道,緩存穿透是由于某些不存在的數(shù)據(jù),每次查詢,我們在緩存中都查找不到該數(shù)據(jù),因此每次都需要去訪問數(shù)據(jù)庫。那么我們可以不可以對于這些數(shù)據(jù)也存入緩存中呢?這樣我們每次查找這些數(shù)據(jù),就只會第一次查找數(shù)據(jù)庫,后面都是查找緩存了。那么有人會問了?“咦,不存在的數(shù)據(jù)怎么查找呢?”所以我們這邊是將某個(gè)不存在的數(shù)據(jù)存儲在緩存中,并且存儲的值為空字符串(也可以是其他的,這里取決于你與前端兄弟的約定)。如下圖:

因此,這樣我們對于這些惡意數(shù)據(jù),就只能“騷擾”我們的寶貝數(shù)據(jù)庫一次了,便解決了緩存穿透的問題,那么還有一個(gè)疑問就是:如果將來這些數(shù)據(jù)有了,但是每次查詢的時(shí)候緩存都直接返回空不是嘛?不會的,因?yàn)槲覀円院髮τ跀?shù)據(jù)庫插入數(shù)據(jù)的同時(shí)會對Redis緩存進(jìn)行一個(gè)Set,這個(gè)Set數(shù)據(jù)的操作會直接覆蓋原有不存在的數(shù)據(jù),因此并不會出現(xiàn)這種問題。

方法二:布隆過濾器。大致就是在前端頁面和緩存直接多了一個(gè)布隆過濾器

布隆過濾器(Bloom Filter)是1970年由布隆提出的。它實(shí)際上是一個(gè)很長的二進(jìn)制向量和一系列隨機(jī)映射函數(shù)。布隆過濾器可以用于檢索一個(gè)元素是否在一個(gè)集合中。它的優(yōu)點(diǎn)是空間效率和查詢時(shí)間都比一般的算法要好的多,缺點(diǎn)是有一定的誤識別率和刪除困難。布隆過濾器可以告訴我們 “某樣?xùn)|西一定不存在或者可能存在”,也就是說布隆過濾器說這個(gè)數(shù)不存在則一定不存,布隆過濾器說這個(gè)數(shù)存在可能不存在。

③緩存雪崩,什么是緩存雪崩呢?緩存雪崩指的是在同一時(shí)間大量Redis緩存中存儲的key過期或者Redis服務(wù)器直接宕機(jī),并且大量的請求查詢這些數(shù)據(jù)的時(shí)候,會導(dǎo)致大量請求一窩蜂的涌向數(shù)據(jù)庫進(jìn)行查詢,導(dǎo)致數(shù)據(jù)庫壓力過大,性能下降甚至宕機(jī)。那么如何解決緩存雪崩呢?

對于情況一:大量key同時(shí)過期,這里說幾種解決方法:

①設(shè)置緩存key過期時(shí)間可以隨機(jī)設(shè)置,這樣不會使得大量的key同一時(shí)間段內(nèi)過期。

②服務(wù)降級:指的是對于一些非核心數(shù)據(jù)來說(比如查詢一些無關(guān)緊要的數(shù)據(jù)時(shí))我們可以預(yù)先設(shè)置一些值,當(dāng)無法訪問緩存的時(shí)候,這些數(shù)據(jù)不會直接查詢數(shù)據(jù)庫,而是返回預(yù)先設(shè)置的值,比如一些錯(cuò)誤信息。

對于情況二:Redis服務(wù)器直接宕機(jī),這里說幾種解決方法:

①搭建Redis服務(wù)集群:嘗試構(gòu)建 Redis 的高可用集群,比如當(dāng)某主節(jié)點(diǎn)掛掉了,集群能夠馬上重新選出新的主節(jié)點(diǎn)。

②業(yè)務(wù)中實(shí)現(xiàn)服務(wù)熔斷或者請求限流機(jī)制:

  • 服務(wù)熔斷:如果監(jiān)聽到發(fā)生了緩存雪崩,直接暫停對緩存服務(wù)的請求,但是這種對業(yè)務(wù)的影響比較大;

  • 服務(wù)限流:可以在入口做限流,不要讓所有的請求都流入到后端的服務(wù)中;

④緩存擊穿:緩存雪崩指的是大量數(shù)據(jù)無法從Redis查詢到,而同時(shí)去查詢數(shù)據(jù)庫導(dǎo)致,緩存擊穿則是某些熱點(diǎn)key,比如雙十一搶蘋果手機(jī),如果突然間Redis緩存對于這個(gè)數(shù)據(jù)過期了,那么這一瞬間大量搶蘋果手機(jī)的請求都會去訪問數(shù)據(jù)庫,導(dǎo)致數(shù)據(jù)庫性能下降甚至宕機(jī)這里我們講兩種解決方法:①Redis互斥鎖。②緩存數(shù)據(jù)邏輯過期。

方法一:Redis互斥鎖。以上我們知道:對于某個(gè)熱點(diǎn)key失效的時(shí)候,由于大量查詢該數(shù)據(jù)的請求在緩存中查找不到,因此同時(shí)查找數(shù)據(jù)庫導(dǎo)致。那么我們只需要對于每個(gè)數(shù)據(jù)設(shè)置一個(gè)互斥鎖,當(dāng)在訪問不到緩存的時(shí)候,只有一個(gè)線程能夠去訪問數(shù)據(jù)庫,其他線程等待,

  • 這樣就解決了以上的問題。

但是這樣會導(dǎo)致一個(gè)問題:那就是由于其他線程都要等待,會導(dǎo)致性能下降,要等那個(gè)拿到互斥鎖的線程查詢完數(shù)據(jù)庫,并且返回?cái)?shù)據(jù)到緩存中才能查到數(shù)據(jù)。

方法二:緩存的數(shù)據(jù)邏輯過期。我們知道,緩存擊穿是由于熱點(diǎn)key過期導(dǎo)致去查詢數(shù)據(jù)庫,那么我們可以這樣想:如果這些熱點(diǎn)key只是邏輯過期(邏輯過期指雖然過期了,但是還是在緩存里面不會刪除,但是程序會知道是已過期的數(shù)據(jù),會訪問一次數(shù)據(jù)庫進(jìn)行更新),那么不就解決了嗎?因此邏輯過期的解決思路是:對于這些熱點(diǎn)key,先查詢緩存,如果沒過期則直接返回,如果過期了則開一個(gè)新的線程

去查詢數(shù)據(jù)庫,而查詢數(shù)據(jù)庫過程中訪問緩存的請求直接返回舊數(shù)據(jù)即可。

但是邏輯過期由于要多一個(gè)線程,因此有一定的內(nèi)存消耗,并且更新過程中訪問的請求都是收到舊的數(shù)據(jù),因此一致性有一定的下降。

以上是使用Redis緩存過程中的一些常見問題,后續(xù)會慢慢補(bǔ)充。

以上就是一篇吃透Redis緩存穿透、雪崩、擊穿問題的詳細(xì)內(nèi)容,更多關(guān)于Redis緩存穿透、雪崩、擊穿的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評論