教育行業(yè)A股IPO第一股(股票代碼 003032)

全國咨詢/投訴熱線:400-618-4000

緩存穿透和緩存擊穿是什么? 怎么解決?

更新時(shí)間:2023年05月15日11時(shí)29分 來源:傳智教育 瀏覽次數(shù):

好口碑IT培訓(xùn)

緩存穿透是指查詢一個(gè)一定不存在的數(shù)據(jù),如果從存儲(chǔ)層查不到數(shù)據(jù)則不寫入緩存,這將導(dǎo)致這個(gè)不存在的數(shù)據(jù)每次請(qǐng)求都要到 DB 去查詢,可能導(dǎo)致 DB 掛掉。這種情況大概率是遭到了攻擊。

通常都會(huì)用布隆過濾器來解決它,

布隆過濾器主要是用于檢索一個(gè)元素是否在一個(gè)集合中。我們當(dāng)時(shí)使用的是redisson實(shí)現(xiàn)的布隆過濾器。

它的底層主要是先去初始化一個(gè)比較大數(shù)組,里面存放的二進(jìn)制0或1。在一開始都是0,當(dāng)一個(gè)key來了之后經(jīng)過3次hash計(jì)算,模于數(shù)組長度找到數(shù)據(jù)的下標(biāo)然后把數(shù)組中原來的0改為1,這樣的話,三個(gè)數(shù)組的位置就能標(biāo)明一個(gè)key的存在。查找的過程也是一樣的。

當(dāng)然是有缺點(diǎn)的,布隆過濾器有可能會(huì)產(chǎn)生一定的誤判,我們一般可以設(shè)置這個(gè)誤判率,大概不會(huì)超過5%,其實(shí)這個(gè)誤判是必然存在的,要不就得增加數(shù)組的長度,其實(shí)已經(jīng)算是很劃分了,5%以內(nèi)的誤判率一般的項(xiàng)目也能接受,不至于高并發(fā)下壓倒數(shù)據(jù)庫。

緩存擊穿的意思是對(duì)于設(shè)置了過期時(shí)間的key,緩存在某個(gè)時(shí)間點(diǎn)過期的時(shí)候,恰好這時(shí)間點(diǎn)對(duì)這個(gè)Key有大量的并發(fā)請(qǐng)求過來,這些請(qǐng)求發(fā)現(xiàn)緩存過期一般都會(huì)從后端 DB 加載數(shù)據(jù)并回設(shè)到緩存,這個(gè)時(shí)候大并發(fā)的請(qǐng)求可能會(huì)瞬間把 DB 壓垮。

解決方案有兩種方式:

第一可以使用互斥鎖:當(dāng)緩存失效時(shí),不立即去load db,先使用如 Redis 的 setnx 去設(shè)置一個(gè)互斥鎖,當(dāng)操作成功返回時(shí)再進(jìn)行 load db的操作并回設(shè)緩存,否則重試get緩存的方法。

第二種方案可以設(shè)置當(dāng)前key邏輯過期,大概是思路如下:

①:在設(shè)置key的時(shí)候,設(shè)置一個(gè)過期時(shí)間字段一塊存入緩存中,不給當(dāng)前key設(shè)置過期時(shí)間

②:當(dāng)查詢的時(shí)候,從redis取出數(shù)據(jù)后判斷時(shí)間是否過期

③:如果過期則開通另外一個(gè)線程進(jìn)行數(shù)據(jù)同步,當(dāng)前線程正常返回?cái)?shù)據(jù),這個(gè)數(shù)據(jù)不是最新

當(dāng)然兩種方案各有利弊:

如果選擇數(shù)據(jù)的強(qiáng)一致性,建議使用分布式鎖的方案,性能上可能沒那么高,鎖需要等,也有可能產(chǎn)生死鎖的問題如果選擇key的邏輯刪除,則優(yōu)先考慮的高可用性,性能比較高,但是數(shù)據(jù)同步這塊做不到強(qiáng)一致。

0 分享到:
和我們?cè)诰€交談!