jedis客户端报Too many Cluster redirections异常?很困扰?不知道是什么问题?请看如下文章,为你一一解答。java
请求间歇性穿透缓存。redis
redis.clients.jedis.exceptions.JedisClusterMaxRedirectionsException: Too many Cluster redirections? at redis.clients.jedis.JedisClusterCommand.runWithRetries(JedisClusterCommand.java:34) at redis.clients.jedis.JedisClusterCommand.runWithRetries(JedisClusterCommand.java:85) at redis.clients.jedis.JedisClusterCommand.runWithRetries(JedisClusterCommand.java:68) at redis.clients.jedis.JedisClusterCommand.runWithRetries(JedisClusterCommand.java:85) at redis.clients.jedis.JedisClusterCommand.runWithRetries(JedisClusterCommand.java:68) at redis.clients.jedis.JedisClusterCommand.runWithRetries(JedisClusterCommand.java:85) at redis.clients.jedis.JedisClusterCommand.runWithRetries(JedisClusterCommand.java:68) at redis.clients.jedis.JedisClusterCommand.run(JedisClusterCommand.java:29) at redis.clients.jedis.JedisCluster.set(JedisCluster.java:75)
经过分析如下代码得知错误缘由:缓存
private T runWithRetries(byte[] key, int redirections, boolean tryRandomNode, boolean asking) { if (redirections <= 0) { throw new JedisClusterMaxRedirectionsException("Too many Cluster redirections?"); } Jedis connection = null; try { if (asking) { // TODO: Pipeline asking with the original command to make it // faster.... connection = askConnection.get(); connection.asking(); // if asking success, reset asking flag asking = false; } else { if (tryRandomNode) { connection = connectionHandler.getConnection(); } else { connection = connectionHandler.getConnectionFromSlot(JedisClusterCRC16.getSlot(key)); } } return execute(connection); } catch (JedisConnectionException jce) { if (tryRandomNode) { // maybe all connection is down throw jce; } // release current connection before recursion releaseConnection(connection); connection = null; // retry with random connection return runWithRetries(key, redirections - 1, true, asking); } catch (JedisRedirectionException jre) { // if MOVED redirection occurred, if (jre instanceof JedisMovedDataException) { // it rebuilds cluster's slot cache // recommended by Redis cluster specification this.connectionHandler.renewSlotCache(connection); } // release current connection before recursion or renewing releaseConnection(connection); connection = null; if (jre instanceof JedisAskDataException) { asking = true; askConnection.set(this.connectionHandler.getConnectionFromNode(jre.getTargetNode())); } else if (jre instanceof JedisMovedDataException) { } else { throw new JedisClusterException(jre); } return runWithRetries(key, redirections - 1, false, asking); } finally { releaseConnection(connection); } }
当发生JedisConnectionException或者JedisRedirectionException时,会从新调用当前方法。网络
与该错误关系不大。dom
由于该错误是:链接Redis错误,若是链接第一个节点失败,尝试第二个节点也失败,会直接推断成所有节点down掉抛出错误,中断处理。ui
和该错误关系很大。this
对该错误处理时,并处理了如下两个异常:
JedisMovedDataException:节点重置/迁移后,会抛出该异常
JedisAskDataException: 数据迁移,发生asking问题, 获取asking的Jediscode
今后推断,发生该问题的缘由为:ip
所以,致使该错误的缘由可为:ci