「最强」Lettuce 已支持 Redis6 客户端缓存
时间:2022-07-23
本文章向大家介绍「最强」Lettuce 已支持 Redis6 客户端缓存
,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
Redis 客户端缓存
缓存的解决方案一般有两种:
【L1】 内存缓存(如 Caffeine、Ehcache) —— 速度快,进程内可用,但重启缓存丢失,出现缓存雪崩的问题。
【L2】集中式缓存(如 Redis)—— 可同时为多节点提供服务,但高并发下,带宽成为瓶颈。
业内有很多开源框架来解决以上问题,既能有 L1 速度,并且拥有 L2 集群态。如下
在 redis 6.0 版本中,已经默认支持了客户端缓存功能,Java 中主流的连接客户端 lettuce 在最新的快照版本 (6.0.0.BUILD-SNAPSHOT) 已经提供支持。 下边就通过代码来体验一下客户端缓存的神奇功能。
Redis 6.0 安装
安装 redis 6
,这里通过 Docker 安装命令如下
docker run --name redis6 -p 6379:6379 --restart=always -d redis:6.0.6
Jar 依赖
注意: 这里使用 lettuce 客户端,注意当前使用 6.0 的快照版本 ,需要在 pom 增加 lettuce 快照仓库
- 1.lettuce 6.0 快照依赖
<dependency>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
<version>6.0.0.BUILD-SNAPSHOT</version>
</dependency>
-
- 配置快照仓库
<repositories>
<repository>
<id>sonatype-snapshots</id>
<name>Sonatype Snapshot Repository</name>
<url>https://oss.sonatype.org/content/repositories/snapshots/</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
代码操作
- 使用 lettuce 连接 redis ,并循环查看 k1 的值
// <1> 创建单机连接的连接信息
RedisURI redisUri = RedisURI.builder() //
.withHost("127.0.0.1")
.withPort(6379)
.build();
RedisClient redisClient = RedisClient.create(redisUri);
StatefulRedisConnection<String, String> otherParty = redisClient.connect();
RedisCommands<String, String> commands = otherParty.sync();
StatefulRedisConnection<String, String> connection = redisClient.connect();
// <2> 创建缓存访问器
Map<String, String> clientCache = new ConcurrentHashMap<>(); //map 自动保存所有操作key的 key=value
CacheFrontend<String, String> frontend = ClientSideCaching.enable(CacheAccessor.forMap(clientCache), connection,
TrackingArgs.Builder.enabled());
// <3> 客户端正常写入测试数据 k1 v1
String key = "k1";
commands.set(key, "v1");
// <4> 循环读取
while (true) {
// <4.1> 缓存访问器中的值,查看是否和 Redis 服务端同步
String cachedValue = frontend.get(key);
System.out.println("当前 k1 的值为:--->" + cachedValue);
Thread.sleep(3000);
}
- redis-cli 客户端同时操作 k1 修改 k1 的值
./redis-cli -h 127.0.0.1 -p 6379
> set k1 v2
- 注意查看 控制台日志
...
当前 k1 的值为:--->v1
当前 k1 的值为:--->v1
当前 k1 的值为:--->v1
当前 k1 的值为:--->v2
当前 k1 的值为:--->v2
当前 k1 的值为:--->v2
....
如上: k1 的值在其他客户端(redis-cli)修改,lettuce 客户端确实感知到了数据变化。 但 lettuce 到底 CacheFrontend.get
到底有没有查询 redis 呢?
我们可以通过以下监控看下客户端具体的操作细节
监控
./redis-cli -h 127.0.0.1 -p 6379
> MONITOR
OK
1595922453.165088 [0 172.16.1.96:57482] "SET" "k1" "v1" # 对应 <3> 写入测试数据
1595922453.168238 [0 172.16.1.96:57483] "GET" "k1" # <4.1> 缓存访问器中的值,由于第一次查询为空需要穿透去查询 redis-server
1595922466.525942 [0 172.16.1.96:57498] "COMMAND" # 其他客户端 redis-cli 接入 提醒
1595922472.046488 [0 172.16.1.96:57498] "set" "k1" "v2" # 其他客户端 操作 k1
1595922474.208214 [0 172.16.1.96:57483] "GET" "k1" # 由于k1 值发生变化,循环 <4.1> 会重新查询redis-server
如上: 虽然是个死循环,但是关于 redis 操作只有以上注释的几条,说明客户端缓存生效。
总结
- 当前仅有 lettuce 支持此功能,jedis 还未支持
- spring-boot-data-redis 暂未支持此功能,估计需要 spring boot 2.5 版本
- 配置dg broker的问题分析及修复(r6笔记第84天)
- SDP(5):ScalikeJDBC- JDBC-Engine:Streaming
- SDP(4):ScalikeJDBC- JDBC-Engine:Updating
- SDP(3):ScalikeJDBC- JDBC-Engine:Fetching
- SDP(2):ScalikeJDBC-Connection Pool Configuration
- 使用外部表关联MySQL数据到Oracle(r6笔记第100天)
- 使用selenium模块模拟浏览器爬去网页,并进行点击定位内容笔记
- python 报错'gbk' codec can't encode character 'ue5d1' in position 0:
- python文件打开方式详解——a、a+、r+、w+区别
- 三封报警邮件的分析(r6笔记第95天)
- HCTF2017 部分 Web 出题思路详解
- 基于springboot+kotlin+gradle构建的框架的坑
- 创建Task的多种方法
- 运行map()后,报:<map object at 0x02629E50>解决方法与原因分析
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 一看就懂的Tensorflow实战(模型的保存与读取)
- 知识卡片 文本分词
- 一看就懂的Tensorflow实战(TensorBoard基础篇)
- 一看就懂的Tensorflow实战(TensorBoard高级篇)
- 一看就懂的Tensorflow实战(LSTM)
- 给我半首歌的时间,给你说明白Immutable List
- 一看就懂的Tensorflow实战(GAN)
- 一看就懂的Tensorflow实战(DCGAN)
- VBA解压缩ZIP文件08——解压-没有压缩
- 一文教你搞懂C语言的Q格式
- 基础算法之排序算法
- C++核心准则E4,5:设计并构建不变量
- Selenium实际应用注入并执行Javascript语句
- 什么是Python的 “内存管理机制”
- 2020年手工webpack构建react项目,完美支持ssr,包括css和图片资源