面試官:什么是緩存穿透 ? 怎么解決 ?
候選人:
嗯~~,我想一下
緩存穿透是指查詢一個一定不存在的數(shù)據(jù),如果從存儲層查不到數(shù)據(jù)則不寫入緩存,這將導(dǎo)致這個不存在的數(shù)據(jù)每次請求都要到 DB 去查詢,可能導(dǎo)致 DB 掛掉。這種情況大概率是遭到了攻擊。
解決方案的話,我們通常都會用布隆過濾器來解決它
面試官:好的,你能介紹一下布隆過濾器嗎?
候選人:
嗯,是這樣~
布隆過濾器主要是用于檢索一個元素是否在一個集合中。我們當(dāng)時使用的是redisson實現(xiàn)的布隆過濾器。
它的底層主要是先去初始化一個比較大數(shù)組,里面存放的二進制0或1。在一開始都是0,當(dāng)一個key來了之后經(jīng)過3次hash計算,模于數(shù)組長度找到數(shù)據(jù)的下標(biāo)然后把數(shù)組中原來的0改為1,這樣的話,三個數(shù)組的位置就能標(biāo)明一個key的存在。查找的過程也是一樣的。
當(dāng)然是有缺點的,布隆過濾器有可能會產(chǎn)生一定的誤判,我們一般可以設(shè)置這個誤判率,大概不會超過5%,其實這個誤判是必然存在的,要不就得增加數(shù)組的長度,其實已經(jīng)算是很劃分了,5%以內(nèi)的誤判率一般的項目也能接受,不至于高并發(fā)下壓倒數(shù)據(jù)庫。
面試官:什么是緩存擊穿 ? 怎么解決 ?
候選人:
嗯??!
緩存擊穿的意思是對于設(shè)置了過期時間的key,緩存在某個時間點過期的時候,恰好這時間點對這個Key有大量的并發(fā)請求過來,這些請求發(fā)現(xiàn)緩存過期一般都會從后端 DB 加載數(shù)據(jù)并回設(shè)到緩存,這個時候大并發(fā)的請求可能會瞬間把 DB 壓垮。
解決方案有兩種方式:
第一可以使用互斥鎖:當(dāng)緩存失效時,不立即去load db,先使用如 Redis 的 setnx 去設(shè)置一個互斥鎖,當(dāng)操作成功返回時再進行 load db的操作并回設(shè)緩存,否則重試get緩存的方法
第二種方案可以設(shè)置當(dāng)前key邏輯過期,大概是思路如下:
①:在設(shè)置key的時候,設(shè)置一個過期時間字段一塊存入緩存中,不給當(dāng)前key設(shè)置過期時間
②:當(dāng)查詢的時候,從redis取出數(shù)據(jù)后判斷時間是否過期
③:如果過期則開通另外一個線程進行數(shù)據(jù)同步,當(dāng)前線程正常返回數(shù)據(jù),這個數(shù)據(jù)不是最新
當(dāng)然兩種方案各有利弊:
如果選擇數(shù)據(jù)的強一致性,建議使用分布式鎖的方案,性能上可能沒那么高,鎖需要等,也有可能產(chǎn)生死鎖的問題
如果選擇key的邏輯刪除,則優(yōu)先考慮的高可用性,性能比較高,但是數(shù)據(jù)同步這塊做不到強一致。
面試官:什么是緩存雪崩 ? 怎么解決 ?
候選人:
嗯??!
緩存雪崩意思是設(shè)置緩存時采用了相同的過期時間,導(dǎo)致緩存在某一時刻同時失效,請求全部轉(zhuǎn)發(fā)到DB,DB 瞬時壓力過重雪崩。與緩存擊穿的區(qū)別:雪崩是很多key,擊穿是某一個key緩存。文章來源:http://www.zghlxwxcb.cn/news/detail-721289.html
解決方案主要是可以將緩存失效時間分散開,比如可以在原有的失效時間基礎(chǔ)上增加一個隨機值,比如1-5分鐘隨機,這樣每一個緩存的過期時間的重復(fù)率就會降低,就很難引發(fā)集體失效的事件。文章來源地址http://www.zghlxwxcb.cn/news/detail-721289.html
到了這里,關(guān)于redis緩存擊穿/穿透/雪崩面試回答的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!