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

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

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

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

一、緩存穿透(Cache Penetration)

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

2. 核心原因

  • 業(yè)務邏輯錯誤:前端未校驗請求參數(shù),導致無效key直達數(shù)據(jù)庫。
  • 惡意攻擊:黑客故意構造大量不存在的key進行請求。

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

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

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

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

二、緩存擊穿(Cache Breakdown)

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

2. 核心原因

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

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

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

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

  • 思路:緩存數(shù)據(jù)中增加邏輯過期時間字段,后臺線程異步更新緩存,請求仍返回舊數(shù)據(jù)。
  • 優(yōu)點:無鎖競爭,保證高可用。
  • 缺點:數(shù)據(jù)短暫不一致,需接受舊數(shù)據(jù)。
  • 代碼示例
public class CacheData {
    private Object data;
    private long expireTime; // 邏輯過期時間戳
}
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同時過期或Redis服務宕機,導致所有請求穿透緩存,直接壓垮數(shù)據(jù)庫,引發(fā)系統(tǒng)癱瘓。例如,電商平臺商品緩存統(tǒng)一過期,凌晨用戶訪問高峰導致MySQL崩潰。

2. 核心原因

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

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

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

(2)Redis高可用集群

  • 部署哨兵(Sentinel)或集群模式:主從自動切換,避免單點故障。
  • 配置限流/熔斷:如使用Hystrix或Sentinel,當Redis請求超限時自動降級。

(3)本地緩存兜底

  • 思路:使用Caffeine或Guava Cache作為本地二級緩存,Redis宕機時可返回本地數(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)緩存預熱

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

四、總結

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

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

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

相關文章

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

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

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

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

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

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

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

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

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

    如何使用Redis保存用戶會話Session詳解

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

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

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

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

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

    Redis使用ZSET實現(xiàn)消息隊列的項目實踐

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

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

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

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

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

最新評論

公主岭市| 通化市| 梓潼县| 阿合奇县| 宽甸| 清原| 巴林左旗| 连南| 兴义市| 丰台区| 泗水县| 馆陶县| 天镇县| 宝应县| 和龙市| 淮安市| 美姑县| 安塞县| 姚安县| 东乡县| 东乌珠穆沁旗| 南开区| 措美县| 安岳县| 西华县| 昆山市| 柯坪县| 瑞金市| 太仆寺旗| 安国市| 合肥市| 平邑县| 达拉特旗| 印江| 青河县| 清河县| 揭阳市| 宁南县| 苍溪县| 涟水县| 阳新县|