缓存性能王者,阿里巴巴二级缓存JetCache框架

关注我的公众号:【编程朝花夕拾】,可获取首发内容。

01 引言

上一节介绍了本地缓存相关的使用以及坑点,本地缓存的使用往往带有局限性,用的更多的依然还是类似Redis这样的分布式缓存。

阿里巴巴出品的JetCache正是整合了本地缓存和分布式缓存,由框架自动管理本地缓存和远程缓存。提供了注解驱动的声明是缓存,同时也提供缓存的管理器CacheManage,可以随时手工接管缓存的使用。

我们一起来了解一下吧!

02 JetCache简介

JetCache 是一个 Java 缓存抽象框架,为不同缓存解决方案提供统一使用方式,其注解功能比 Spring Cache 更强大。它支持原生 TTL、两级缓存、分布式环境下自动刷新,还能通过代码操作缓存实例。

当前有 RedisCacheTairCache(未开源)、CaffeineCache LinkedHashMapCache 四种实现。其具备多种特性,如通过统一缓存 API 操作缓存、支持带 TTL 和两级缓存的注解式方法缓存、可创建及配置缓存实例、自动收集缓存访问统计信息、自定义键生成和值序列化策略、支持多种缓存键和值转换器、分布式缓存自动刷新和分布式锁、异步访问、更新后使本地缓存失效以及 Spring Boot支持等。

环境要求:

  • JDK1.8
  • Spring Framework4.0.8+ (optional, with annotation support),jetcache 2.7 need 5.2.4+
  • Spring Boot 1.1.9+ (optional), jetcache 2.7 need 2.2.5+

Github地址:github.com/alibaba/jet...

03 使用案例

3.1 Maven

案例基于Spring Boot 2.6.13

xml 复制代码
<dependency>
    <groupId>com.alicp.jetcache</groupId>
    <artifactId>jetcache-starter-redis</artifactId>
    <version>2.7.8</version>
</dependency>

<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>4.4.3</version>
</dependency>

jetcache-starter-redis默认使用的是Jedis客户端。因为jetcache-starter-redis 2.7.8Spring Boot 2.6.13有冲突,需要引入Jedis 4.x版本。

否则就是出现部分类找不到的现象:

3.2 配置文件

properties 复制代码
jetcache.statIntervalMinutes=15
jetcache.areaInCacheName=false
#还可以选caffeine
jetcache.local.default.type=linkedhashmap   
#还可以选fastjson/fastjson2
jetcache.local.default.keyConvertor=jackson  
jetcache.local.default.limit=100

jetcache.remote.default.type=redis
#还可以选fastjson/fastjson2
jetcache.remote.default.keyConvertor=jackson  
#还可以选kryo/kryo5
jetcache.remote.default.valueEncoder=java 
#还可以选kryo/kryo5
jetcache.remote.default.valueDecoder=java     
jetcache.remote.default.poolConfig.minIdle=5
jetcache.remote.default.poolConfig.maxIdle=20
jetcache.remote.default.poolConfig.maxTotal=50
# 集群配置
jetcache.remote.default.cluster[0]=127.0.0.1:7000
jetcache.remote.default.cluster[1]=127.0.0.1:7001
jetcache.remote.default.cluster[2]=127.0.0.1:7002

JetCache的配置并没有提示,所以配置的时候要注意,防止配错。

详细的配置说明:github.com/alibaba/jet...

启动类的注解

@EnableMethodCache(basePackages = "xx.xx.xx")

3.3 注解使用案例

注解可以加在接口上,也可以加在类上。案例以在类上使用为例。

常用注解:

  • @Cached
  • @CacheUpdate
  • @CacheInvalidate
  • @CacheRefresh

@Cached@CacheRefresh

java 复制代码
/**
 * @Description: 新增/刷新缓存
 *
 * @Author: ws
 * @Date: 2025/7/22 13:45
 **/
@Cached(expire = 3600, cacheType = CacheType.BOTH, name = "cache_key_", key = "#userId")
@CacheRefresh(refresh = 10)
@RequestMapping("test01")
public String test01(String userId) {
    System.out.println(LocalDateTime.now().format(FORMAT) + " userId=" + userId);
    return "test01" + Instant.now().toEpochMilli();
}

代码注意事项:

  • CacheType.BOTH表示同时使用本地缓存和远程缓存,这里可以指定任意一个缓存使用。
  • 属性中namekey的拼接组成Redis中的key
  • key使用的是EL表达式,通过#取属性的值
  • @CacheRefreshrefresh指每隔多长时间刷新一次缓存

缓存更新效果

再次请求缓存已经更新

@CacheUpdate

java 复制代码
/**
 * @Description: 更新缓存
 *
 * @Author: ws
 * @Date: 2025/7/22 13:45
 **/
@CacheUpdate(name = "cache_key_", key = "#userId", value = "#val")
@RequestMapping("test03")
public String test03(String userId, String val) {
    return "缓存更新成功!";
}

这里要说明的更新的value的值也是通过EL表达式从参数中获取的,无法指定方法中的数据作为缓存的结果

@CacheInvalidate

java 复制代码
/**
 * @Description: 更新缓存
 *
 * @Author: ws
 * @Date: 2025/7/22 13:45
 **/
@CacheInvalidate(name = "cache_key_", key = "#userId")
@RequestMapping("test04")
public String test04(String userId) {
    return "缓存失效!";
}

这里值得注意的是,这里的缓存失效,会将远程的缓存失效以及本机的缓存失效,其他节点的本地缓存并不能同步失效。

3.4 手动API接管

java 复制代码
@Autowired
CacheManager cacheManager;

@RequestMapping("test02")
public String test02(String userId) {
    Cache<String, String> cacheKey = cacheManager.getCache("cache_key_");
    if (cacheKey == null) {
        return  "cache_key_ 不存在";
    }
    if (cacheKey instanceof MultiLevelCache cache) {
        Cache[] caches = cache.caches();
        Arrays.stream(caches).forEach(item -> {
            if (item instanceof LinkedHashMapCache) {
                System.out.println("LinkedHashMapCache:" + item.get(userId));
            }else if (item instanceof RedisCache) {
                System.out.println("RedisCache:" + item.get(userId));
            }
        });
    }
    return cacheKey.get(userId);
}

效果

3.5 命中率统计

JetCache自带了统计功能,每隔一段时间就会输出统计数据。通过jetcache.statIntervalMinutes配置控制

04 关键注意事项

因为结合本地缓存和远程缓存,那么框架就存在这两者的优势和劣势。使用的时候也需要注意:

  • 缓存防止大Key的出现
  • 本地缓存需要增加容量限制
  • 结合TTL和主动失效
  • 多节点本地缓存不同步的问题
  • 使用时Spring BootJedisJetCache版本兼容问题

05 小结

通过合理利用JetCache的同步机制和缓存策略,可显著提升系统性能并保障数据一致性。建议结合具体业务场景进行参数调优,并持续监控缓存健康度。

使用任何一个框架,我们也要考虑可能带来的问题。线下发现不了,线上就会教会我们了。

相关推荐
IT_陈寒几秒前
Redis 性能翻倍的 5 个隐藏技巧,99% 的开发者都不知道第3点!
前端·人工智能·后端
JaguarJack1 分钟前
PHP 桌面端框架NativePHP for Desktop v2 发布!
后端·php·laravel
番茄Salad2 分钟前
自定义Spring Boot Starter项目并且在其他项目中通过pom引入使用
java·spring boot
程序员三明治14 分钟前
详解Redis锁误删、原子性难题及Redisson加锁底层原理、WatchDog续约机制
java·数据库·redis·分布式锁·redisson·watchdog·看门狗
自由的疯23 分钟前
Java 怎么学习Kubernetes
java·后端·架构
自由的疯24 分钟前
Java kubernetes
java·后端·架构
普通网友1 小时前
IZT#73193
java·php·程序优化
rechol1 小时前
C++ 继承笔记
java·c++·笔记
Han.miracle4 小时前
数据结构——二叉树的从前序与中序遍历序列构造二叉树
java·数据结构·学习·算法·leetcode
Le1Yu5 小时前
分布式事务以及Seata(XA、AT模式)
java