线上一个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. MongoDB 镜像配置方法

    镜像下载.域名解析.时间同步请点击 阿里巴巴开源镜像站 MongoDB 是一个基于分布式文件存储的数据库.由 C++ 语言编写.旨在为 WEB 应用提供可扩展的高性能数据存储解决方案. 配置方法 安装 ...

  2. 同一局域网ping ip 失败(可能是你的路由器坑了你)

    事件起源:手机需要通过fiddler代理抓包 一顿操作猛如虎,手机输入ip+端口,芭比q了,连接不上.. 解决思路: 一.保证双方处于同一局域网内 二.查看电脑配置,找到 防火墙,关闭防火墙,再试 三 ...

  3. springcloud学习03-spring cloud eureka(下)

    7.配置服务提供者(生产者) 7.1.配置resources/application.yml. 值eureka.client.service-url(或serviceUrl).defaultZone是 ...

  4. weblogic重要漏洞记录

    (PS:之前在freebuf发过,这里直接复制过来的,所以有些图片会有水印) 前言 T3协议存在多个反序列化漏洞CVE-2015-4852/CVE-2016-0638/CVE-2016-3510/CV ...

  5. Git-rebase使用原理

    使用 Git 已经好几年了,却始终只是熟悉一些常用的操作.对于 Git Rebase 却很少用到,直到这一次,不得不用. 一.起因 上线构建的过程中扫了一眼代码变更,突然发现,commit 提交竟然多 ...

  6. java-spring

    Spring-IOC ioc概念 控制反转 把对象创建和对象之间的调用过程,交给Spring 进行管理. 目的就是,为了降低耦合度,因为当你想在一个类当中调用另外一个类的方法,你需要获得另外一个类的实 ...

  7. 解释 JDBC 抽象和 DAO 模块?

    通过使用 JDBC 抽象和 DAO 模块,保证数据库代码的简洁,并能避免数据库资源 错误关闭导致的问题,它在各种不同的数据库的错误信息之上,提供了一个统一 的异常访问层.它还利用 Spring 的 A ...

  8. scrapy基于请求传参实现深度爬取

    请求传参实现深度爬取 请求传参: 实现深度爬取:爬取多个层级对应的页面数据 使用场景:爬取的数据没有在同一张页面中 在手动请求的时候传递item:yield scrapy.Request(url,ca ...

  9. 修改if-else多层嵌套的方法

    例子:在判断三角形形状的一个程序中,会出现 if-else 的多层嵌套,可利用程序的顺序执行结构重构代码,使其更可读.如果还想保证代码的安全性,可以用函数封装这段代码. #include <st ...

  10. 比较数字范围:判断number存在(minRange ~ maxRange)范围中

    一.使用场景 当需要比较范围时 如: 这种情况,如果要写三个表达式会很长,这时候就可以用这个工具类进行比较 number:用户输入(长,宽,高) minRange: 0.0 maxRange:33 二 ...