redis实战第十五篇 redis cluster的批处理中ask重定向解决方案
时间:2022-07-23
本文章向大家介绍redis实战第十五篇 redis cluster的批处理中ask重定向解决方案,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
ask重定向现象请参考【传送门】
分别使用mget和pipline做批处理 1.使用mget批量获取,如果存在重定向问题,会抛出异常。
@Test
public void testMget(){
JedisCluster jedis = RedisClusterUtil.getJedis();
List<String> results = null;
results = jedis.mget("user:{info}:id","user:{info}:age");
for(String res:results){
System.out.println(res);
}
results = jedis.mget("user:{info}:id","user:{info}:age","user:{info}:name","user:{info}:email");
for(String res:results){
System.out.println(res);
}
}
返回结果如下所示,第一次mget执行成功,是因为两个键都迁移完成,第二次获取失败是因为存在ask重定向问题。
232132
20
redis.clients.jedis.exceptions.JedisDataException: TRYAGAIN Multiple keys request during rehashing of slot
2.使用pipline做批量处理
@Test
public void testPiplione(){
//创建JedisCluster时,节点地址可以只填写部分,集群内部可以通过cluster nodes获取所有节点信息
JedisSlotBasedConnectionHandler connectionHandler = new JedisCluster(new HostAndPort("192.168.0.31",6380),1000,1000,5,"1234@abcd",new JedisPoolConfig()){
public JedisSlotBasedConnectionHandler getConnectionHandler() {
return (JedisSlotBasedConnectionHandler) super.connectionHandler;
}
}.getConnectionHandler();
List<String> keys = Arrays.asList("user:{info}:id","user:{info}:age","user:{info}:name","user:{info}:email");
Jedis jedis = connectionHandler.getConnectionFromSlot(JedisClusterCRC16.getSlot(keys.get(3)));
try {
Pipeline pipelined = jedis.pipelined();
for (String key : keys) {
pipelined.get(key);
}
List<Object> results = pipelined.syncAndReturnAll();
for (Object result : results) {
System.out.println(result);
}
} finally {
jedis.close();
}
}
批处理结果如下,当存在重定向问题时,pipline不会抛出异常,而是直接返回异常对象,并且成功迁移的键能获取到值。
redis.clients.jedis.exceptions.JedisAskDataException: ASK 5642 192.168.0.33:6380
redis.clients.jedis.exceptions.JedisAskDataException: ASK 5642 192.168.0.33:6380
peter
132132@163.com
基于异常结果对象,可以获取到对应的重定向节点信息,根据获取到的节点信息获取连接再次发送请求。
@Test
public void testPiplione2(){
JedisSlotBasedConnectionHandler connectionHandler = new JedisCluster(new HostAndPort("192.168.0.31",6380),1000,1000,5,"1234@abcd",new JedisPoolConfig()){
public JedisSlotBasedConnectionHandler getConnectionHandler() {
return (JedisSlotBasedConnectionHandler) super.connectionHandler;
}
}.getConnectionHandler();
List<String> keys = Arrays.asList("user:{info}:id","user:{info}:age","user:{info}:name","user:{info}:email");
Jedis jedis = connectionHandler.getConnectionFromSlot(JedisClusterCRC16.getSlot(keys.get(3)));
try {
Pipeline pipelined = jedis.pipelined();
for (String key : keys) {
pipelined.get(key);
}
List<Object> results = pipelined.syncAndReturnAll();
for (int i =0 ; i<keys.size() ; i++) {
// 键顺序和结果顺序,Pipeline严格按照键发送的顺序返回结果,即使出现异常也是如此
Object result = results.get(i);
//判断是否是异常结果对象
if (result != null && result instanceof JedisAskDataException) {
JedisAskDataException askException = (JedisAskDataException) result;
//根据异常结果对象获取节点信息
HostAndPort targetNode = askException.getTargetNode();
//根据节点信息获取jedis连接
Jedis targetJedis = connectionHandler.getConnectionFromNode(targetNode);
try {
// 执行asking
targetJedis.asking();
// 获取key并执行
String key = keys.get(i);
String targetResult = targetJedis.get(key);
System.out.println(targetResult);
} finally {
targetJedis.close();
}
} else {
System.out.println(result);
}
}
}finally {
jedis.close();
}
}
以下是执行结果,可以看出pipline可以根据返回的异常结果对象,获取ask重定向节点信息,发送ask请求,获取返回结果,这点和mget不一样,mget出现ask重定向问题时会直接抛出异常。
232132
20
peter
132132@163.com
集群环境下的批量操作场景,建议优先选择pipline,这样不仅可以处理slot迁移过程的ask重定向问题,还可以提高redis的IO效率。
- TechEmpower 13轮测试中的ASP.NET Core性能测试
- 反馈型神经网络
- (Head First 设计模式)学习笔记(1)
- [c#]Webservice中如何实现方法重载(overload)以及如何传送不能序列化的对象作参数
- Web.Config文件配置小记
- [原创]web application中使用Profile应该注意的问题
- MRTG FOR WINDOWS 安装指南
- 几种常见复合sql查询语句的linq写法[继续补充中]
- [原创]在msmq3.0中使用http协议发送消息
- 微信小程序开发探索之路
- 前端周记 2017 年终总结
- asp.net mvc中的路径选择
- MVC中实现加载更多
- 在ASP.NET MVC 中获取当前URL、controller、action
- 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 数组属性和方法
- 记录一些小技巧-JS篇
- 初次在Vue项目使用TypeScript,需要做什么
- VScode - 10个提高工作效率的快捷键
- Vue - 自定义组件双向绑定
- 解决 [Element Warn][Form]model is required for validate to work!
- 编写TypeScript工具类型,你需要知道的知识
- 微信小程序8种数据通信的方式
- 前端手写代码原理实现
- JavaScript 进制转换&位运算,了解一下?
- 10个实用的工具函数
- 小程序scroll-view点击项自动居中
- 维护你的请求队列,处理token异常
- 小程序数据埋点实践之曝光量
- Notification API,为你的网页添加桌面通知推送
- 点亮你的Vue技术栈,万字Nuxt.js实践笔记来了