基于Spring Boot的多级缓存架构实现

打印 上一主题 下一主题

主题 955|帖子 955|积分 2880

基于Spring Boot的多级缓存架构实现

以下是一个基于Spring Boot的多级缓存架构实现示例

多级缓存架构实现方案

1. 依赖配置(pom.xml)

  1. <dependency>
  2.     <groupId>org.springframework.boot</groupId>
  3.     <artifactId>spring-boot-starter-cache</artifactId>
  4. </dependency>
  5. <dependency>
  6.     <groupId>com.github.ben-manes.caffeine</groupId>
  7.     <artifactId>caffeine</artifactId>
  8. </dependency>
  9. <dependency>
  10.     <groupId>org.springframework.boot</groupId>
  11.     <artifactId>spring-boot-starter-data-redis</artifactId>
  12. </dependency>
复制代码
2. 缓存配置类

  1. @Configuration
  2. @EnableCaching
  3. public class MultiLevelCacheConfig {
  4.     // 一级缓存(本地缓存)
  5.     @Bean
  6.     public CacheManager caffeineCacheManager() {
  7.         CaffeineCacheManager manager = new CaffeineCacheManager();
  8.         manager.setCaffeine(Caffeine.newBuilder()
  9.                 .maximumSize(1000)
  10.                 .expireAfterWrite(30, TimeUnit.SECONDS)); // 本地缓存比Redis缓存更短
  11.         return manager;
  12.     }
  13.     // 二级缓存(Redis缓存)
  14.     @Bean
  15.     public CacheManager redisCacheManager(RedisConnectionFactory factory) {
  16.         RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
  17.                 .entryTtl(Duration.ofMinutes(5))
  18.                 .serializeValuesWith(SerializationPair.fromSerializer(RedisSerializer.json()));
  19.         return RedisCacheManager.builder(factory)
  20.                 .cacheDefaults(config)
  21.                 .transactionAware()
  22.                 .build();
  23.     }
  24.     // 组合缓存管理器
  25.     @Bean
  26.     @Primary
  27.     public CacheManager multiLevelCacheManager(
  28.             @Qualifier("caffeineCacheManager") CacheManager level1,
  29.             @Qualifier("redisCacheManager") CacheManager level2) {
  30.         return new MultiLevelCacheManager(level1, level2);
  31.     }
  32. }
复制代码
3. 多级缓存管理器实现

  1. public class MultiLevelCacheManager implements CacheManager {
  2.     private final CacheManager level1; // 本地缓存
  3.     private final CacheManager level2; // Redis缓存
  4.     private final ConcurrentMap<String, Cache> cacheMap = new ConcurrentHashMap<>();
  5.     public MultiLevelCacheManager(CacheManager level1, CacheManager level2) {
  6.         this.level1 = level1;
  7.         this.level2 = level2;
  8.     }
  9.     @Override
  10.     public Cache getCache(String name) {
  11.         return cacheMap.computeIfAbsent(name,
  12.             key -> new MultiLevelCache(
  13.                 level1.getCache(name),
  14.                 level2.getCache(name)
  15.             ));
  16.     }
  17.     @Override
  18.     public Collection<String> getCacheNames() {
  19.         return Stream.concat(
  20.             level1.getCacheNames().stream(),
  21.             level2.getCacheNames().stream()
  22.         ).collect(Collectors.toSet());
  23.     }
  24.     // 多级缓存实现
  25.     static class MultiLevelCache implements Cache {
  26.         private final Cache level1;
  27.         private final Cache level2;
  28.         private final String name;
  29.         public MultiLevelCache(Cache level1, Cache level2) {
  30.             this.level1 = level1 != null ? level1 : new NoOpCache();
  31.             this.level2 = level2 != null ? level2 : new NoOpCache();
  32.             this.name = level1.getName() + ":" + level2.getName();
  33.         }
  34.         @Override
  35.         public String getName() {
  36.             return name;
  37.         }
  38.         @Override
  39.         public Object getNativeCache() {
  40.             return this;
  41.         }
  42.         @Override
  43.         public ValueWrapper get(Object key) {
  44.             // 先查一级缓存
  45.             ValueWrapper value = level1.get(key);
  46.             if (value == null) {
  47.                 // 二级缓存查询
  48.                 value = level2.get(key);
  49.                 if (value != null) {
  50.                     // 回填一级缓存
  51.                     level1.put(key, value.get());
  52.                 }
  53.             }
  54.             return value;
  55.         }
  56.         @Override
  57.         public <T> T get(Object key, Class<T> type) {
  58.             // 实现逻辑类似get方法
  59.             T value = level1.get(key, type);
  60.             if (value == null) {
  61.                 value = level2.get(key, type);
  62.                 if (value != null) {
  63.                     level1.put(key, value);
  64.                 }
  65.             }
  66.             return value;
  67.         }
  68.         @Override
  69.         public void put(Object key, Object value) {
  70.             // 同时写入两级缓存
  71.             level1.put(key, value);
  72.             level2.put(key, value);
  73.         }
  74.         @Override
  75.         public void evict(Object key) {
  76.             // 同时清除两级缓存
  77.             level1.evict(key);
  78.             level2.evict(key);
  79.         }
  80.         @Override
  81.         public void clear() {
  82.             level1.clear();
  83.             level2.clear();
  84.         }
  85.     }
  86.     // 空缓存实现(容错)
  87.     static class NoOpCache implements Cache {
  88.         // 实现基础的Cache方法,返回空值
  89.     }
  90. }
复制代码
4. 业务层使用

  1. @Service
  2. public class ProductService {
  3.     @Cacheable(value = "products", key = "#id")
  4.     public Product getProduct(Long id) {
  5.         // 数据库查询逻辑
  6.         return productRepository.findById(id)
  7.                .orElseThrow(() -> new NotFoundException("Product not found"));
  8.     }
  9.     @CacheEvict(value = "products", key = "#product.id")
  10.     public void updateProduct(Product product) {
  11.         productRepository.save(product);
  12.     }
  13. }
复制代码
5. 配置说明(application.yml)

  1. spring:
  2.   cache:
  3.     multi-level:
  4.       level1:
  5.         ttl: 30s    # 本地缓存时间
  6.         max-size: 1000
  7.       level2:
  8.         ttl: 5m     # Redis缓存时间
  9.   redis:
  10.     host: redis-cluster.prod
  11.     port: 6379
  12.     timeout: 2000ms
复制代码

关键实现要点


  • 缓存层级策略
     

  • 一致性保障


  • 写操作:同时清除两级缓存(@CacheEvict​)
  • 读操作:二级缓存掷中后自动回填一级缓存
  • TTL策略:一级缓存TTL(30s) < 二级缓存TTL(5m)

  • 性能优化


  • 本地缓存:使用Caffeine高性能缓存库
  • 异步回填:可扩展为异步加载(需自定义CacheLoader)
  • 批量操作:支持@Cacheable的批量查询优化

扩展发起


  • 缓存预热
  1. @PostConstruct
  2. public void preloadHotData() {
  3.     // 加载热点数据到缓存
  4.     hotProducts.forEach(product ->
  5.         cacheManager.getCache("products").put(product.getId(), product));
  6. }
复制代码

  • 监控集成
  1. @Bean
  2. public MeterRegistryCustomizer<MeterRegistry> cacheMetrics() {
  3.     return registry -> {
  4.         CaffeineCacheManager caffeine = context.getBean(CaffeineCacheManager.class);
  5.         RedisCacheManager redis = context.getBean(RedisCacheManager.class);
  6.         
  7.         // 注册Caffeine监控
  8.         CacheMetrics.monitor(registry, caffeine, "level1");
  9.         // 注册Redis监控
  10.         CacheMetrics.monitor(registry, redis, "level2");
  11.     };
  12. }
复制代码

  • 防雪崩策略
  1. // 在MultiLevelCache.get方法中添加
  2. ValueWrapper get(Object key) {
  3.     try {
  4.         // 添加分布式锁检查
  5.         if (lockManager.tryLock(key)) {
  6.             // 实际查询逻辑
  7.         }
  8.     } finally {
  9.         lockManager.unlock(key);
  10.     }
  11. }
复制代码


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

大连全瓷种植牙齿制作中心

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表