最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Redis緩存穿透、緩存擊穿與緩存雪崩實(shí)戰(zhàn)指南

 更新時(shí)間:2026年05月07日 09:26:17   作者:河阿里  
本文介紹Redis在高并發(fā)分布式系統(tǒng)中的應(yīng)用及可能引發(fā)的問題,包括緩存穿透、緩存擊穿和緩存雪崩,針對(duì)這些問題,提出了布隆過濾器、分布式鎖、隨機(jī)過期時(shí)間、高可用集群、本地緩存和預(yù)熱策略等多種解決方案,通過合理配置和組合使用這些方案,可以有效提升系統(tǒng)的穩(wěn)定性和性能

在現(xiàn)代高并發(fā)的分布式系統(tǒng)架構(gòu)中,Redis憑借其高性能的內(nèi)存讀寫能力,已成為企業(yè)級(jí)應(yīng)用不可或缺的緩存中間件。然而,緩存的引入雖然極大地提升了系統(tǒng)響應(yīng)速度,降低了數(shù)據(jù)庫(kù)負(fù)載,但也帶來了一系列復(fù)雜的邊緣風(fēng)險(xiǎn)。

一、緩存穿透(Cache Penetration)

1. 定義與問題
緩存穿透是指查詢一個(gè)數(shù)據(jù)庫(kù)根本不存在的數(shù)據(jù)。由于緩存中無對(duì)應(yīng)key,請(qǐng)求直接穿透緩存層訪問數(shù)據(jù)庫(kù)。若大量此類請(qǐng)求存在(如惡意攻擊或業(yè)務(wù)誤操作),數(shù)據(jù)庫(kù)將承受巨大壓力,甚至崩潰。

2. 核心原因

  • 業(yè)務(wù)邏輯錯(cuò)誤:前端未校驗(yàn)請(qǐng)求參數(shù),導(dǎo)致無效key直達(dá)數(shù)據(jù)庫(kù)。
  • 惡意攻擊:黑客故意構(gòu)造大量不存在的key進(jìn)行請(qǐng)求。

3. 解決方案
(1)緩存空值

  • 思路:若數(shù)據(jù)庫(kù)查詢?yōu)榭?,仍將key存入緩存,值為null或特殊標(biāo)記,并設(shè)置較短過期時(shí)間(如1分鐘)。
  • 優(yōu)點(diǎn):簡(jiǎn)單高效,后續(xù)相同請(qǐng)求可直接命中緩存。
  • 缺點(diǎn):需維護(hù)額外空值數(shù)據(jù),可能占用空間。
  • 代碼示例
public Object getData(String key) {
    Object value = redis.get(key);
    if (value == null) { // 緩存未命中
        value = db.queryData(key); // 查詢數(shù)據(jù)庫(kù)
        if (value == null) { // 數(shù)據(jù)不存在
            redis.set(key, "NULL", 60); // 緩存空值,過期時(shí)間1分鐘
        } else {
            redis.set(key, value, 3600); // 緩存有效數(shù)據(jù),過期時(shí)間1小時(shí)
        }
    }
    return value;
}

(2)布隆過濾器(Bloom Filter)[推薦]

  • 思路:使用高效概率型數(shù)據(jù)結(jié)構(gòu)過濾不存在的請(qǐng)求。布隆過濾器通過多個(gè)哈希函數(shù)將key映射到位數(shù)組,若所有位均為1,則可能存在于數(shù)據(jù)庫(kù);若存在0,則一定不存在。
  • 優(yōu)點(diǎn):空間占用極低,過濾效率高。
  • 缺點(diǎn):存在誤判(可能將不存在的key誤判為存在),不支持刪除操作。
  • 代碼示例(Guava布隆過濾器)
BloomFilter<String> filter = BloomFilter.create(Funnels.stringFunnel(), 1000000, 0.01); // 容量100萬,誤判率1%
// 初始化:將數(shù)據(jù)庫(kù)所有key預(yù)加載到布隆過濾器
filter.putAll(db.getAllKeys());
public Object getData(String key) {
    if (!filter.mightContain(key)) { // 布隆過濾器判斷不存在
        return null; // 直接返回,不訪問數(shù)據(jù)庫(kù)
    }
    Object value = redis.get(key);
    if (value == null) {
        value = db.queryData(key);
        redis.set(key, value, 3600);
    }
    return value;
}

二、緩存擊穿(Cache Breakdown)

1. 定義與問題
緩存擊穿又稱熱點(diǎn)Key問題,指一個(gè)訪問極其頻繁的熱點(diǎn)key突然失效,大量并發(fā)請(qǐng)求同時(shí)穿透緩存,直接沖擊數(shù)據(jù)庫(kù)。例如,電商平臺(tái)秒殺商品的緩存過期瞬間,大量用戶搶購(gòu)導(dǎo)致數(shù)據(jù)庫(kù)崩潰。

2. 核心原因

  • 熱點(diǎn)數(shù)據(jù)緩存過期時(shí)間設(shè)置不合理,或手動(dòng)刪除緩存。
  • 高并發(fā)請(qǐng)求集中在同一時(shí)間點(diǎn)。

3. 解決方案
(1)互斥鎖(分布式鎖)[推薦]

  • 思路:緩存失效時(shí),僅允許第一個(gè)請(qǐng)求獲取鎖,查詢數(shù)據(jù)庫(kù)并重建緩存,其余請(qǐng)求等待或返回舊數(shù)據(jù)。
  • 優(yōu)點(diǎn):保證數(shù)據(jù)一致性,避免并發(fā)重建。
  • 缺點(diǎn):鎖競(jìng)爭(zhēng)可能增加延遲,需防止死鎖。
  • 代碼示例(Redis分布式鎖)
public Object getData(String key) {
    Object value = redis.get(key);
    if (value == null) { // 緩存未命中
        if (redis.setNX(key + "_lock", "1", 10)) { // 獲取鎖,過期時(shí)間10秒
            try {
                value = db.queryData(key); // 查詢數(shù)據(jù)庫(kù)
                redis.set(key, value, 3600); // 重建緩存
            } finally {
                redis.del(key + "_lock"); // 釋放鎖
            }
        } else { // 未獲取鎖,等待重試
            Thread.sleep(50);
            return getData(key); // 遞歸調(diào)用
        }
    }
    return value;
}

(2)邏輯過期(不設(shè)置物理過期)

  • 思路:緩存數(shù)據(jù)中增加邏輯過期時(shí)間字段,后臺(tái)線程異步更新緩存,請(qǐng)求仍返回舊數(shù)據(jù)。
  • 優(yōu)點(diǎn):無鎖競(jìng)爭(zhēng),保證高可用。
  • 缺點(diǎn):數(shù)據(jù)短暫不一致,需接受舊數(shù)據(jù)。
  • 代碼示例
public class CacheData {
    private Object data;
    private long expireTime; // 邏輯過期時(shí)間戳
}
public Object getData(String key) {
    CacheData data = redis.get(key);
    if (data == null) {
        data = db.queryData(key);
        redis.set(key, data, 3600);
    }
    if (data.expireTime < System.currentTimeMillis()) { // 邏輯過期
        Thread asyncThread = new Thread(() -> {
            // 異步更新緩存
            CacheData newData = db.queryData(key);
            redis.set(key, newData, 3600);
        });
        asyncThread.start();
    }
    return data.data;
}

三、緩存雪崩(Cache Avalanche)

1. 定義與問題
緩存雪崩指大量緩存key同時(shí)過期或Redis服務(wù)宕機(jī),導(dǎo)致所有請(qǐng)求穿透緩存,直接壓垮數(shù)據(jù)庫(kù),引發(fā)系統(tǒng)癱瘓。例如,電商平臺(tái)商品緩存統(tǒng)一過期,凌晨用戶訪問高峰導(dǎo)致MySQL崩潰。

2. 核心原因

  • 緩存過期時(shí)間設(shè)置集中(如批量數(shù)據(jù)同一時(shí)間過期)。
  • Redis單點(diǎn)故障或集群不可用。
  • 系統(tǒng)啟動(dòng)時(shí)未預(yù)熱緩存。

3. 解決方案(分層防御)
(1)過期時(shí)間錯(cuò)開

  • 思路:為每個(gè)key增加隨機(jī)過期時(shí)間(如基礎(chǔ)過期時(shí)間 + 隨機(jī)值),分散失效時(shí)間點(diǎn)。
  • 代碼示例
redis.set(key, value, 3600 + new Random().nextInt(300)); // 基礎(chǔ)1小時(shí) + 0-5分鐘隨機(jī)

(2)Redis高可用集群

  • 部署哨兵(Sentinel)或集群模式:主從自動(dòng)切換,避免單點(diǎn)故障。
  • 配置限流/熔斷:如使用Hystrix或Sentinel,當(dāng)Redis請(qǐng)求超限時(shí)自動(dòng)降級(jí)。

(3)本地緩存兜底

  • 思路:使用Caffeine或Guava Cache作為本地二級(jí)緩存,Redis宕機(jī)時(shí)可返回本地?cái)?shù)據(jù)。
  • 代碼示例(Caffeine)
LoadingCache<String, Object> localCache = Caffeine.newBuilder()
    .expireAfterWrite(30, TimeUnit.MINUTES) // 本地緩存過期30分鐘
    .build(key -> redis.get(key));
public Object getData(String key) {
    Object value = localCache.get(key);
    if (value == null) {
        value = redis.get(key);
        localCache.put(key, value);
    }
    return value;
}

(4)緩存預(yù)熱

  • 系統(tǒng)啟動(dòng)時(shí)加載熱點(diǎn)數(shù)據(jù):通過定時(shí)任務(wù)或啟動(dòng)腳本,提前將高頻訪問數(shù)據(jù)加載到Redis。
  • 代碼示例(偽代碼)
public void warmUpCache() {
    List<String> hotKeys = db.getTopNKeys(); // 獲取Top N熱點(diǎn)key
    for (String key : hotKeys) {
        redis.set(key, db.queryData(key), 3600);
    }
}

四、總結(jié)

  1. 緩存穿透:使用布隆過濾器前置攔截?zé)o效請(qǐng)求,或緩存空值兜底。
  2. 緩存擊穿分布式鎖控制并發(fā)重建,或邏輯過期異步更新。
  3. 緩存雪崩分層防御策略,過期時(shí)間隨機(jī)化 + 高可用集群 + 本地緩存兜底 + 緩存預(yù)熱。
  4. 監(jiān)控與預(yù)警:實(shí)時(shí)監(jiān)控Redis命中率、數(shù)據(jù)庫(kù)QPS等指標(biāo),異常時(shí)自動(dòng)報(bào)警或熔斷。

通過以上方案組合使用,可大幅提升系統(tǒng)穩(wěn)定性,避免因緩存問題導(dǎo)致的服務(wù)崩潰。架構(gòu)設(shè)計(jì)時(shí)需根據(jù)實(shí)際業(yè)務(wù)場(chǎng)景權(quán)衡性能與一致性,選擇最適合的解決方案。

到此這篇關(guān)于Redis:緩存穿透、緩存擊穿與緩存雪崩的文章就介紹到這了,更多相關(guān)Redis緩存穿透、緩存擊穿與緩存雪崩內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Redis實(shí)現(xiàn)訂單自動(dòng)過期功能的示例代碼

    Redis實(shí)現(xiàn)訂單自動(dòng)過期功能的示例代碼

    這篇文章主要介紹了Redis實(shí)現(xiàn)訂單自動(dòng)過期功能的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-05-05
  • 淺談redis采用不同內(nèi)存分配器tcmalloc和jemalloc

    淺談redis采用不同內(nèi)存分配器tcmalloc和jemalloc

    下面小編就為大家?guī)硪黄獪\談redis采用不同內(nèi)存分配器tcmalloc和jemalloc。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2016-12-12
  • 解讀Redis的持久化方式(RDB、AOF)

    解讀Redis的持久化方式(RDB、AOF)

    文章主要介紹了Redis的RDB和AOF兩種持久化機(jī)制的區(qū)別、工作原理和優(yōu)點(diǎn),并詳細(xì)講解了Redis 4.0+版本中RDB+AOF混合持久化的實(shí)現(xiàn)方式、配置建議和實(shí)際應(yīng)用,強(qiáng)調(diào)了混合持久化在生產(chǎn)環(huán)境中的重要性和配置要點(diǎn),以及在不同場(chǎng)景下的推薦配置策略
    2026-04-04
  • Redis持久化使用及說明(RDB&AOF)

    Redis持久化使用及說明(RDB&AOF)

    Redis通過RDB(定期快照)和AOF(日志記錄)實(shí)現(xiàn)持久化,兼顧內(nèi)存性能與數(shù)據(jù)安全,RDB文件緊湊,適合冷備;AOF實(shí)時(shí)性強(qiáng),但體積較大,兩者結(jié)合使用(混合持久化)可平衡效率與可靠性,確保數(shù)據(jù)在異常重啟時(shí)恢復(fù)
    2025-08-08
  • 如何使用Redis保存用戶會(huì)話Session詳解

    如何使用Redis保存用戶會(huì)話Session詳解

    這篇文章主要給大家介紹了關(guān)于如何使用Redis保存用戶會(huì)話Session的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-01-01
  • Redis內(nèi)存回收用法及說明

    Redis內(nèi)存回收用法及說明

    Redis通過配置文件設(shè)置最大內(nèi)存空間,當(dāng)達(dá)到上限時(shí),會(huì)使用過期策略和淘汰策略來管理內(nèi)存,過期策略包括惰性刪除和周期刪除,而淘汰策略則根據(jù)內(nèi)存使用情況主動(dòng)刪除部分key以釋放空間
    2025-12-12
  • Redis消息隊(duì)列實(shí)現(xiàn)秒殺教程

    Redis消息隊(duì)列實(shí)現(xiàn)秒殺教程

    這篇文章主要介紹了Redis消息隊(duì)列實(shí)現(xiàn)秒殺教程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2025-04-04
  • Redis使用ZSET實(shí)現(xiàn)消息隊(duì)列的項(xiàng)目實(shí)踐

    Redis使用ZSET實(shí)現(xiàn)消息隊(duì)列的項(xiàng)目實(shí)踐

    本文主要介紹了Redis使用ZSET實(shí)現(xiàn)消息隊(duì)列的項(xiàng)目實(shí)踐,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-07-07
  • 基于Redis實(shí)現(xiàn)搶紅包和發(fā)紅包功能

    基于Redis實(shí)現(xiàn)搶紅包和發(fā)紅包功能

    搶紅包是我們生活常用的社交功能, 這個(gè)功能最主要的特點(diǎn)就是用戶的并發(fā)請(qǐng)求高, 在系統(tǒng)設(shè)計(jì)上, 可以使用非常多的辦法來扛住用戶的高并發(fā)請(qǐng)求, 在本文中簡(jiǎn)要介紹使用Redis緩存中間件來實(shí)現(xiàn)搶紅包算法,需要的朋友可以參考下
    2024-04-04
  • 淺談Redis中的內(nèi)存淘汰策略和過期鍵刪除策略

    淺談Redis中的內(nèi)存淘汰策略和過期鍵刪除策略

    本文主要介紹了淺談Redis中的內(nèi)存淘汰策略和過期鍵刪除策略,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-09-09

最新評(píng)論

莱州市| 驻马店市| 句容市| 西乌| 昌吉市| 宁蒗| 刚察县| 锡林郭勒盟| 淮南市| 南皮县| 论坛| 古浪县| 镇原县| 临桂县| 河南省| 喀什市| 南丰县| 农安县| 桂东县| 隆德县| 社会| 蓬莱市| 宜良县| 赤城县| 镇江市| 南川市| 府谷县| 盐城市| 大兴区| 东明县| 来凤县| 蒙自县| 美姑县| 府谷县| 湛江市| 思南县| 镇原县| 新兴县| 林芝县| 吴旗县| 资中县|