多级缓存对比(Caffeine + Redis),以及缓存不一致问题的解决

这篇文章资料来自于网络,是对部分知识整理,这里只是记录一下,仅供参考

一、Spring Cache、Caffeine、Ehcache、Redis、Guava缓存的对比分析与选型建议:


1.1、核心特性对比

特性 Spring Cache(抽象层) Caffeine Ehcache Redis Guava(已淘汰)
类型 缓存抽象接口 本地高性能缓存 本地/分布式缓存 分布式缓存 本地缓存(旧版)
性能 依赖具体实现 极高性能(W-TinyLFU) 中高(支持磁盘存储) 高(网络延迟敏感) 中(基于LRU)
分布式支持 支持(RMI/JGroup) 原生支持集群
持久化 支持(磁盘存储) 支持(RDB/AOF)
适用场景 注解化缓存管理 单节点高频访问 单机或简单分布式 跨进程共享/大规模数据 旧项目兼容

1.2、选型建议与适用场景

1. Spring Cache(抽象层)

  • 定位 :提供统一的缓存API,支持多种缓存实现(如Caffeine、Redis等),通过注解(@Cacheable@CacheEvict)简化开发13。
  • 适用场景:需要快速集成缓存且希望代码与具体实现解耦的项目。适合结合Caffeine或Redis使用。
  • 局限性:复杂场景(如动态刷新、多级缓存联动)需直接操作底层API。

2. Caffeine

  • 优势 :基于W-TinyLFU算法,命中率高;性能碾压Guava(读写吞吐量提升4倍以上)68。

  • 适用场景:单机高并发场景(如电商秒杀),需要极低延迟的本地缓存。Spring 5+默认推荐替代Guava48。

  • 配置示例

    Caffeine.newBuilder() .maximumSize(10_000) .expireAfterWrite(5, TimeUnit.MINUTES) .build();

3. Ehcache

  • 优势 :支持磁盘持久化内存溢出保护,适合数据量较大的单机应用;与Spring集成良好39。
  • 适用场景:需要缓存数据持久化(如重启后恢复)或简单分布式同步(通过RMI)。例如金融系统的静态配置缓存。
  • 局限性:集群方案复杂,性能低于Caffeine57。

4. Redis

  • 优势:分布式缓存、数据持久化、丰富数据结构(如Hash/List);支持哨兵和集群模式,高可用性强。
  • 适用场景:跨服务共享数据(如会话缓存)、高频读写且需保证一致性的场景(如库存扣减)。
  • 注意点 :网络延迟可能成为瓶颈,需结合本地缓存(如Caffeine)形成多级缓存

5. Guava(历史选择)

  • 现状:已被Caffeine全面取代,Spring 5+不再支持。仅建议旧项目维护时使用。
  • 缺陷:基于LRU算法,命中率低于Caffeine;不支持空值缓存。

二、多级缓存架构实现(Caffeine + Redis)

Caffeine 与 Redis 的深度集成

在现代 Java 开发领域,Spring Cache 凭借其简洁高效的特性,成为了众多开发者优化应用性能的首选利器。它巧妙地将缓存逻辑与业务代码解耦,让我们只需通过简单的注解操作,便能轻松享受缓存带来的 "速度加成"。而 Spring Cache 的强大之处,还体现在它对多种缓存实现的支持,其中 Caffeine 和 Redis 无疑是备受瞩目的两种方案。

1. 架构原理
  1. 请求数据返回数据
  2. 查询Redis返回数据写入本地缓存返回数据
  3. 查询数据库返回数据写入Redis返回数据写入本地缓存返回数据

三、缓存不一致问题的解决

1. 缓存一致性

两级缓存与数据库的数据要保持一致,一旦数据发生了修改,在修改数据库的同时,本地缓存、远程缓存应该同步更新。

解决方案1: MQ

一般现在部署都是集群部署,有多个不同节点的本地缓存; 可以使用MQ的广播模式,当数据修改时向MQ发送消息,节点监听并消费消息,删除本地缓存,达到最终一致性;

解决方案2:Canal + MQ

如果你不想在你的业务代码发送MQ消息,还可以适用近几年比较流行的方法:订阅数据库变更日志,再操作缓存。Canal 订阅Mysql的 Binlog日志,当发生变化时向MQ发送消息,进而也实现数据一致性。

四、 本地内存的技术选型问题

  • 从易用性角度,Guava Cache、Caffeine和Encache都有十分成熟的接入方案,使用简单。
  • 从功能性角度,Guava Cache和Caffeine功能类似,都是只支持堆内缓存,Encache相比功能更为丰富
    • 从性能上进行比较,Caffeine最优、GuavaCache次之,Encache最差(下图是三者的性能对比结果)

      虽然Encache功能更为丰富,甚至提供了持久化和集群的功能,但是这些功能完全可以依靠其他方式实现。真实的业务工程中,建议使用Caffeine作为本地缓存,另外使用redis或者memcache作为分布式缓存,构造多级缓存体系,保证性能和可靠性。

五、参考

https://juejin.cn/post/7502349133346963507

https://juejin.cn/post/7563190036532166719

https://blog.csdn.net/Y_eatMeat/article/details/144224689

https://blog.csdn.net/Nanki_/article/details/135118271

https://www.cnblogs.com/Bytezero/p/18820662

https://juejin.cn/post/7218068880223682620

相关推荐
考虑考虑3 小时前
JDK25模块导入声明
java·后端·java ee
_小马快跑_5 小时前
Java 的 8 大基本数据类型:为何是不可或缺的设计?
java
Re_zero7 小时前
线上日志被清空?这段仅10行的 IO 代码里竟然藏着3个毒瘤
java·后端
洋洋技术笔记7 小时前
Spring Boot条件注解详解
java·spring boot
程序员清风1 天前
程序员兼职必看:靠谱软件外包平台挑选指南与避坑清单!
java·后端·面试
皮皮林5511 天前
利用闲置 Mac 从零部署 OpenClaw 教程 !
java
华仔啊1 天前
挖到了 1 个 Java 小特性:var,用完就回不去了
java·后端
SimonKing1 天前
SpringBoot整合秘笈:让Mybatis用上Calcite,实现统一SQL查询
java·后端·程序员
日月云棠2 天前
各版本JDK对比:JDK 25 特性详解
java
用户8307196840822 天前
Spring Boot 项目中日期处理的最佳实践
java·spring boot