緩存穿透與熱點(diǎn)緩存等問(wèn)題的解決方案

不管我們使用的哪種緩存產(chǎn)品,基本上都會(huì)遇到緩存擊穿、緩存失效以及熱點(diǎn)key的問(wèn)題。一旦出現(xiàn)上述問(wèn)題,如洪水般的請(qǐng)求會(huì)涌向后臺(tái)DB服務(wù)器,輕則應(yīng)用遲緩,重則整個(gè)應(yīng)用系統(tǒng)癱瘓。

1- 緩存并發(fā)更新控制

一個(gè)共享緩存失效后,接下來(lái)有多個(gè)線(xiàn)程嘗試從后臺(tái)數(shù)據(jù)庫(kù)服務(wù)器獲取數(shù)據(jù)來(lái)更新緩存時(shí),因?yàn)橹恍枰粋€(gè)線(xiàn)程完成從數(shù)據(jù)庫(kù)中取數(shù)據(jù)然后在放在緩存內(nèi)即可,然后其他線(xiàn)程再去取這個(gè)緩存,并需要并發(fā)的更新這個(gè)緩存。

解決方案

使用鎖機(jī)制(緩存服務(wù)器集群環(huán)境下,使用分布式鎖),在緩存更新或者過(guò)期的情況下,先嘗試獲取到鎖,當(dāng)更新或者從數(shù)據(jù)庫(kù)獲取完成后再釋放鎖,其他的請(qǐng)求只需要犧牲一定的等待時(shí)間,即可直接從緩存中繼續(xù)獲取數(shù)據(jù),效率較高。可在緩存更新方法上加上sychronized修飾。

2- 緩存擊穿

也叫緩存穿透,查詢(xún)一個(gè)數(shù)據(jù)庫(kù)中不存在的數(shù)據(jù),比如商品詳情,查詢(xún)一個(gè)不存在的ID,每次都會(huì)訪問(wèn)DB,可能不會(huì)被關(guān)注,但是這個(gè)卻是造成數(shù)據(jù)庫(kù)高負(fù)載的元兇。

解決方案
  1. 緩存空對(duì)象
    當(dāng)通過(guò)某一個(gè)key去查詢(xún)數(shù)據(jù)的時(shí)候,如果對(duì)應(yīng)在數(shù)據(jù)庫(kù)中的數(shù)據(jù)都不存在,我們將此key對(duì)應(yīng)的value設(shè)置為一個(gè)默認(rèn)的值,比如“NULL”,并設(shè)置一個(gè)緩存的失效時(shí)間,這時(shí)在緩存失效之前,所有通過(guò)此key的訪問(wèn)都被緩存擋住了。后面如果此key對(duì)應(yīng)的數(shù)據(jù)在DB中存在時(shí),緩存失效之后,通過(guò)此key再去訪問(wèn)數(shù)據(jù),就能拿到新的value了。這種方式實(shí)現(xiàn)起來(lái)成本較低,比較適合命中不高,但可能被頻繁更新的數(shù)
    據(jù)

  2. 單獨(dú)過(guò)濾處理
    對(duì)所有可能對(duì)應(yīng)數(shù)據(jù)為空的key進(jìn)行統(tǒng)一的存放,并在請(qǐng)求前做攔截,這樣避免請(qǐng)求穿透到后端數(shù)據(jù)庫(kù)。這種方式實(shí)現(xiàn)起來(lái)相對(duì)復(fù)雜,比較適合命中不高,但是更新不頻繁的數(shù)據(jù)。

3- 緩存顛簸

緩存的顛簸問(wèn)題,有些地方可能被成為“緩存抖動(dòng)”,可以看做是一種比“雪崩”更輕微的故障,但是也會(huì)在一段時(shí)間內(nèi)對(duì)系統(tǒng)造成沖擊和性能影響。一般是由于緩存節(jié)點(diǎn)故障導(dǎo)致。

解決方案

業(yè)內(nèi)推薦的做法是通過(guò)一致性Hash算法來(lái)解決。

4- 熱點(diǎn)Key

緩存中的某些Key(可能對(duì)應(yīng)用與某個(gè)促銷(xiāo)商品)對(duì)應(yīng)的value存儲(chǔ)在集群中一臺(tái)機(jī)器,使得所有流量涌向同一機(jī)器,成為系統(tǒng)的瓶頸,該問(wèn)題的挑戰(zhàn)在于它無(wú)法通過(guò)增加機(jī)器容量來(lái)解決。

解決方案
  1. 客戶(hù)端熱點(diǎn)key緩存:將熱點(diǎn)key對(duì)應(yīng)value并緩存在客戶(hù)端本地,并且設(shè)置一個(gè)失效時(shí)間。對(duì)于每次讀請(qǐng)求,將首先檢查key是否存在于本地緩存中,如果存在則直接返回,如果不存在再去訪問(wèn)分布式緩存的機(jī)器。
  2. 服務(wù)端負(fù)載均衡:將熱點(diǎn)key復(fù)制多個(gè)副本,然后存儲(chǔ)到緩存集群的不同機(jī)器上。當(dāng)通過(guò)熱點(diǎn)key去查詢(xún)數(shù)據(jù)時(shí),通過(guò)某種hash算法隨機(jī)選擇一個(gè)副本機(jī)器訪問(wèn)緩存,將熱點(diǎn)分散到了不同機(jī)器上。

5- 緩存雪崩

緩存雪崩就是指由于緩存的原因,導(dǎo)致大量請(qǐng)求到達(dá)后端數(shù)據(jù)庫(kù),從而導(dǎo)致數(shù)據(jù)庫(kù)崩潰,整個(gè)系統(tǒng)崩潰,發(fā)生災(zāi)難。

解決方法

場(chǎng)景1:導(dǎo)致這種現(xiàn)象的原因有很多種,上面提到的“緩存并發(fā)”,“緩存穿透”,“緩存顛簸”等問(wèn)題,其實(shí)都可能會(huì)導(dǎo)致緩存雪崩現(xiàn)象發(fā)生。

根據(jù)上面的解決方法來(lái)避免雪崩的發(fā)生

場(chǎng)景2: 緩存冷啟動(dòng)或者大量緩存同時(shí)失效,例如某個(gè)時(shí)間點(diǎn)內(nèi),系統(tǒng)預(yù)加載的緩存周期性集中失效了,也可能會(huì)導(dǎo)致雪崩。

解決方案:

  1. 為了解決冷啟動(dòng)的問(wèn)題,啟動(dòng)時(shí),先預(yù)熱緩存,根據(jù)實(shí)際業(yè)務(wù)估算將數(shù)據(jù)從數(shù)據(jù)庫(kù)總load到緩存中,注意要分批次load,防止DB崩潰。
  2. 為了避免這種周期性大量緩存同時(shí)失效,可以通過(guò)設(shè)置不同的過(guò)期時(shí)間,來(lái)錯(cuò)開(kāi)緩存過(guò)期,從而避免緩存集中失效。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容