RedisCommandExecutionException: MOVED 9656 192.168.1.101:7002

RedisCommandExecutionException: MOVED 9656 192.168.1.101:7002

最近一个同事,在使用Redis集群进行操作的过程中,遇到如下错误
在这里插入图片描述
看这个错误信息,感觉挺奇怪。操作代码,使用Spring封装的RedisTemplate,而且操作内容并不复杂。将相关操作通过redis命令,在客服端执行
在这里插入图片描述
其实,看到这里,想必各位,已经知道异常出现的原因了。由于name和age两个key的槽位不同,在存储时,这两个key被映射到不同的节点,从而出现了上述异常。
下面介绍下Redis槽位信息

Redis集群内置16384个哈希槽,数据存储时,Redis首先对key使用crc16算法进行计算,将计算结果对16384取模,从而确定当前key对应于那个哈希槽。Redis正式通过哈希槽,来将数据大致均匀的映射到不同的节点。

在Redis中,可以通过cluster keyslot命令,查看key对应的槽位。
在这里插入图片描述
好了,到现在为止,知道了这个异常在Redis层面出现的原因。那么,这个原因出现的具体原因是什么呢?首先,让我们看一下其Redis配置
在这里插入图片描述
正式由于在这里使用单节点的配置方式,才导致上述异常信息。基于Redis集群,应当通过

spring.redis.cluster.nodes=192.168.1.101:7001,192.168.1.101:7002,192.168.1.101:7003

结论
1、Redis通过哈希槽,确保数据能够大致均匀的保存到各个节点。而哈希槽的确定,是对key进行crc16运算,然后进行16384求模得到。
2、redis配置时,若使用的是集群,需要使用spring.redis.cluster.nodes方式,进行配置。

  • 13
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
引用[1]中的错误信息"Caused by: io.lettuce.core.RedisCommandExecutionException: MOVED 15592 192.168.199.128:7002"表示在执行Redis命令时发生了MOVED错误。这个错误通常是由于Redis集群的重新分片或节点迁移引起的。当Redis集群中的某个键被移动到另一个节点时,客户端可能会收到MOVED错误作为响应。 要解决这个问题,你可以采取以下步骤: 1. 检查你的Redis集群配置,确保所有节点的配置正确,并且集群中的主节点和从节点都正常运行。 2. 检查你的应用程序代码,确保它正确处理MOVED错误。当你收到MOVED错误时,你的应用程序应该能够重新定位到正确的节点并重新发送命令。 3. 如果你使用的是Lettuce作为Redis客户端,你可以使用Lettuce提供的RedisClusterClient和RedisClusterCommands来处理MOVED错误。这些类库会自动处理MOVED错误,并将命令重新发送到正确的节点。 下面是一个使用Lettuce处理MOVED错误的示例代码: ```java import io.lettuce.core.RedisClient; import io.lettuce.core.RedisURI; import io.lettuce.core.cluster.RedisClusterClient; import io.lettuce.core.cluster.api.StatefulRedisClusterConnection; import io.lettuce.core.cluster.api.sync.RedisClusterCommands; public class RedisClusterExample { public static void main(String[] args) { RedisURI redisURI = RedisURI.create("redis://192.168.199.128:7002"); RedisClusterClient redisClusterClient = RedisClusterClient.create(redisURI); StatefulRedisClusterConnection<String, String> connection = redisClusterClient.connect(); RedisClusterCommands<String, String> commands = connection.sync(); String key = "your_key"; String value = "your_value"; try { commands.set(key, value); } catch (io.lettuce.core.RedisCommandExecutionException e) { if (e.getMessage().startsWith("MOVED")) { // 解析MOVED错误中的新节点信息 String[] movedInfo = e.getMessage().split(" "); String newHost = movedInfo[2].split(":")[0]; int newPort = Integer.parseInt(movedInfo[2].split(":")[1]); // 更新RedisURI并重新连接到新节点 redisURI.setHost(newHost); redisURI.setPort(newPort); connection = redisClusterClient.connect(redisURI); commands = connection.sync(); // 重新发送命令 commands.set(key, value); } else { // 处理其他类型的Redis命令执行异常 e.printStackTrace(); } } connection.close(); redisClusterClient.shutdown(); } } ``` 请注意,上述代码仅为示例,你需要根据你的实际情况进行适当的修改和调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我要做个有钱人2020

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值