线上一个redis集群中主节点使用的内存达到了9.78g,按照redis单个实例最大内存不要超出10g的规范,扩容操作就放在了今天晚上进行。因为之前redis迁槽都是采用 redis-trib.rb reshard xxx.xxx.xxx.xxx:8001 的方式进行,今晚准备采用 redis-trib.rb reshard --from 61e615f22e5e338ed8d0e107ac5d1f80b41cabc3 --to 139ccdd0dfdf757950cb9a45b812bad898eb6b6e --slots 2730 --yes --timeout 10000 --pipeline 100 xxx.xxx.xxx.xxx:8001 的方式进行,就先在测试环境跑上一把,很遗憾,测试环境运行失败!!

在命令运行过程中,出现了以下错误:

Moving slot 8183 from 61e615f22e5e338ed8d0e107ac5d1f80b41cabc3
Moving slot 8184 from 61e615f22e5e338ed8d0e107ac5d1f80b41cabc3
Moving slot 8185 from 61e615f22e5e338ed8d0e107ac5d1f80b41cabc3
Moving slot 8186 from 61e615f22e5e338ed8d0e107ac5d1f80b41cabc3
Moving slot 8187 from 61e615f22e5e338ed8d0e107ac5d1f80b41cabc3
Moving slot 8188 from 61e615f22e5e338ed8d0e107ac5d1f80b41cabc3
Moving slot 8189 from 61e615f22e5e338ed8d0e107ac5d1f80b41cabc3
Moving slot 8190 from 61e615f22e5e338ed8d0e107ac5d1f80b41cabc3
Moving slot 5461 from 192.168.96.14:8002@18002 to 192.168.96.14:8001:
[ERR] Calling MIGRATE: ERR Syntax error, try CLIENT (LIST | KILL | GETNAME | SETNAME | PAUSE | REPLY)

OK,那就查看以下集群状态吧:

S: e68d2e6a96c154ac6927059fc0264da98fd0f73b 192.168.96.14:8006@18006
slots: (0 slots) slave
replicates d5a545398f54d03d9ac2289d37430f48f472d525
S: 1e020b85eb2ee077e0d2de3a9b70c9ea6a30c156 192.168.96.14:8004@18004
slots: (0 slots) slave
replicates 139ccdd0dfdf757950cb9a45b812bad898eb6b6e
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
[WARNING] Node 192.168.96.14:8001 has slots in importing state (5461).
[WARNING] Node 192.168.96.14:8002@18002 has slots in migrating state (5461).
[WARNING] The following slots are open: 5461
>>> Check slots coverage...
[OK] All 16384 slots covered.

好吧,集群状态报错,那就先把集群恢复原状:

1. redis-trib.rb fix xxx.xx.xx.xxx:8001

该命令不怎么好使啊:

[OK] All nodes agree about slots configuration.
>>> Check for open slots...
[WARNING] Node 192.168.96.14:8001 has slots in importing state (5461).
[WARNING] Node 192.168.96.14:8002@18002 has slots in migrating state (5461).
[WARNING] The following slots are open: 5461
>>> Fixing open slot 5461
Set as migrating in: 192.168.96.14:8002@18002
Set as importing in: 192.168.96.14:8001
Moving slot 5461 from 192.168.96.14:8002@18002 to 192.168.96.14:8001:
[ERR] Calling MIGRATE: ERR Syntax error, try CLIENT (LIST | KILL | GETNAME | SETNAME | PAUSE | REPLY)

2. 没办法了,在 WARNING 的两个节点上分别执行 cluster setslot 5461 stable,然后再check集群状态,这次正常了,如果不行,就再fix一次。

集群状态虽然恢复了,但是扩容还是要做的,再在测试环境执行一次,还是同样的错误,这就有点尴尬了。

再尴尬问题还是要解决的,那就先看看这个报错的5461槽位中有哪些key,以及这些key的状态:

[root@localhost data]# redis-cli -p 8002
127.0.0.1:8002> CLUSTER GETKEYSINSLOT 5461 100
1) "key4290"
127.0.0.1:8002>
127.0.0.1:8002> DEBUG OBJECT key4290
Value at:0x7f0823b6f360 refcount:1 encoding:embstr serializedlength:11 lru:794344 lru_seconds_idle:3689

可以看到,这个key也没有什么不正常的,继续查原因,既然自动的不行,那就手动迁槽试试,看看到底那里出的问题

--------------------------------------------------------------------------------------------------------------------------------------------------------------------

redis迁槽流程:

1. 对目标节点发送 cluster setslot {slot} importing {sourceNodeId}命令,让目标节点准备导入槽的数据

2. 对源节点发送  cluster setslot {slot} migrating {targetNodeId}命令,让源节点准备迁出槽的数据

3. 源节点循环执行cluster getkeysinslot {slot} {count}命令,获取count个属于槽 slot的键

4. 在源节点上执行 migrate {targetIp} {targetPort} "" 0 {timeout} keys {keys ....} 命令,把获取的键通过pipeline的机制批量迁移至目标节点

5. 重复3、4步直到槽下所有的键值数据都迁移至目标节点

6. 向集群中的所有主节点发送 cluster setslot {slot} node {targetNodeId}命令,通知槽分配给目标节点。

--------------------------------------------------------------------------------------------------------------------------------------------------------------------

按照redis迁槽流程一步一步执行,终于在执行第4步的时候报了个错误:

[root@localhost logs]# redis-cli -p 8002
127.0.0.1:8002> cluster setslot 5461 migrating 139ccdd0dfdf757950cb9a45b812bad898eb6b6e
OK
127.0.0.1:8002> cluster getkeysinslot 5461 100
1) "key4290"
127.0.0.1:8002> migrate 192.168.96.14 8001 "" 0 5000 keys key4290
(error) ERR Target instance replied with error: NOREPLICAS Not enough good slaves to write.

貌似找到原因了,再去target节点上一看:

[root@localhost data]# redis-cli -p 8001
127.0.0.1:8001> cluster setslot 5461 importing 61e615f22e5e338ed8d0e107ac5d1f80b41cabc3
OK
127.0.0.1:8001> config get min-slaves-to-write
1) "min-slaves-to-write"
2) "2"

果然,min-slaves-to-write设置的是2,而测试环境的redis集群是3主3从的结构,调整 min-slaves-to-write的值,将其设置为0,再跑一遍,手动迁槽成功,但是redis-trib.rb操作还是报一样的错误,醉了

最后,同事说是不是redis-trib.rb有问题,好,换一台机器跑redis-trib.rb命令,成功。

Redis4.0.14 迁槽失败的更多相关文章

  1. redis-4.0.14 cluster 配置实战

    1.操作系统配置 切换到root用户修改配置sysctl.conf vim /etc/sysctl.conf # 添加配置: vm.max_map_count= vm.overcommit_memor ...

  2. Redis(1.11)Redis4.0.11 cluster 分布式集群搭建

    概念与了解:Redis(1.7)Redis高可用架构(理论篇) [0]试验环境 结构图如下: (这里试验没有那么多机器,就用3台机器搭建试验) redis1是redis集群的一个节点A,上面运行了两个 ...

  3. linux非root用户安装4.0.14版本redis

    先到官网https://redis.io/download下安装包,现在最新是5.0.5版本,可惜点击下载后被windows禁了,那就下4版本的,往下看Other versions的Old(4.0), ...

  4. Redis-4.0.11集群配置

    版本:redis-3.0.5 redis-3.2.0  redis-3.2.9  redis-4.0.11 参考:http://redis.io/topics/cluster-tutorial. 集群 ...

  5. Redis(二)CentOS7安装Redis4.0.10与集群搭建

    一 Redis单机安装 1 Redis下载安装 1.1 检查依赖环境(Redis是C语言开发,编译依赖gcc环境) [root@node21 redis-]$ gcc -v -bash: gcc: c ...

  6. centos7多节点部署redis4.0.11集群

    1.服务器集群服务器 redis节点node-i(192.168.0.168) 7001,7002node-ii(192.168.0.169) 7003,7004node-iii(192.168.0. ...

  7. linux下redis4.0.2集群部署(利用Ruby脚本命令)

    一.原生命令方式和Ruby脚本方式区别 利用Ruby脚本部署和用原生命令部署,节点准备的步骤都是一样的,节点启动后的握手,以及主从.槽分配,利用Ruby脚本一步就能完成,利用原生命令需要一步一步地执行 ...

  8. CentOs7.3 搭建 Redis-4.0.1 Cluster 集群服务

    环境 VMware版本号:12.0.0 CentOS版本:CentOS 7.3.1611 三台虚拟机(IP):192.168.252.101,192.168.102..102,192.168.252. ...

  9. Redis4.0之持久化存储

    一,redis概述与实验环境说明 1.1 什么是redis redis是一种内存型的NoSQL数据库,优点是快,常用来做缓存用  redis存储数据的方法是以key-value的形式  value类型 ...

随机推荐

  1. 4月24日 python学习总结 多进程与子进程

    一.进程 并发的本质: cpu切换进程+保存状态 一个程序执行了多次,就启动了多个进程 进程与进程之间的内存空间是隔离开的 二.在一个进程中开启子进程 新进程的创建都是由一个已经存在的进程执行了一个用 ...

  2. python溴事百科爬虫

    import urllib.request import re # qianxiao996精心制作 #博客地址:https://blog.csdn.net/qq_36374896 def jokeCr ...

  3. Android studio Error occurred during initialization of VM

    Unable to start the daemon process. This problem might be caused by incorrect configuration of the d ...

  4. mac安装git

    https://blog.csdn.net/shaock2018/article/details/91127607 继续报错 rm -rf /usr/local/Homebrew/Library/Ta ...

  5. 面试问题之操作系统:linux线程API

    https://blog.csdn.net/youwotianya/article/details/80933449

  6. ClassNotFoundException: javax.persistence.Converter

    检查你的hibernate-jpa-2.0-api-1.0.0.final.jar,会发现javax.persitence包中没有Convert类. 解决办法:下载hibernate-jpa-2.1- ...

  7. SpringBoot项目集成swagger报NumberFormatException: For input string: ""

    java.lang.NumberFormatException: For input string: "" at java.lang.NumberFormatException.f ...

  8. spring boot 自动装配的原理

    参考: https://blog.csdn.net/Dongguabai/article/details/80865599.如有侵权,请联系本人删除! 入口: import org.springfra ...

  9. String工具类之“前缀比较”StringUtils.startsWith和StringUtils.startsWithIgnoreCase

    (1)字符串以prefix为前缀(区分大小写) StringUtils.startsWith(被比较的字符串,比较字符串) 总结: 根据下面代码发现,上面的例子有部分时错误的,有可能是因为思维原因,他 ...

  10. python学习笔记(五)——模块导入

    模块是一个包含所有你定义的函数和变量的文件,其后缀名是.py.模块可以被别的程序引入,以使用该模块中的函数等功能.这也是使用 python 标准库的方法. 1.模块的定义与分类 在python中模块实 ...