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

SpringBoot+Caffeine+Redis實(shí)現(xiàn)多級緩存的方法

 更新時(shí)間:2026年02月04日 09:41:45   作者:三水不滴  
多級緩存是指在系統(tǒng)中部署多層功能互補(bǔ)的緩存組件,讓請求按照預(yù)設(shè)順序依次訪問各層緩存,僅當(dāng)所有緩存層均未命中時(shí),才訪問底層數(shù)據(jù)庫的架構(gòu)模式,這篇文章主要介紹了SpringBoot+Caffeine+Redis實(shí)現(xiàn)多級緩存的方法,需要的朋友可以參考下

多級緩存:架構(gòu)設(shè)計(jì)、實(shí)戰(zhàn)落地與問題解決

在高并發(fā)分布式系統(tǒng)中,緩存是提升接口響應(yīng)速度、降低數(shù)據(jù)庫壓力的核心技術(shù),但單一緩存層往往難以兼顧性能、一致性高可用。多級緩存通過整合不同層級的緩存組件,揚(yáng)長避短構(gòu)建層次化緩存體系,成為支撐百萬級 QPS 系統(tǒng)的標(biāo)配方案。本文將從核心概念、架構(gòu)設(shè)計(jì)、實(shí)戰(zhàn)實(shí)現(xiàn)、一致性保障及經(jīng)典問題解決五個(gè)維度,全面解析多級緩存技術(shù),同時(shí)結(jié)合 SpringBoot+Caffeine+Redis 的實(shí)戰(zhàn)案例,讓技術(shù)落地更具可操作性。

一、什么是多級緩存?

多級緩存是指在系統(tǒng)中部署多層功能互補(bǔ)的緩存組件,讓請求按照預(yù)設(shè)順序依次訪問各層緩存,僅當(dāng)所有緩存層均未命中時(shí),才訪問底層數(shù)據(jù)庫的架構(gòu)模式。其核心設(shè)計(jì)思想是離用戶越近的緩存,速度越快、開銷越低,通過分層攔截請求,最大化減少對后端存儲的訪問。

在 Java 后端體系中,最主流的是二級緩存架構(gòu)(本地緩存 + 分布式緩存),部分場景會結(jié)合數(shù)據(jù)庫自身緩存形成三級體系,各層核心特性與選型如下:

  1. 本地緩存:運(yùn)行在應(yīng)用進(jìn)程內(nèi)部的內(nèi)存緩存,無網(wǎng)絡(luò) IO 開銷,讀寫延遲納秒級。主流選型為 Caffeine(性能優(yōu)于 Guava Cache、Ehcache),適合存儲高頻訪問的熱點(diǎn)數(shù)據(jù),缺點(diǎn)是數(shù)據(jù)僅當(dāng)前實(shí)例可見,無法分布式共享,且受 JVM 內(nèi)存限制。
  2. 分布式緩存:獨(dú)立于應(yīng)用的中間件,部署在集群中可被所有應(yīng)用實(shí)例共享,數(shù)據(jù)一致性更易保障。主流選型為 Redis(支持豐富數(shù)據(jù)結(jié)構(gòu)、持久化、分布式鎖),適合存儲全量熱點(diǎn)數(shù)據(jù) + 通用業(yè)務(wù)數(shù)據(jù),缺點(diǎn)是存在網(wǎng)絡(luò) IO 開銷,性能略低于本地緩存。
  3. 數(shù)據(jù)庫緩存:數(shù)據(jù)庫自身的查詢緩存 / 緩沖池(如 MySQL 的 InnoDB Buffer Pool),屬于底層被動緩存,通常無需人工干預(yù),僅作為最后一道數(shù)據(jù)屏障。

各層緩存性能對比(核心指標(biāo)):

緩存層級讀寫延遲集群共享部署成本適用場景
本地緩存(Caffeine)納秒級低(無獨(dú)立組件)高頻熱點(diǎn)數(shù)據(jù)、單機(jī)維度臨時(shí)數(shù)據(jù)
分布式緩存(Redis)微秒級中(需集群部署)全量熱點(diǎn)數(shù)據(jù)、跨實(shí)例共享數(shù)據(jù)
數(shù)據(jù)庫緩存毫秒級所有數(shù)據(jù)的最終存儲

二、為什么需要多級緩存?

單一緩存層在高并發(fā)場景下存在難以克服的短板,而多級緩存通過優(yōu)勢互補(bǔ)解決這些問題,同時(shí)帶來極致的性能提升。我們通過一組電商商品詳情頁的壓測數(shù)據(jù),直觀感受多級緩存的價(jià)值:

架構(gòu)模式QPSTP99 延遲 (ms)數(shù)據(jù)庫負(fù)載緩存命中率
單 Redis 緩存5.8 萬12065%75%
Caffeine+Redis 多級緩存120 萬458%99.2%

從數(shù)據(jù)可以看出,多級緩存讓 QPS 提升 20 倍、TP99 延遲降低 60%、數(shù)據(jù)庫負(fù)載減少 87%,核心價(jià)值體現(xiàn)在三個(gè)方面:

  1. 極致性能:本地緩存攔截 80% 以上的高頻請求,避免大量請求穿透到 Redis,減少網(wǎng)絡(luò) IO 和 Redis 集群壓力,讓接口響應(yīng)速度達(dá)到極致。
  2. 高可用兜底:當(dāng)分布式緩存集群(如 Redis)發(fā)生宕機(jī)時(shí),本地緩存可臨時(shí)兜底核心熱點(diǎn)數(shù)據(jù),避免系統(tǒng)直接雪崩,提升服務(wù)容錯(cuò)能力。
  3. 資源優(yōu)化:通過分層存儲數(shù)據(jù),將高頻數(shù)據(jù)放在本地緩存(低開銷),通用數(shù)據(jù)放在分布式緩存(共享性),避免 Redis 存儲大量低價(jià)值數(shù)據(jù),降低緩存集群的部署成本。

此外,多級緩存還能從架構(gòu)層面規(guī)避單一緩存的經(jīng)典問題,比如本地緩存的分布式一致性問題可通過 Redis 兜底,Redis 的網(wǎng)絡(luò)開銷問題可通過本地緩存攔截,讓系統(tǒng)更健壯。

三、多級緩存核心架構(gòu)設(shè)計(jì)

3.1 核心設(shè)計(jì)原則

多級緩存的設(shè)計(jì)需遵循3 個(gè)核心原則,否則易導(dǎo)致架構(gòu)臃腫、數(shù)據(jù)一致性混亂:

  1. 請求就近原則:請求優(yōu)先訪問本地緩存,未命中再訪問分布式緩存,最后訪問數(shù)據(jù)庫,反向流程不可行。
  2. 數(shù)據(jù)分層原則:不同價(jià)值的數(shù)據(jù)存儲在對應(yīng)層級,本地緩存僅存高頻熱點(diǎn)數(shù)據(jù)(控制容量,避免 OOM),分布式緩存存全量業(yè)務(wù)數(shù)據(jù),不重復(fù)存儲低價(jià)值數(shù)據(jù)。
  3. 失效由上至下原則:緩存更新 / 失效時(shí),先操作本地緩存,再操作分布式緩存,避免出現(xiàn) “本地緩存有舊數(shù)據(jù),分布式緩存有新數(shù)據(jù)” 的不一致情況。

3.2 主流架構(gòu):Caffeine+Redis 二級緩存

Java 后端中,Caffeine(本地)+ Redis(分布式) 是工業(yè)級落地的主流架構(gòu),適用于 90% 以上的業(yè)務(wù)場景(電商、社交、資訊等),其請求訪問流程數(shù)據(jù)更新流程如下,是后續(xù)實(shí)戰(zhàn)的核心基礎(chǔ)。

(1)請求訪問流程(讀操作)
  1. 應(yīng)用接收到請求后,首先查詢Caffeine 本地緩存,命中則直接返回結(jié)果,結(jié)束請求;
  2. 本地緩存未命中,查詢Redis 分布式緩存,命中則將數(shù)據(jù)回寫到本地緩存(方便后續(xù)請求攔截),然后返回結(jié)果;
  3. 分布式緩存也未命中,執(zhí)行數(shù)據(jù)庫查詢,查詢結(jié)果非空時(shí),依次回寫到 Redis 和 Caffeine,然后返回結(jié)果;
  4. 數(shù)據(jù)庫查詢結(jié)果為空時(shí),執(zhí)行空值緩存(短期過期),避免后續(xù)請求穿透到數(shù)據(jù)庫。
(2)數(shù)據(jù)更新流程(寫操作)

遵循 “先更數(shù)據(jù)庫,再刪緩存” 原則(避免 “先刪緩存,再更數(shù)據(jù)庫” 的并發(fā)不一致問題),核心步驟:

  1. 執(zhí)行數(shù)據(jù)庫的增 / 刪 / 改操作,保證數(shù)據(jù)落地;
  2. 刪除 Redis 對應(yīng)緩存(而非更新,避免并發(fā)覆蓋);
  3. 驅(qū)逐 Caffeine 本地緩存(當(dāng)前實(shí)例),若為集群部署,通過消息隊(duì)列(如 RocketMQ/Kafka)通知其他實(shí)例驅(qū)逐本地緩存;
  4. 后續(xù)請求會觸發(fā)緩存重新加載,保證數(shù)據(jù)最新。

注意:寫操作優(yōu)先選擇刪緩存而非更緩存,原因是:若同時(shí)有多個(gè)寫請求,直接更新緩存可能導(dǎo)致并發(fā)覆蓋,而刪除緩存后,由讀請求觸發(fā)懶加載,能保證緩存數(shù)據(jù)的最終一致性。

四、實(shí)戰(zhàn)落地:SpringBoot 整合 Caffeine+Redis 多級緩存

本節(jié)基于SpringBoot 2.7.x,實(shí)現(xiàn) Caffeine+Redis 的二級緩存架構(gòu),包含核心依賴、配置、代碼實(shí)現(xiàn),同時(shí)整合空值緩存、分布式鎖等特性,直接可用于生產(chǎn)環(huán)境(僅需根據(jù)業(yè)務(wù)調(diào)整參數(shù))。

4.1 核心依賴引入(Maven)

引入 Caffeine、Redis、SpringCache 核心依賴,簡化緩存操作,無需手動封裝緩存工具類:

<!-- SpringCache緩存抽象(簡化緩存注解使用) -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<!-- Caffeine本地緩存 -->
<dependency>
    <groupId>com.github.ben-manes.caffeine</groupId>
    <artifactId>caffeine</artifactId>
    <version>3.1.8</version>
</dependency>
<!-- Redis分布式緩存(Lettuce客戶端) -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- 序列化依賴(解決Redis存儲對象亂碼問題) -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson2</artifactId>
    <version>2.0.32</version>
</dependency>

4.2 核心配置(配置類 + yml)

(1)緩存配置類:初始化 Caffeine 和 Redis 緩存管理器

通過配置類實(shí)現(xiàn)雙緩存管理器,分別管理本地緩存和分布式緩存,支持注解式緩存操作,核心參數(shù)按需調(diào)整(如過期時(shí)間、最大容量):

import com.github.benmanes.caffeine.cache.Caffeine;
import org.springframework.cache.CacheManager;
import org.springframework.cache.caffeine.CaffeineCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import java.util.concurrent.TimeUnit;
@Configuration
@EnableCaching // 開啟SpringCache注解支持
public class MultiLevelCacheConfig {
    // 1. 本地緩存管理器(Caffeine):優(yōu)先使用,存儲熱點(diǎn)數(shù)據(jù)
    @Bean("caffeineCacheManager")
    public CacheManager caffeineCacheManager() {
        CaffeineCacheManager cacheManager = new CaffeineCacheManager();
        // 核心配置:最大容量1000條、寫入后5秒過期(短過期防臟數(shù)據(jù))、弱引用回收
        cacheManager.setCaffeine(Caffeine.newBuilder()
                .maximumSize(1000)
                .expireAfterWrite(5, TimeUnit.SECONDS)
                .weakValues());
        return cacheManager;
    }
    // 2. 分布式緩存管理器(Redis):@Primary表示默認(rèn)緩存管理器,存儲通用數(shù)據(jù)
    @Bean("redisCacheManager")
    @Primary
    public CacheManager redisCacheManager(RedisConnectionFactory factory) {
        // 序列化配置:解決對象亂碼
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
                .serializeValuesWith(RedisSerializationContext.SerializationPair
                        .fromSerializer(new GenericJackson2JsonRedisSerializer()))
                .entryTtl(30, TimeUnit.SECONDS); // 寫入后30秒過期
        return RedisCacheManager.builder(factory)
                .cacheDefaults(config)
                .build();
    }
}
(2)yml 配置:Redis 連接信息
spring:
  redis:
    host: 127.0.0.1
    port: 6379
    password: 123456
    lettuce:
      pool:
        max-active: 8 # 最大連接數(shù)
        max-idle: 8   # 最大空閑連接
        min-idle: 2   # 最小空閑連接
        max-wait: 1000ms # 連接等待時(shí)間
    timeout: 3000ms # 連接超時(shí)時(shí)間

4.3 業(yè)務(wù)層實(shí)現(xiàn):注解式多級緩存操作

基于 SpringCache 注解,實(shí)現(xiàn)商品詳情查詢商品庫存更新的核心業(yè)務(wù),完美貼合前文的 “請求訪問流程” 和 “數(shù)據(jù)更新流程”,代碼簡潔易維護(hù):

import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.CachePut;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.Optional;
@Service
public class ProductService {
    @Resource
    private ProductMapper productMapper; // 數(shù)據(jù)庫Mapper
    @Resource
    private StringRedisTemplate redisTemplate;
    // 空值標(biāo)記:解決緩存穿透
    private static final Product NULL_PRODUCT = new Product(-1L, "NULL", 0, 0.0);
    /**
     * 商品詳情查詢:多級緩存(先Caffeine,再Redis,最后DB)
     * @Cacheable:緩存查詢結(jié)果,指定本地緩存管理器
     */
    @Cacheable(value = "product", key = "#id", cacheManager = "caffeineCacheManager")
    public Product getProduct(Long id) {
        // 1. 本地緩存未命中,查詢Redis
        String redisKey = "product:" + id;
        Product redisProduct = redisTemplate.opsForValue().get(redisKey);
        if (redisProduct != null) {
            return redisProduct;
        }
        // 2. Redis未命中,查詢數(shù)據(jù)庫
        Product dbProduct = productMapper.selectById(id);
        // 3. 空值緩存:防止穿透
        Product cacheProduct = Optional.ofNullable(dbProduct).orElse(NULL_PRODUCT);
        // 4. 回寫Redis:設(shè)置60秒過期
        redisTemplate.opsForValue().set(redisKey, cacheProduct, 60, TimeUnit.SECONDS);
        // 5. 若為NULL_PRODUCT,返回null,避免業(yè)務(wù)層處理異常
        return cacheProduct.equals(NULL_PRODUCT) ? null : cacheProduct;
    }
    /**
     * 商品庫存更新:先更DB,再刪緩存(保證一致性)
     * @CacheEvict:刪除指定緩存
     */
    @CacheEvict(value = "product", key = "#productId", cacheManager = "caffeineCacheManager")
    public void updateProductStock(Long productId, int delta) {
        // 1. 更新數(shù)據(jù)庫:先落地?cái)?shù)據(jù)
        productMapper.updateStock(productId, delta);
        // 2. 刪除Redis緩存:避免舊數(shù)據(jù)
        String redisKey = "product:" + productId;
        redisTemplate.delete(redisKey);
        // 3. 本地緩存已通過@CacheEvict刪除,無需手動操作
    }
}

4.4 集群化改造:本地緩存一致性

上述代碼僅適用于單機(jī)部署,集群部署時(shí),某一實(shí)例更新數(shù)據(jù)后,其他實(shí)例的本地緩存仍會存在舊數(shù)據(jù),導(dǎo)致數(shù)據(jù)不一致。解決該問題的主流方案是基于消息隊(duì)列的緩存通知,核心思路:

  1. 部署消息隊(duì)列(如 RocketMQ/Kafka),創(chuàng)建緩存更新主題;
  2. 當(dāng)某一實(shí)例執(zhí)行緩存刪除操作時(shí),向主題發(fā)送緩存失效消息(包含緩存 key、緩存名稱);
  3. 所有應(yīng)用實(shí)例均作為消費(fèi)者,監(jiān)聽該主題,收到消息后,刪除本地對應(yīng)緩存;
  4. 保證消息的至少一次消費(fèi),避免緩存失效消息丟失。

簡化實(shí)現(xiàn):使用 Redis 的 Pub/Sub 替代消息隊(duì)列(輕量、無需獨(dú)立部署),實(shí)現(xiàn)緩存通知,適合中小型集群。

五、多級緩存的一致性保障

多級緩存的核心痛點(diǎn)是數(shù)據(jù)一致性—— 各層緩存之間、各實(shí)例的本地緩存之間,可能因更新延遲、緩存污染導(dǎo)致數(shù)據(jù)不一致。由于強(qiáng)一致性會引入分布式事務(wù)、鎖等機(jī)制,導(dǎo)致性能大幅下降,工業(yè)級場景中均采用最終一致性(允許短時(shí)間不一致,最終所有緩存層數(shù)據(jù)收斂),核心保障策略分為三類:

5.1 緩存更新策略:選對策略,從源頭減少不一致

主流的緩存更新策略有 3 種,結(jié)合多級緩存的特性, “先更 DB,再刪緩存” 是最優(yōu)選擇,其他策略僅適用于特殊場景:

  1. 先更 DB,再刪緩存(推薦):無并發(fā)覆蓋問題,實(shí)現(xiàn)簡單,僅存在 “刪緩存失敗” 的小概率問題,可通過定時(shí)任務(wù)補(bǔ)償解決;
  2. 先刪緩存,再更 DB:高并發(fā)下會出現(xiàn) “緩存臟數(shù)據(jù)”(A 刪緩存→B 查緩存未命中→查舊 DB→回寫緩存→A 更 DB),導(dǎo)致緩存數(shù)據(jù)長期不一致;
  3. 雙寫策略(更新 DB 同時(shí)更新緩存):高并發(fā)下會出現(xiàn) “緩存覆蓋”(A 和 B 同時(shí)更新 DB,再先后更新緩存,導(dǎo)致緩存數(shù)據(jù)與最新 DB 數(shù)據(jù)不一致),僅適用于低并發(fā)場景。

5.2 過期時(shí)間策略:強(qiáng)制讓臟數(shù)據(jù)失效

為各層緩存設(shè)置合理的過期時(shí)間(TTL) ,是最終一致性的最后一道屏障,即使出現(xiàn)緩存更新失敗,臟數(shù)據(jù)也會在過期后自動失效,重新從 DB 加載最新數(shù)據(jù)。

  • 本地緩存(Caffeine):設(shè)置短 TTL(5-10 秒),快速淘汰臟數(shù)據(jù),避免本地緩存長期不一致;
  • 分布式緩存(Redis):設(shè)置中等 TTL(30-60 秒),兼顧緩存命中率和數(shù)據(jù)新鮮度;
  • 空值緩存:設(shè)置極短 TTL(3-5 分鐘),避免無效空值占用過多緩存空間。

同時(shí),為 Redis 緩存設(shè)置隨機(jī) TTL 偏移量(如 30 秒 ±5 秒),避免大量緩存同時(shí)過期導(dǎo)致的雪崩問題。

5.3 異步同步策略:解決集群本地緩存一致性

如前文所述,集群部署時(shí)的本地緩存一致性,通過 “消息通知 + 異步刪除” 實(shí)現(xiàn),主流方案對比:

同步方案實(shí)現(xiàn)難度性能適用場景
Redis Pub/Sub中小型集群、對一致性要求一般的場景
消息隊(duì)列(RocketMQ/Kafka)大型集群、核心業(yè)務(wù)場景
分布式配置中心(Nacos/Apollo)配置類緩存、低頻更新數(shù)據(jù)

六、多級緩存經(jīng)典問題解決

緩存系統(tǒng)的三大經(jīng)典問題 ——穿透、擊穿、雪崩,在多級緩存架構(gòu)中可通過分層防護(hù)實(shí)現(xiàn)更高效的解決,相比單一緩存層,防護(hù)手段更豐富、效果更徹底。

6.1 緩存穿透:攔截?zé)o效請求,避免穿透到 DB

問題定義:請求查詢的數(shù)在所有緩存層和 DB 中均不存在,導(dǎo)致每次請求都穿透到 DB,若遭遇惡意請求(如偽造不存在的商品 ID),會壓垮數(shù)據(jù)庫。多級緩存防護(hù)方案(雙重防護(hù),層層攔截):

  1. 第一層:接口層參數(shù)校驗(yàn):在 Controller/Gateway 層對請求參數(shù)做強(qiáng)校驗(yàn)(如 ID 必須大于 0、符合業(yè)務(wù)規(guī)則),直接攔截明顯無效的請求;
  2. 第二層:空值緩存:在 Caffeine 和 Redis 中緩存空值(如前文的 NULL_PRODUCT),設(shè)置短 TTL,讓后續(xù)相同無效請求被緩存攔截;
  3. 進(jìn)階方案:布隆過濾器:將 DB 中所有有效主鍵(如商品 ID、用戶 ID)預(yù)先加載到布隆過濾器,請求先經(jīng)過過濾器校驗(yàn),不存在的鍵直接攔截,僅可能存在的鍵才進(jìn)入緩存層,適合超大規(guī)模數(shù)據(jù)場景(如千萬級商品庫)。

6.2 緩存擊穿:保護(hù)熱點(diǎn)數(shù)據(jù),避免單點(diǎn)穿透

問題定義:某個(gè)超高訪問量的熱點(diǎn)數(shù)據(jù)(如秒殺商品)在緩存中過期的瞬間,大量并發(fā)請求同時(shí)穿透到 DB,導(dǎo)致數(shù)據(jù)庫單點(diǎn)壓力驟增。多級緩存防護(hù)方案(熱點(diǎn)數(shù)據(jù)專屬防護(hù)):

  1. 第一層:熱點(diǎn)數(shù)據(jù)永不過期:對秒殺、首頁焦點(diǎn)圖等核心熱點(diǎn)數(shù)據(jù),設(shè)置物理永不過期,通過手動更新 / 刪除控制緩存生命周期,從源頭避免過期;
  2. 第二層:本地鎖 + 分布式鎖雙重鎖:緩存過期后,通過本地鎖(synchronized) 攔截單機(jī)內(nèi)的并發(fā)請求,再通過Redis 分布式鎖(Redisson) 攔截集群內(nèi)的并發(fā)請求,僅允許一個(gè)線程查詢 DB 并更新緩存,其他線程等待緩存更新后再查詢;
  3. 第三層:熱點(diǎn)數(shù)據(jù)預(yù)熱:系統(tǒng)啟動時(shí) / 流量高峰前,通過定時(shí)任務(wù)將熱點(diǎn)數(shù)據(jù)主動加載到 Caffeine 和 Redis 中,避免緩存冷啟動導(dǎo)致的擊穿。

6.3 緩存雪崩:分散過期時(shí)間,避免集體穿透

問題定義:大量緩存數(shù)據(jù)在同一時(shí)間點(diǎn)過期,或分布式緩存集群(Redis)宕機(jī),導(dǎo)致所有請求瞬間涌向 DB,引發(fā)數(shù)據(jù)庫雪崩,進(jìn)而導(dǎo)致整個(gè)系統(tǒng)癱瘓。多級緩存防護(hù)方案(架構(gòu)級防護(hù),容錯(cuò)性拉滿):

  1. 第一層:差異化 TTL:為 Redis 緩存設(shè)置隨機(jī)過期時(shí)間偏移量(如基礎(chǔ) TTL30 秒 + 隨機(jī) 0-5 秒),讓緩存過期時(shí)間分散,避免集體失效;
  2. 第二層:多級緩存兜底:即使 Redis 集群宕機(jī),Caffeine 本地緩存仍能攔截大部分熱點(diǎn)請求,保證核心業(yè)務(wù)可用,同時(shí)觸發(fā)告警機(jī)制;
  3. 第三層:緩存高可用 + 服務(wù)降級:Redis 采用 Cluster/Sentinel 集群部署,避免單點(diǎn)故障;同時(shí)結(jié)合 Hystrix/Sentinel 實(shí)現(xiàn)服務(wù)降級,當(dāng) DB 壓力達(dá)到閾值時(shí),直接返回本地緩存的兜底數(shù)據(jù),放棄部分?jǐn)?shù)據(jù)新鮮度,保證服務(wù)可用性;
  4. 第四層:數(shù)據(jù)庫限流:在 DB 代理層(如 MyCat)設(shè)置訪問限流,控制每秒訪問 DB 的請求數(shù),避免數(shù)據(jù)庫被壓垮。

七、多級緩存調(diào)優(yōu)與監(jiān)控

7.1 性能調(diào)優(yōu)關(guān)鍵參數(shù)

多級緩存的性能調(diào)優(yōu)核心是平衡緩存命中率和資源占用,關(guān)鍵參數(shù)調(diào)整原則:

  1. Caffeine 調(diào)優(yōu)maximumSize根據(jù) JVM 內(nèi)存合理設(shè)置(如單機(jī) 1G 內(nèi)存設(shè)置 1000-2000 條),避免 OOM;優(yōu)先使用expireAfterWrite(寫入后過期)而非expireAfterAccess(訪問后過期),減少性能開銷;
  2. Redis 調(diào)優(yōu):開啟持久化(RDB+AOF 混合),避免數(shù)據(jù)丟失;優(yōu)化連接池參數(shù)(如max-active根據(jù)并發(fā)量設(shè)置),減少連接等待;使用 Redis Cluster 集群,提升并發(fā)能力;
  3. JVM 調(diào)優(yōu):開啟 G1GC,設(shè)置-XX:MaxGCPauseMillis=100,減少 GC 停頓對本地緩存的影響;合理設(shè)置 JVM 堆內(nèi)存,為本地緩存預(yù)留足夠空間。

7.2 核心監(jiān)控指標(biāo)

無監(jiān)控不架構(gòu),多級緩存需要監(jiān)控各層緩存的核心指標(biāo),及時(shí)發(fā)現(xiàn)緩存失效、命中率低等問題,主流監(jiān)控方案為 Prometheus+Grafana:

  1. 緩存命中率:核心指標(biāo),本地緩存(Caffeine)命中率應(yīng)≥90%,Redis 命中率應(yīng)≥95%,命中率過低需分析數(shù)據(jù)分布,調(diào)整緩存策略;
  2. 緩存未命中率:持續(xù)偏高需排查是否存在穿透、擊穿問題;
  3. Redis 指標(biāo):CPU 使用率、內(nèi)存使用率、網(wǎng)絡(luò) IO、連接數(shù),避免 Redis 成為性能瓶頸;
  4. 數(shù)據(jù)庫指標(biāo):QPS、連接數(shù)、慢查詢數(shù),驗(yàn)證緩存攔截效果,若數(shù)據(jù)庫 QPS 持續(xù)偏高,需優(yōu)化緩存策略。

監(jiān)控實(shí)現(xiàn):Caffeine 自帶監(jiān)控指標(biāo),可通過Cache.stats()獲取;Redis 可通過 Exporter 采集指標(biāo);最終在 Grafana 中制作可視化大盤,設(shè)置指標(biāo)告警(如命中率低于 90% 時(shí)觸發(fā)短信 / 釘釘告警)。

八、大廠落地最佳實(shí)踐

多級緩存在阿里、京東、拼多多等大廠的高并發(fā)場景中已廣泛落地,總結(jié)其核心落地經(jīng)驗(yàn),讓技術(shù)落地更貼合生產(chǎn)環(huán)境:

  1. 數(shù)據(jù)分層存儲:本地緩存僅存TOP 10% 的高頻熱點(diǎn)數(shù)據(jù),其余數(shù)據(jù)存在 Redis,避免本地緩存占用過多 JVM 內(nèi)存;
  2. 避免過度設(shè)計(jì):中小型系統(tǒng)優(yōu)先使用 “Caffeine+Redis” 二級架構(gòu),無需引入更多緩存層,增加架構(gòu)復(fù)雜度;
  3. 緩存更新失敗補(bǔ)償:針對 “刪緩存失敗” 問題,增加定時(shí)任務(wù)補(bǔ)償(如每分鐘掃描 DB 更新日志,對比緩存數(shù)據(jù),刪除不一致的緩存);
  4. 冷啟動防護(hù):系統(tǒng)重啟時(shí),先通過預(yù)熱腳本加載熱點(diǎn)數(shù)據(jù),再對外提供服務(wù),避免冷啟動導(dǎo)致的緩存穿透、擊穿;
  5. 灰度發(fā)布:緩存策略變更(如 TTL 調(diào)整、數(shù)據(jù)分層變更)時(shí),采用灰度發(fā)布,逐步擴(kuò)大范圍,避免全量發(fā)布導(dǎo)致的性能問題。

九、總結(jié)

多級緩存并非簡單的 “本地緩存 + 分布式緩存” 組合,而是一套兼顧性能、一致性、高可用的層次化架構(gòu)設(shè)計(jì)思想。其核心價(jià)值在于通過分層攔截請求,將性能做到極致,同時(shí)通過最終一致性策略、分層防護(hù)手段,解決緩存的經(jīng)典問題,成為支撐百萬級 QPS 高并發(fā)系統(tǒng)的核心技術(shù)。

本文結(jié)合 SpringBoot+Caffeine+Redis 的實(shí)戰(zhàn)案例,從架構(gòu)設(shè)計(jì)到代碼實(shí)現(xiàn),從一致性保障到問題解決,實(shí)現(xiàn)了技術(shù)的全鏈路落地。在實(shí)際項(xiàng)目中,無需生搬硬套,可根據(jù)業(yè)務(wù)規(guī)模、并發(fā)量、數(shù)據(jù)一致性要求,靈活調(diào)整緩存架構(gòu)和策略 —— 中小型系統(tǒng)優(yōu)先保證落地簡單,大型高并發(fā)系統(tǒng)重點(diǎn)做好緩存分層、監(jiān)控和容錯(cuò)。

緩存的本質(zhì)是用空間換時(shí)間,而多級緩存則是讓這份 “交換” 的性價(jià)比達(dá)到最高,這也是其能成為高并發(fā)系統(tǒng)標(biāo)配的根本原因。

到此這篇關(guān)于SpringBoot+Caffeine+Redis實(shí)現(xiàn)多級緩存的文章就介紹到這了,更多相關(guān)SpringBoot Caffeine Redis多級緩存內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論

武清区| 双牌县| 庆阳市| 敦煌市| 滕州市| 三穗县| 伊宁市| 玉龙| 左权县| 郓城县| 泰兴市| 建瓯市| 大英县| 曲阜市| 三河市| 莱阳市| 津市市| 五原县| 泰安市| 九江市| 嘉祥县| 上蔡县| 长顺县| 紫云| 民丰县| 长春市| 大同县| 泾川县| 宾川县| 天门市| 博白县| 射洪县| 天峻县| 翁牛特旗| 赤城县| 汝州市| 商河县| 永寿县| 鞍山市| 库尔勒市| 宁城县|