Redis6.0中的新特性 客户端缓存 client-side caching ,通过telnet连接模拟客户端,测试了三种客户端缓存的工作模式,这篇文章我们就来点硬核实战,看看客户端缓存在java项目中应该如何落地。
铺垫
首先介绍一下今天要使用到的工具 Lettuce
,它是一个可伸缩线程安全的redis客户端。多个线程可以共享同一个 RedisConnection
,利用nio框架 Netty
来高效地管理多个连接。
放眼望向现在常用的redis客户端开发工具包,虽然能用的不少,但是目前率先拥抱redis6.0,支持客户端缓存功能的却不多,而lettuce就是其中的领跑者。
我们先在项目中引入最新版本的依赖,下面正式开始实战环节:
<dependency> <groupId>io.lettuce</groupId> <artifactId>lettuce-core</artifactId> <version>6.1.8.RELEASE</version> </dependency>
实战
在项目中应用lettuce,开启并使用客户端缓存功能,只需要下面这一段代码:
public static void main(String[] args) throws InterruptedException { // 创建 RedisClient 连接信息 RedisURI redisURI= RedisURI.builder() .withHost("127.0.0.1") .withPort(6379) .build(); RedisClient client = RedisClient.create(redisURI); StatefulRedisConnection<String, String> connect = client.connect(); Map<String, String> map = new HashMap<>(); CacheFrontend<String,String> frontend=ClientSideCaching.enable(CacheAccessor.forMap(map), connect, TrackingArgs.Builder.enabled().noloop()); String key="user"; while (true){ String value = frontend.get(key); System.out.println(value); TimeUnit.SECONDS.sleep(10); } }
上面的代码主要完成了几项工作:
- 通过
RedisURI
配置redis连接的标准信息,并建立连接 - 创建用于充当本地缓存的
Map
,开启客户端缓存功能,建立一个缓存访问器CacheFrontend
- 在循环中使用
CacheFrontend
,不断查询同一个key对应的值并打印
启动上面的程序,控制台会不断的打印 user
对应的缓存,在启动一段时间后,我们在其他的客户端修改 user
对应的值,运行的结果如下:
可以看到,在其他客户端修改了key所对应的值后,打印结果也发生了变化。但是到这里,我们也不知道 lettuce
是不是真的使用了客户端缓存,虽然结果正确,但是说不定是它每次都重新执行了 get
命令呢?
所以我们下面来看看源码,分析一下具体的代码执行流程。
分析
在上面的代码中,最关键的类就是 CacheFrontend
了,我们再来仔细看一下上面具体实例化时的语句:
CacheFrontend<String,String> frontend=ClientSideCaching.enable( CacheAccessor.forMap(map), connect, TrackingArgs.Builder.enabled().noloop(