先上结果:

$redis->sDiffStore('live_room:robots:data:' . $info['id'], 'user_info:robots_list', '');

上述代码执行后redis抛出一个异常。来看redis源码是如何抛出这个异常的(附redis源码地址:redis/cluster.c at 5.0 · redis/redis · GitHub):

CLUSTER_REDIR_CROSS_SLOT 这个异常,继续定位:

这里已经说的很明白了,如果一个redis请求操作了多个Key,并且key不在同一个slot下,就会出现这个异常,来看源码的实现:

问题很好定位,解决的话我是放弃了redis提供的方法,自己将key1的内容拿出来,利用协程去将这些数据跑到新key下,此举在数据量大的情况下是否合适另说,紧急情况下解决问题为主。

通过这个问题明确几个概念:

1. redis 集群的 slot :

redis 集群中的 key 空间被划分为 16384 个 hash slot,节点数量也被限制为最多16384个(建议1000以内)。每个节点负责一部分的 hash slot,key 划分到 hash slot的规则如下:

HASH_SLOT = CRC16(key) mod 16384

hash slot 最大的作用应该就是提高扩展性了,可以很好地帮助集群的横向伸缩,增减节点时只需要将节点上的 slot 转移到其他节点。

2. 哪些操作会被限制:

集群模式,一次请求,涉及多个key。

  • 多 key 命令:mset mget sDiffStore sUnionStore 等
  • 多 key 的事务(MULTI)
  • 多 key 的Lua脚本

3. 出现环境:

据说!是据说啊!!!我没有证据。

Redis Enterprise 没有这个问题,只是开源版有这个问题

4. 解决办法:

hash tag

-------------------------------------------------------虚线以内部分为摘录

hash tag 可以影响 hash slot 的生成,相同 hash tag 的 key 会被分配到相同的 hash slot。hash tag使用 {...} 形式。对于包含 hash tag 的 key,redis只会对 {} 内的字符串计算 hash,从而相同 hash tag 的 key 会计算得到相同的 hash slot。

一个有效的 hash tag 应该是key中首个 { 和首个 }(在首个 { 之后) 之间有字符存在。

示例:

  • {user1000}.following、 {user1000}.follower 有相同 hash tag,会被分到相同的 slot
  • foo{}{bar} 没有有效的 hash tag,会按照 foo{}{bar} 进行 hash 计算
  • foozap 有有效的 hash tag,会按照 {bar 进行 hash 计算
  • foo{bar}{zap} 有有效的 hash tag,会按照 bar 进行 hash 计算

注意,hash tag 要合理使用,避免大量的 key 被分配到相同 slot 里导致数据存储和访问倾斜。

-------------------------------------------------------虚线以内部分为摘录

可见,hash tag可以使那些key中有相同且固定字符串的key最终被分配到同一个hash slot中,这样从数据源头上避免了跨slot操作的问题,但是不能滥用,并且需要在一开始的代码结构设计中就要考虑到这个问题,不然就像我上述出问题的代码,多个key是完全不同的,在不变key的情况下,即使有hash tag也不能解决这个问题,只能暂时用笨办法一个一个循环插入了。

总结完毕   收工结束!

文章知识点与官方知识档案匹配,可进一步学习相关知识
MySQL入门技能树首页概览52178 人正在系统学习中

[转帖]redis集群报错CROSSSLOT Keys in request don‘t hash to the same slot的更多相关文章

  1. redis集群报错

    写入redis集群报错:(error) MOVED 6918 解决方法:redis-cli -c -p 7001 -h 10.0.0.104

  2. redis集群报错:(error) CLUSTERDOWN Hash slot not served

    百度上坑太多,如果你遇到搭建redis集群的时候出现这个错误在百度上找到解决办法基本上都是坑. 首先集群搭建完成后,你肯定去登陆redis进行测试 1.redis01/redis-cli -h &qu ...

  3. redis集群报错:(error) CLUSTERDOWN The cluster is down

    更换了电脑,把原来的电脑上的虚拟机复制到了新电脑上,启动虚拟机上的centos系统,然后启动redis集群(redis5版本),发现集群可以启动,redis进程也有,但是连接集群中的任意节点就报错,如 ...

  4. maven项目中使用redis集群报错: java.lang.NumberFormatException: For input string: "7001@17001"

    解决:由于redis集群的采用的版本是2.7的,在maven的pom.xml中将jedis的版本改成2.9的就可以了

  5. maven项目中使用redis集群报错: java.lang.NumberFormatException: For input string: "7006@17006"

    Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [redis.client ...

  6. redis集群报错:(error) MOVED 11469 192.168.163.249:7002

    应该是你没有启动集群模式(即缺少了那个"-c"): redis-cli -c -h yourhost -p yourpost

  7. redis集群报错,(error) MOVED 15495 127.0.0.1:7003

        节点会对命令请求进行分析和key的slot计算,并且会查找这个命令所要处理的键所在的槽.如果要查找的哈希槽正好就由接收到命令的节点负责处理, 那么节点就直接执行这个命令. 另一方面, 如果所查 ...

  8. redis集群报错:(error) MOVED 5798 127.0.0.1:7001

    原因 这种情况一般是因为启动redis-cli时没有设置集群模式所导致. 解决方案 启动时使用-c参数来启动集群模式,命令如下: redis-cli -c -p 7000 测试 127.0.0.1:7 ...

  9. Redis创建集群报错

    Redis创建集群报错: 1:任何一个集群节点中都不能存在数据,如果有备份一下删除掉aof文件或rdb文件 2: nodes-集群端口.conf 文件存的会有报错记录,所以该文件也要删除

  10. quartz集群报错but has failed to stop it. This is very likely to create a memory leak.

    quartz集群报错but has failed to stop it. This is very likely to create a memory leak. 在一台配置1核2G内存的阿里云服务器 ...

随机推荐

  1. 面试官问我:线程锁导致的kafka客户端超时,如何解决?

    本文分享自华为云社区<线程锁导致的kafka客户端超时问题>,作者: 张俭 . 问题背景 有一个环境的kafka client发送数据有部分超时,拓扑图也非常简单 定位历程 我们先对客户端 ...

  2. vue2升级vue3:vue3 hooks库选用

    之前a-hooks:https://ahooks.js.org/,比react-use 精简好用.但是没有vue版本的. 网上有个人实现的:https://github.com/dewfall123/ ...

  3. Vue 应用程序性能优化:代码压缩、加密和混淆配置详解

    ​ 简介在 Vue 应用程序的开发中,代码压缩.加密和混淆是优化应用程序性能和提高安全性的重要步骤. Vue CLI 是一个功能强大的开发工具,它提供了方便的配置选项来实现这些功能.本文将介绍如何使用 ...

  4. 记一次 .NET某MES自动化桌面程序 卡死分析

    一:背景 1. 讲故事 前些天有位朋友在微信上找到我,说他们的客户端程序卡死了,让我帮忙看下是什么原因导致的?dump也拿到了手,既然有了dump就开始正式分析吧. 二:WinDbg 分析 1. 什么 ...

  5. 【redis】 redis linux下安装 redis启动方式 redis典型场景 redis通用命令 数据结构和内部编码 redis字符串类型

    目录 上节回顾 今日内容 1 redis介绍 2 redis linux下安装 3 redis启动方式 3.1 最简启动 3.2 动态参数启动 3.3 配置文件启动 3.4 客户端连接命令 4 red ...

  6. protobuf安装、编译和使用

    protobuf使用简单示例 一.安装 首先下载protobuf的安装包,我这里使用的是protobuf-cpp-3.21.5.tar.gz 解压安装包 tar -xzf protobuf-cpp-3 ...

  7. 【ToolChains】CLion(VS2019) + CMake + Vcpkg 的使用

    参考博客: https://blog.51cto.com/u_15075510/4201238 http://t.csdn.cn/pADDU https://zhuanlan.zhihu.com/p/ ...

  8. Windows环境下,解决无法使用ping命令

    众所周知,ping命令是个非常实用的网络命令:有时,我们会发现在电脑中无法使用ping命令,一般来说,是由于电脑的环境变量出了问题,本文将介绍如何解决这个问题. 1.一般出现ping命令无法使用的情况 ...

  9. 版本升级 | v1.0.11 上线,你的需求被翻牌了吗?

    叮咚-综合我们接到的各种用户反馈,OpenSCA 项目组在 1.0.10 的基础上迭代了 1.0.11 版本 升级功能 优化 Java 解析逻辑 支持打印结果概览及常见报错信息到终端界面 支持输出 C ...

  10. 微信小程序图片展示类型