自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Redis緩存雪崩、穿透、擊穿三步曲

數(shù)據(jù)庫(kù)
本文介紹了緩存雪崩產(chǎn)生的原因是因?yàn)槎虝r(shí)間內(nèi)大量緩存同時(shí)失效,而導(dǎo)致大量請(qǐng)求直接查詢(xún)數(shù)據(jù)庫(kù)的情況。

本文收集了一些 Redis 使用中經(jīng)常遇到的一些問(wèn)題,和與之相對(duì)應(yīng)的解決方案,這些內(nèi)容不但會(huì)出現(xiàn)在實(shí)際工作中,也是面試的高頻問(wèn)題,接下來(lái)一起來(lái)看。

一、緩存雪崩

緩存雪崩是指在短時(shí)間內(nèi),有大量緩存同時(shí)過(guò)期,導(dǎo)致大量的請(qǐng)求直接查詢(xún)數(shù)據(jù)庫(kù),從而對(duì)數(shù)據(jù)庫(kù)造成了巨大的壓力,嚴(yán)重情況下可能會(huì)導(dǎo)致數(shù)據(jù)庫(kù)宕機(jī)的情況叫做緩存雪崩。

我們先來(lái)看下正常情況下和緩存雪崩時(shí)程序的執(zhí)行流程圖,正常情況下系統(tǒng)的執(zhí)行流程如下圖所示:

緩存雪崩的執(zhí)行流程,如下圖所示:

以上對(duì)比圖可以看出緩存雪崩對(duì)系統(tǒng)造成的影響,那如何解決緩存雪崩的問(wèn)題?

緩存雪崩的常用解決方案有以下幾個(gè)。

1.加鎖排隊(duì)

加鎖排隊(duì)可以起到緩沖的作用,防止大量的請(qǐng)求同時(shí)操作數(shù)據(jù)庫(kù),但它的缺點(diǎn)是增加了系統(tǒng)的響應(yīng)時(shí)間,降低了系統(tǒng)的吞吐量,犧牲了一部分用戶(hù)體驗(yàn)。

加鎖排隊(duì)的代碼實(shí)現(xiàn),如下所示:

// 緩存 key
String cacheKey = "userlist";
// 查詢(xún)緩存
String data = jedis.get(cacheKey);
if (StringUtils.isNotBlank(data)) {
    // 查詢(xún)到數(shù)據(jù),直接返回結(jié)果
    return data;
} else {
    // 先排隊(duì)查詢(xún)數(shù)據(jù)庫(kù),在放入緩存
    synchronized (cacheKey) {
        data = jedis.get(cacheKey);
        if (!StringUtils.isNotBlank(data)) { // 雙重判斷
            // 查詢(xún)數(shù)據(jù)庫(kù)
            data = findUserInfo();
            // 放入緩存
            jedis.set(cacheKey, data);
        }
        return data;
    }
}

以上為加鎖排隊(duì)的實(shí)現(xiàn)示例,讀者可根據(jù)自己的實(shí)際項(xiàng)目情況做相應(yīng)的修改。

2.隨機(jī)化過(guò)期時(shí)間

為了避免緩存同時(shí)過(guò)期,可在設(shè)置緩存時(shí)添加隨機(jī)時(shí)間,這樣就可以極大的避免大量的緩存同時(shí)失效。

示例代碼如下:

// 緩存原本的失效時(shí)間
int exTime = 10 * 60;
// 隨機(jī)數(shù)生成類(lèi)
Random random = new Random();
// 緩存設(shè)置
jedis.setex(cacheKey, exTime+random.nextInt(1000) , value);

3.設(shè)置二級(jí)緩存

二級(jí)緩存指的是除了 Redis 本身的緩存,再設(shè)置一層緩存,當(dāng) Redis 失效之后,先去查詢(xún)二級(jí)緩存。

例如可以設(shè)置一個(gè)本地緩存,在 Redis 緩存失效的時(shí)候先去查詢(xún)本地緩存而非查詢(xún)數(shù)據(jù)庫(kù)。

加入二級(jí)緩存之后程序執(zhí)行流程,如下圖所示:

二、緩存穿透

緩存穿透是指查詢(xún)數(shù)據(jù)庫(kù)和緩存都無(wú)數(shù)據(jù),因?yàn)閿?shù)據(jù)庫(kù)查詢(xún)無(wú)數(shù)據(jù),出于容錯(cuò)考慮,不會(huì)將結(jié)果保存到緩存中,因此每次請(qǐng)求都會(huì)去查詢(xún)數(shù)據(jù)庫(kù),這種情況就叫做緩存穿透。

緩存穿透執(zhí)行流程如下圖所示:

其中紅色路徑表示緩存穿透的執(zhí)行路徑,可以看出緩存穿透會(huì)給數(shù)據(jù)庫(kù)造成很大的壓力。

緩存穿透的解決方案有以下幾個(gè)。

1.使用過(guò)濾器

我們可以使用過(guò)濾器來(lái)減少對(duì)數(shù)據(jù)庫(kù)的請(qǐng)求,例如使用我們前面章節(jié)所學(xué)的布隆過(guò)濾器,我們這里簡(jiǎn)單復(fù)習(xí)一下布隆過(guò)濾器,它的原理是將數(shù)據(jù)庫(kù)的數(shù)據(jù)哈希到 bitmap 中,每次查詢(xún)之前,先使用布隆過(guò)濾器過(guò)濾掉一定不存在的無(wú)效請(qǐng)求,從而避免了無(wú)效請(qǐng)求給數(shù)據(jù)庫(kù)帶來(lái)的查詢(xún)壓力。

2.緩存空結(jié)果

另一種方式是我們可以把每次從數(shù)據(jù)庫(kù)查詢(xún)的數(shù)據(jù)都保存到緩存中,為了提高前臺(tái)用戶(hù)的使用體驗(yàn) (解決長(zhǎng)時(shí)間內(nèi)查詢(xún)不到任何信息的情況),我們可以將空結(jié)果的緩存時(shí)間設(shè)置得短一些,例如 3~5 分鐘。

三、緩存擊穿

緩存擊穿指的是某個(gè)熱點(diǎn)緩存,在某一時(shí)刻恰好失效了,然后此時(shí)剛好有大量的并發(fā)請(qǐng)求,此時(shí)這些請(qǐng)求將會(huì)給數(shù)據(jù)庫(kù)造成巨大的壓力,這種情況就叫做緩存擊穿。

緩存擊穿的執(zhí)行流程如下圖所示:

它的解決方案有以下幾個(gè)。

1.加鎖排隊(duì)

此處理方式和緩存雪崩加鎖排隊(duì)的方法類(lèi)似,都是在查詢(xún)數(shù)據(jù)庫(kù)時(shí)加鎖排隊(duì),緩沖操作請(qǐng)求以此來(lái)減少服務(wù)器的運(yùn)行壓力。

2.設(shè)置永不過(guò)期

對(duì)于某些熱點(diǎn)緩存,我們可以設(shè)置永不過(guò)期,這樣就能保證緩存的穩(wěn)定性,但需要注意在數(shù)據(jù)更改之后,要及時(shí)更新此熱點(diǎn)緩存,不然就會(huì)造成查詢(xún)結(jié)果的誤差。

3.緩存預(yù)熱

首先來(lái)說(shuō),緩存預(yù)熱并不是一個(gè)問(wèn)題,而是使用緩存時(shí)的一個(gè)優(yōu)化方案,它可以提高前臺(tái)用戶(hù)的使用體驗(yàn)。

緩存預(yù)熱指的是在系統(tǒng)啟動(dòng)的時(shí)候,先把查詢(xún)結(jié)果預(yù)存到緩存中,以便用戶(hù)后面查詢(xún)時(shí)可以直接從緩存中讀取,以節(jié)約用戶(hù)的等待時(shí)間。

緩存預(yù)熱的執(zhí)行流程,如下圖所示:

緩存預(yù)熱的實(shí)現(xiàn)思路有以下三種:

  • 把需要緩存的方法寫(xiě)在系統(tǒng)初始化的方法中,這樣系統(tǒng)在啟動(dòng)的時(shí)候就會(huì)自動(dòng)的加載數(shù)據(jù)并緩存數(shù)據(jù);
  • 把需要緩存的方法掛載到某個(gè)頁(yè)面或后端接口上,手動(dòng)觸發(fā)緩存預(yù)熱;
  • 設(shè)置定時(shí)任務(wù),定時(shí)自動(dòng)進(jìn)行緩存預(yù)熱。

小結(jié)

本文介紹了緩存雪崩產(chǎn)生的原因是因?yàn)槎虝r(shí)間內(nèi)大量緩存同時(shí)失效,而導(dǎo)致大量請(qǐng)求直接查詢(xún)數(shù)據(jù)庫(kù)的情況,解決方案是加鎖、隨機(jī)設(shè)置過(guò)期時(shí)間和設(shè)置二級(jí)緩存等。

還介紹了查詢(xún)數(shù)據(jù)庫(kù)無(wú)數(shù)據(jù)時(shí)會(huì)導(dǎo)致的每次空查詢(xún)都不走緩存的緩存穿透問(wèn)題,解決方案是使用布隆過(guò)濾器和緩存空結(jié)果等。

同時(shí)還介紹了緩存在某一個(gè)高并發(fā)時(shí)刻突然失效導(dǎo)致的緩存擊穿問(wèn)題,以及解決方案——加鎖、設(shè)置永不過(guò)期等方案,最后還介紹了優(yōu)化系統(tǒng)性能的手段緩存預(yù)熱。

責(zé)任編輯:趙寧寧 來(lái)源: 程序員wayn
相關(guān)推薦

2020-03-16 14:57:24

Redis面試雪崩

2023-03-10 13:33:00

緩存穿透緩存擊穿緩存雪崩

2019-10-12 14:19:05

Redis數(shù)據(jù)庫(kù)緩存

2021-06-05 09:01:01

Redis緩存雪崩緩存穿透

2022-03-08 00:07:51

緩存雪崩數(shù)據(jù)庫(kù)

2022-11-18 14:34:28

2019-11-05 14:24:31

緩存雪崩框架

2024-04-07 00:00:02

Redis雪崩緩存

2023-04-14 07:34:19

2023-12-06 13:38:00

Redis緩存穿透緩存擊穿

2022-05-27 07:57:20

緩存穿透緩存雪崩緩存擊穿

2020-10-23 10:46:03

緩存雪崩擊穿

2023-11-10 14:58:03

2024-03-12 10:44:42

2023-01-31 08:37:11

緩存穿透擊穿

2024-01-19 20:42:08

Redis數(shù)據(jù)庫(kù)Key

2020-10-13 07:44:40

緩存雪崩 穿透

2021-12-25 22:28:27

緩存穿透緩存擊穿緩存雪崩

2012-08-08 17:05:36

App運(yùn)營(yíng)

2022-07-11 07:36:36

緩存緩存雪崩緩存擊穿
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)