文档章节

JedisRedirectionException:Too many Cluster redirections

黑_麦
 黑_麦
发布于 2017/06/05 15:35
字数 1252
阅读 109
收藏 0
点赞 0
评论 0

最近用Jedis作为redis客户端,经常碰到这个问题,程序刚启动,没几秒钟,就出现这个问题:

redis.clients.jedis.exceptions.JedisClusterMaxRedirectionsException: Too many Cluster redirections?
at redis.clients.jedis.JedisClusterCommand.runWithRetries(JedisClusterCommand.java:38)
at redis.clients.jedis.JedisClusterCommand.runWithRetries(JedisClusterCommand.java:86)
at redis.clients.jedis.JedisClusterCommand.runWithRetries(JedisClusterCommand.java:71)
at redis.clients.jedis.JedisClusterCommand.runWithRetries(JedisClusterCommand.java:86)
at redis.clients.jedis.JedisClusterCommand.runWithRetries(JedisClusterCommand.java:71)
at redis.clients.jedis.JedisClusterCommand.runWithRetries(JedisClusterCommand.java:86)
at redis.clients.jedis.JedisClusterCommand.runWithRetries(JedisClusterCommand.java:71)
at redis.clients.jedis.JedisClusterCommand.runWithRetries(JedisClusterCommand.java:86)
at redis.clients.jedis.JedisClusterCommand.runWithRetries(JedisClusterCommand.java:71)
at redis.clients.jedis.JedisClusterCommand.runWithRetries(JedisClusterCommand.java:86)
at redis.clients.jedis.JedisClusterCommand.runWithRetries(JedisClusterCommand.java:71)
at redis.clients.jedis.JedisClusterCommand.run(JedisClusterCommand.java:32)
at redis.clients.jedis.JedisCluster.hsetnx(JedisCluster.java:325)

一开始怀疑redis集群没搭好,网络不稳定,程序写的不好导致,排查了很长时间,最后还是从错误log去排查,为什么会runWithRetries,为什么会有Too many Cluster redirections,下面从我们自身程序、JedisCluster源码说起,到如何解决这个问题,以及一些Jedis不足的地方。

1. 我们系统用jstorm+redis集群对数据进行处理,并导出统计结果。Spout每分钟要分发100万条记录给下游的CalculateBolt(50个Task,在不同的节点上运行),CalculateBolt对每条记录进行处理,与redis现有数据比对,更新计数器等等。最后由OutputBolt导出统计结果。在每个CalculateBolt中都有一个JedisCluster全局变量(private JedisCluster jedisCluster),并在prepare方法中初始化,在execute方法中处理记录。

2. 我们new一个JedisCluster时,JedisCluster会根据我们传进去的ip跟port建立一个JedisPool实例(JedisPool对应着redis集群的一个节点,假设这个ip跟port对应着Node5),并从这个JedisPool实例中得到一个jedis实例,然后这个jedis实例执行cluster nodes命令,最后我们就知道整个集群的节点情况,包括每个节点的ip跟port,每个节点负责处理的slot(槽位),JedisCluster会缓存这些信息到node pools(Map<String,JedisPool>),slots(Map<Integer,JedisPool>)。

注意:这里已经建立了所有节点对应的JedisPool实例,但这个JedisPool池里面暂时还没有Jedis实例(除了我们指定ip和prot的那个JedisPool里有一个Jedis实例)。

3. 当我们要处理一个key时,正常情况下,根据CRC16得到slot,然后根据这个slot从slots映射中得到对应的JedisPool,然后从这个Pool中得到Jedis(new Socket对象,设置KeepAlive,TcpNoDelay等参数,建立连接,设置read超时时间等),然后操作redis命令。但建立连接时,是有时间期限的,2秒钟,如果2秒钟内没有建立,返回JedisConnectionException异常,我们捕获异常,然后重试。这里的重试就是redirect retry了,重试的流程是不一样的,重试时会Collections.shuffle(pools),这里的pools就是上面的node pools,这时的pools已经乱序了,建立连接,然后访问,然后redis会返回move data指令,告知去哪个正确的节点上执行命令,然后jedis会更新slot到JedisPool的映射关系(我们会操作redis集群,进行线性扩展,槽位可能改变),这样就完成一次redirect了。然后jedis从新开始,试图得到connection,又超时,又redirect,5次一样,抛出一开始所说的异常。

4. redis为什么会连不上,我们知道redis是单线程的,你可以想象当有很多client试图连接redis服务器时,他们排队(其实不是)等待连接,回到我们的程序,当有一个CalculateBolt要连到Node1节点时,这时由于我们处理的数据的不均衡性,很有可能所有其他的CalculateBolt都在这个Node1节点上排队,再加上网络的延迟等等因素,超时了,下次redirect后,还是超时,好,异常抛出。

5. 我们知道异常抛出的原因后,其实我们有很多fix方法的,如建立JedisPool时,先实例化一个到redis节点的jedis实例(jedis实例里有socket连接),但现在只有我们指定ip跟port的那个JedisPool有一个jedis实例,其他的是没有的,要在第一次访问时建立。当然最简单的当然是增大超时时间了,但变态的是,这个超时时间在jedis里竟然是硬编码,Protocol.DEFAULT_TIMEOUT,你要改,下载源码,修改,重新编译打包,我不清楚为什么这个是硬编码,也许jedis作者认为2s已经是很长的时间了,不可能连接超时了。

6. 我是用上面第二点,增大超时时间,幸好有github,幸好有maven,改起来也算快速。但也算是Jedis需要改进的地方了。Jedis还需要改进的是它的异常捕获,很垃圾。举个例子,上面的异常中的71行其实是JedisConnectionException异常,但这个异常的栈信息却丢失了,其实我们知道最先抛出的应该是一个SocketTimeoutException,但这个RuntimeException在外面的上上层方法中,被捕获了,catch(Exception e),然后重新抛出了一个JedisConnectionException,但这个异常信息里却没有原先的异常栈信息,导致异常信息丢失。

© 著作权归作者所有

共有 人打赏支持
黑_麦
粉丝 0
博文 5
码字总数 315
作品 0
昌平
程序员
Redis 3.0.7 和 3.2.0 rc2 发布

Redis 3.0.7 和 3.2.0 rc2 发布,3.2.0 rc2 更新如下: --[ Redis 3.2.0 RC2 (version 3.1.102) ] Release date: 25 jan 2016 Upgrade urgency MODERATE: this release fixes important Red......

oschina ⋅ 2016/01/26 ⋅ 4

jedis 2.7集群异常

在使用jedis2.7测试redis集群的时候出现异常: Exception in thread "main" redis.clients.jedis.exceptions.JedisClusterMaxRedirectionsException: Too many Cluster redirections? at red......

小心有诈 ⋅ 2015/04/08 ⋅ 1

美团在Redis上踩过的一些坑-5.redis cluster遇到的一些问题

转载请注明出处哈:http://carlosfu.iteye.com/blog/2254154 由于演讲时间有限,有关Redis-Cluster,演讲者没做太多介绍,简单的介绍了一些Redis-Cluster概念作用和遇到的两个问题,我们在Red...

lirulei90 ⋅ 01/05 ⋅ 0

搭建redis-cluster环境

前提:之前因为redis-cluster没有php客户端+小白鼠,所以直接一票否决,当前情况下使用的redis高可用是通过哨兵+脚本vip切换,但目前redis支持了php客户端,我准备测试下redis cluster. 参考...

tiger2013 ⋅ 2016/03/04 ⋅ 0

PUMA 2.15.0 发布,Ruby 的 Web 服务器

PUMA 2.15.0 发布,最新版本是 PUMA 2.15.3。 PUMA 2.15.3 主要修复 JRuby 解析器相关的问题。 PUMA 2.15.0,PUMA 2.15.1 和 PUMA 2.15.2 版本更新内容如下: === 2.15.2 / 2015-11-06 2 个 ...

oschina ⋅ 2015/11/10 ⋅ 4

S3QL 1.9 发布,在线数据存储系统

S3QL 1.9 发布,该版本修复了当修改系统时区设置导致文件时间被更改的问题,修复了改进了 contrib/benchmark.p ,修复了 "Too many chained redirections" bug,当碰到 5xx 服务器错误进行重...

红薯 ⋅ 2012/01/22 ⋅ 0

Redis 集群常见错误和处理方法收集(持续更新)

1、Too many redirections 解决: 1)查看创建集群时,不要使用127.0.01这种地址,使用实际地址。 2)new JedisCluster(jedisClusterNodes(jedisClusterNodes, timeout, maxredirection)时,...

go2school ⋅ 2016/03/24 ⋅ 0

Redis集群的使用测试(Jedis客户端的使用)

Redis集群的使用测试(Jedis客户端的使用) 1、 Jedis客户端建议升级到最新版(当前为2.7.3),这样对3.0.x集群有比较好的支持。 https://github.com/xetorthio/jedis http://mvnrepository....

1362802538 ⋅ 2016/12/01 ⋅ 0

Cherokee 1.0.15 发布重要更新,建议升级

Cherokee 号称是目前最快的 Web 服务器软件,在性能上,甚至比 Nginx 还略胜一筹。与 Apache、Lighttpd、Nginx 等其他同类软件的对比,大家不妨看看这个测试页面。其易用性做得也很不错。 Ch...

红薯 ⋅ 2010/12/30 ⋅ 0

LFTP 4.6.2 发布,命令行 FTP 工具

LFTP 4.6.2 发布,新增特征如下: new command "edit" instead of the edit alias. new setting ssl:priority for disabling selected protocols. new settings fish:auto-confirm and sftp......

oschina ⋅ 2015/04/17 ⋅ 3

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Java的Excel导出工具类

首先在POM中引入需要的Jar <dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.47</version></dependency><dependency><groupId>o......

Kxvz ⋅ 3分钟前 ⋅ 0

Java 3DES加密解密

import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.codec.binary.Base64; //算法代码[java] view plain copy /** * 转换成十六进制字......

说回答 ⋅ 10分钟前 ⋅ 0

php 浮点型计算精度问题

今天碰到一个金额计算的问题,浮点数做差,结果有误(精度有问题)。 $a = floatval('6');$b = floatval('4.99');$m = floatval('1');$r = $a - $b;$r = $r - $m;var_dump($r);//f...

stupidboy ⋅ 32分钟前 ⋅ 0

Mahout推荐算法之SlopOne

一、 算法原理 有别于基于用户的协同过滤和基于item的协同过滤,SlopeOne采用简单的线性模型估计用户对item的评分。如下图,估计UserB对ItemJ的偏好 图(1) 在真实情况下,该方法有如下几个...

xiaomin0322 ⋅ 37分钟前 ⋅ 0

LVM讲解

LVM是什么 LVM是 Logical Volume Manager(逻辑卷管理)的简写,它是Linux环境下对磁盘分区进行管理的一种机制,Linux用户安装Linux操作系统时遇到的一个常见的难以决定的问题就是如何正确地...

李超小牛子 ⋅ 46分钟前 ⋅ 0

mysql更改密码、连接mysql、mysql常用命令

1. 更改mysql的root账户密码: mysql中root账户和系统root不是一个账户 1.1 更改环境变量PATH,增加mysql绝对路径 由于mysql安装目录为/usr/local/mysql/,所以系统不能直接使用mysql,需把/...

laoba ⋅ 47分钟前 ⋅ 0

阿里云发布企业数字化及上云外包平台服务:阿里云众包平台

摘要: 阿里云正式发布旗下众包平台业务(网址:https://zhongbao.aliyun.com/),支持包括:网站定制开发,APP、电商系统等软件开发,商标、商品LOGO、VI、产品包装设计、营销推广、大数据人...

猫耳m ⋅ 47分钟前 ⋅ 0

阿里云发布企业数字化及上云外包平台服务:阿里云众包平台

摘要: 阿里云正式发布旗下众包平台业务(网址:https://zhongbao.aliyun.com/),支持包括:网站定制开发,APP、电商系统等软件开发,商标、商品LOGO、VI、产品包装设计、营销推广、大数据人...

阿里云云栖社区 ⋅ 51分钟前 ⋅ 0

1.03-Maven中使用ueditor富文本编辑器

起因:在maven仓库未找到百度的ueditor的jar包 操作: 1.下载百度的ueditor的jar包 2.打开命令行,切换到ueditor的下载位置,运行一下命令: mvn install:install-file -Dfile=ueditor-1.1....

静以修身2025 ⋅ 56分钟前 ⋅ 0

几道Spring 面试题

1、BeanFactory 接口和 ApplicationContext 接口有什么区别? ApplicationContext 接口继承BeanFactory接口 Spring核心工厂是BeanFactory BeanFactory采取延迟加载,第一次getBean时才会初始...

职业搬砖20年 ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部