线上一个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. vue学习过程总结(05) - vue的重要插件vue-router

    vue-router的中文文档:https://router.vuejs.org/zh/installation.html(基于文档的摘抄) 1.vue中的组件与插件 转载:https://blog. ...

  2. DDOS攻击应用

    0x01 环境 包含3台主机 attact 作为攻击方,使用Centos7.2,安装slowhttptest server 作为被攻击服务器,安装有apached windows,用于访问 serve ...

  3. 【SEED Labs】TCP Attacks Lab

    Lab Overview 实验环境下载:https://seedsecuritylabs.org/Labs_16.04/Networking/TCP_Attacks/ 本实验涵盖以下课题: • TCP ...

  4. Windows 8下完美使用Virtual PC 2007(virtual pc 2007 64 win8 兼容性)

    Windows 8下完美使用Virtual PC 2007(virtual pc 2007 64 win8 兼容性) 一.从微软的官方网站下载Virtual PC 2007 SP1英文版,文件名为se ...

  5. 12.19 file 与io流

    12.19 file与io流 File 1. 新建文件或者文件夹 新建文件 File F = new File(pathname:"路径+文件名");Boolean flag = ...

  6. ArrayList如何实现插入的数据按自定义的方式有序存放?

    编程思路是:实现一个类对ArrayList进行包装,当程序试图向ArrayList中放入数据时,程序将先检查该元素与ArrayList集合中其他元素的大小,然后将该元素插入到指定位置. class M ...

  7. java动态代理--代理接口无实现类

    转载:https://blog.csdn.net/weixin_45674354/article/details/103246715 1.接口定义: package cn.proxy; public ...

  8. List和 Map区别?

    一个是存储单列数据的集合,另一个是存储键和值这样的双列数据的集合,List中存储的数据是有顺序,并且允许重复:Map中存储的数据是没有顺序的,其键是不能重复的,它的值是可以有重复的.

  9. MySQL 里有 2000w 数据,redis 中只存 20w 的数据,如 何保证 redis 中的数据都是热点数据?

    Redis 内存数据集大小上升到一定大小的时候,就会施行数据淘汰策略. 相关知识:Redis 提供 6 种数据淘汰策略: volatile-lru:从已设置过期时间的数据集(server.db[i]. ...

  10. springboot-数据库访问之jpa

    什么是springDate? springData的作用: 整体简化的架构: JPA :Java Persistence API 如果没有springData 我们需要去学每一种对应的jpa实现, 有 ...