线上一个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. Arch Linux 安装 Anbox

    镜像下载.域名解析.时间同步请点击 阿里云开源镜像站 Anbox 介绍 Anbox 是一个可以在 GNU/Linux 发行版上运行 Android App 的容器,是一个开源兼容层. 其工作原理是在 ...

  2. “exec: "ssh-keygen": executable file not found in %PATH%” 问题解决

    set PATH=%PATH%;C:\Program Files (x86)\Git\bin bash start.sh 将以上内容保存为start.bat,放在boot2docker根目录下,管理员 ...

  3. python3 爬虫2--发送请求1

    1urlopen 属于url.request类 我们用urlopen("网址")来发送请求 最基础的发送请求如下 from urllib.request import urlope ...

  4. svn 清理报错

    Can't install '*' from pristine store, because no checksum is recorded for this file svn同步时,提示clean ...

  5. 请说说你对Struts2的拦截器的理解?

    Struts2拦截器是在访问某个Action或Action的某个方法,字段之前或之后实施拦截,并且Struts2拦截器是可插拔的,拦截器是AOP的一种实现. 拦截器栈(Interceptor Stac ...

  6. 使用 rabbitmq 的场景?

    1.服务间异步通信 2.顺序消费 3.定时任务 4.请求削峰

  7. 什么是通知(Advice)?

    特定 JoinPoint 处的 Aspect 所采取的动作称为 Advice.Spring AOP 使用一 个 Advice 作为拦截器,在 JoinPoint "周围"维护一系列 ...

  8. 学习Keepalived(三)

    1.1Keepalived高可用软件 Keepalived起初是专为LVS设计的,专门用来监控LVS集群系统中各个服务节点的状态,后来又加入了VRRP的功能,因此除了配合LVS服务外,也可以作为其他服 ...

  9. 学习Apache(一)

    实验目的 通过apache实现反向代理的功能,类似nginx反向代理和haproxy反向代理 环境准备 逻辑架构如下 前端是apche服务器,监听80端口,后端有两台web服务器,分别是node1和n ...

  10. 学习ITIL

    ITIL IT运维管理体系: IT管理中的PPT(people人:process流程:technology技术): 标准化(是否有紧急故障处理流程).工具化: 备份解决方案:灾备解决方案: 监控解决方 ...