Redisson批量操作类RBuckets和管道利器RBatch
- 《Spring Boot 整合Redisson配置篇》
- 《Spring Boot 整合Redisson操作Redis基础篇》
- 《Redisson批量操作类RBuckets和管道利器RBatch》
摘要:使用Redisson的类RBuckets和RBatch批量操作Redis,减少网络请求次数。
综述
Redis的部署方式有单节点部署、哨兵方式部署、集群方式部署3种方式,这3中方式都使用的是原生的redis。本文基于单节点部署,使用的Spring Boot版本为2.5.x。
RBuckets批量操作
在Spring Boot项目中,通过RBuckets接口实现批量操作多个RBucket对象,官方示例如下:
RBuckets buckets = redisson.getBuckets();
Map<String, V> loadedBuckets = buckets.get("myBucket1", "myBucket2", "myBucket3");
Map<String, Object> map = new HashMap<>();
map.put("myBucket1", new MyObject());
map.put("myBucket2", new MyObject());
// 利用Redis的事务特性,同时保存所有的通用对象桶,如果任意一个通用对象桶已经存在则放弃保存其他所有数据。
buckets.trySet(map);
// 同时保存全部通用对象桶。
buckets.set(map);
方法介绍:
- Map<String,V> get(String... keys):返回桶的key-value对。
- boolean trySet(Map<String,?> buckets):利用Redis的事务特性,同时保存所有的通用对象桶,如果任意一个通用对象桶已经存在则放弃保存其他所有数据。
- void set(Map<String,?> buckets):同时保存全部通用对象桶。
RBatch 批量操作
多个连续命令可以通过RBatch对象在一次网络会话请求里合并发送,这样省去了产生多个请求消耗的时间和资源。这在Redis中叫做管道。
RBatch管道功能就是REDIS的批量发送,实际上是客户端的功能,与服务端无关。相当于把多个请求的命令放在一个数据包通过TCP发送到服务端,然后客户端再一次性读取所有的命令回应。管道技术最显著的优势是提高了 redis 服务的性能。
/**
* 批量操作
*/
private void batchDemo() throws ExecutionException, InterruptedException {
Map<String, String> map = new HashMap<>();
map.put("abc", "testStr");
map.put("abcDemo", "redis");
redisUtils.setMassStrings(map);
log.info("String 测试数据:{}", redisUtils.getStr("abc") + " "
+ redisUtils.getStr("abcDemo"));
RBatch batch = redisUtils.createBatch();
// 模拟购物车场景,真实场景中请替换店铺ID shopId 和商品ID commodityId
String field = "shopId:commodityId";
// 把即将执⾏的命令放进 RBatch
RMapAsync testMap = batch.getMap("customerId:"+ 32L);
// 更新value,并返回上一次的值
String commodityNum = "mapValue" + String.valueOf((int)(Math.random()*9 + 100));
log.info("当前商品数量commodityNum是:{}", commodityNum);
testMap.putAsync(field, commodityNum);
testMap.putAsync("test2", "mapValue3");
testMap.putAsync("test2", "mapValue5");
testMap.putAsync("test:"+ String.valueOf((int)(Math.random()*900 + 100)), String.valueOf((int)(Math.random()*900 + 100)));
RAtomicLongAsync counter = batch.getAtomicLong("counter");
RFuture<Long> num = counter.incrementAndGetAsync();
// 执行RBatch中的全部命令,并返回执行结果
BatchResult result = batch.execute();
List list = result.getResponses();
log.info("Map Batch 执行结果:{}", list);
log.info("计数器当前值:{}", num.get());
}
执行batchDemo()后,控制台打印结果如下:
StudyRedissonController - String 测试数据:testStr redis
StudyRedissonController - 当前商品数量commodityNum是:mapValue106
StudyRedissonController - Map Batch 执行结果:[mapValue101, mapValue5, mapValue3, null, 8]
StudyRedissonController - 计数器当前值:8
测试用例主要介绍了Hash,顺便介绍一下它的使用场景:
- 存储结构化的数据,比如 Java 中的对象。其实 Java 中的对象也可以用 string 进行存储,只需要将对象序列化成 json 字符串就可以,但是如果这个对象的某个属性更新比较频繁的话,那么每次就需要重新将整个对象序列化存储,这样消耗开销比较大。可如果用 hash 来存储对象的每个属性,那么每次只需要更新要更新的属性就可以。
- 购物车场景。以业务线+用户id作为key,以店铺编号+商品的id作为存储的field,以选购商品数量作为键值对的value,这样就构成了购物车的三个要素。
在集群模式下,所有的命令会按各个槽所在的节点,筛选分配到各个节点并同时发送。每个节点返回的结果将会汇总到最终的结果列表里。上述demo中用到的工具类如下:
@Component
public class RedisUtils {
private RedisUtils() {
}
/**
* 默认缓存时间
*/
private static final Long DEFAULT_EXPIRED = 32000L;
/**
* 自动装配redisson client对象
*/
@Resource
private RedissonClient redissonClient;
/**
* 获取getBuckets 对象
*
* @return RBuckets 对象
*/
public RBuckets getBuckets() {
return redissonClient.getBuckets();
}
/**
* 读取缓存中的字符串,永久有效
*
* @param key 缓存key
* @return 字符串
*/
public String getStr(String key) {
RBucket<String> bucket = redissonClient.getBucket(key);
return bucket.get();
}
// ---------------- 批量操作 ------------------------
/**
* 获取RBatch
*
* @return RBatch
*/
public RBatch createBatch() {
return redissonClient.createBatch();
}
/**
* 批量移除缓存
*
* @param keys key 对象
*/
public void deleteBatch(String... keys) {
if (null == keys) {
return;
}
this.getKeys().delete(keys);
}
/**
* 批量缓存字符串,缺点:不可以设置过期时间
*
* @param map 缓存key-value
*/
public void setMassStrings(Map<String, String> map) {
if (MapUtils.isEmpty(map)) {
return;
}
RBuckets buckets = redissonClient.getBuckets();
// 同时保存全部通用对象桶。
buckets.set(map);
}
/**
* 批量缓存字符串,支持过期
*
* @param map 缓存key-value
* @param leaseTime 缓存有效期,必传
*/
public void setMassStrings(Map<String, String> map, long leaseTime) {
if (MapUtils.isEmpty(map)) {
return;
}
final long expireTime = leaseTime <= 0L ? DEFAULT_EXPIRED : leaseTime;
RBatch batch = redissonClient.createBatch();
map.forEach(new BiConsumer<String, String>() {
public void accept(String key, String value) {
batch.getBucket(key).setAsync(value, expireTime, TimeUnit.SECONDS);
}
});
batch.execute();
}
}
结束语
关于redisson中如何使用批量操作类RBuckets和管道利器RBatch就分享到这里,希望本文对大家的学习或者工作具有一定的参考和学习价值;如果有疑问,大家可以在评论区留言交流,也希望大家多多点赞关注。谢谢大家对楼兰胡杨的支持!
Reference
Redisson批量操作类RBuckets和管道利器RBatch的更多相关文章
- 模块(类)之间解耦利器:EventPublishSubscribeUtils 事件发布订阅工具类
如果熟悉C#语言的小伙伴们一般都会知道委托.事件的好处,只需在某个类中提前定义好公开的委托或事件(委托的特殊表现形式)变量,然后在其它类中就可以很随意的订阅该委托或事件,当委托或事件被触发执行时,会自 ...
- ASP.NET Web API 管道模型
ASP.NET Web API 管道模型 前言 ASP.NET Web API是一个独立的框架,也有着自己的一套消息处理管道,不管是在WebHost宿主环境还是在SelfHost宿主环境请求和响应都是 ...
- 在.NET中使用管道将输出流转换为输入流
最近在写一段代码,将本地文件压缩加密后发送到服务器,发送到服务器的类用一个输入流作为参数获取要上传的数据,而压缩类和加密类都是输出流. 如何将输出流转换为输入流,最直观的方法是缓存输出流的全部内容到内 ...
- 管道Pipe
管道Pipe java.nio.channels包中含有一个名为Pipe(管道)的类.广义上讲,管道就是一个用来在两个实体之间单向传输数据的导管.管道的概念对于Unix(和类Unix)操作系统的用户来 ...
- JAVA IO之管道流总结大全(转)
要在文本框中显示控制台输出,我们必须用某种方法“截取”控制台流.换句话说,我们要有一种高效地读取写入到System.out和 System.err 所有内容的方法.如果你熟悉Java的管道流Piped ...
- pipe管道
回顾: 进程间通信方式: 信号,管道 消息队列,共享内存,信号量 sokcet 信号: 本质就是软中断 signal(信号,函数指针); void func(int); kill(pid,signo) ...
- 【mongoDB查询进阶】聚合管道(二) -- 阶段操作符
https://segmentfault.com/a/1190000010826809 什么是管道操作符(Aggregation Pipeline Operators) mongoDB有4类操作符用于 ...
- java IO类简单介绍
一.流的概念 流是字节序列的抽象概念.流和文件的差别:文件是数据的静态存储形式,而流是指数据传输时的形态.文件只是流的操作对象之一.流按其操作的对象不同可以分为文件流.网络流.内存流.磁带流等.Jav ...
- springboot 整合redisson
整合代码已经过测试 1.pom <!-- redisson --> <dependency> <groupId>org.redisson</groupId&g ...
随机推荐
- c语言实现两数交换的三种方法
实现变量的值互相交换的三种不同方法 方法一:利用第三个变量来实现数值的交换 int tmp; tmp = a; a = b; b = tmp; 此方法直观,简易.不易出错,推荐使用 方法二:利用两个变 ...
- 玩转 React(四)- 创造一个新的 HTML 标签
在第二篇文章 <新型前端开发方式> 中有说到 React 有很爽的一点就是给我们一种创造 HTML 标签的能力,那么今天这篇文章就详细讲解下 React 是如何提供这种能力的,作为前端开发 ...
- chrome插件one-read开发1:准备
阅读我的博客文章:chrome插件one-read开发:准备 前言 为啥要做这个,因为我原本想用chrome做一个书签管理的东西,但是很久没有碰过chrome的插件开发了.所以先做一个简单的,来熟悉下 ...
- Web缓存总结
web缓存作用 减少网络带宽消耗降低服务器压力减少网络延迟,加快页面打开速度 Web缓存的类型 数据库数据缓存:为了提供查询的性能,会将查询后的数据放到内存中进行缓存,下次查询时,直接从内存缓存直接返 ...
- HTML5 Performance
简介 performance是html5的新特性之一,通过它,页面的开发者们可以非常精确的统计到自己页面的表现情况,从而有针对性的进行优化,提升用户体验. 下面是小姐姐对performance相关AP ...
- three.js 入门详解(一)
1. 概述 1.1 什么是WebGL? WebGL是在浏览器中实现三维效果的一套规范 想要使用WebGL原生的API来写3D效果的话,很吃力.three.js是WebGL的一个开源框架,它省去了很多麻 ...
- DRF 视图组件
目录 DRF 视图组件 视图组件大纲 两个视图基本类 五个扩展类 九个子类视图 视图集 常用视图集父类 魔法类 一览表 DRF中视图的"七十二变" 第一层:基于APIview的五个 ...
- Android CheckBox的监听事件
1.在xml文件中定义CheckBox,一定要定义id <CheckBox android:id="@+id/beijing" android:layout_width=&q ...
- formData请求接口传递参数格式
element ui组件方法的传递 //引入 组件. <el-upload class="avatar-uploader" :action="action" ...
- 《头号玩家》AI电影调研报告(二)
四. 涉及前沿技术及与现实的交互 1.VR技术 在影片中,斯皮尔伯格用他认为未来的VR虚拟技术为我们创造了众多精彩的画面,令人佩服其对科技的预见性.其中好多的装备特别引人注目,部分也在现实中存在:VR ...