文章目录
- 一、背景
- 二、坑点
- 三、难点
- 四、解决
- 4.1 离线安装redis-trib环境
- 4.2 解决中断```redis-trib rebalance```命令后槽位的修复问题
- 4.2.1 动态扩容的过程
- 4.2.2 ```redis-trib```的执行原理
- 4.2.3 实战记录
- 五、后续
一、背景
- 业务用户的增长,redis集群内存使用越来越大
- 集群单节点的内存限额已经很大了(17GB),不能单纯的通过调整节点内存限额来扩容
- 不能纵向扩容,那就横向扩容
二、坑点
- 因为海外网络的原因,导致使用
redis-trib reblance
进行动态扩容时很慢 - 本地机房10分钟迁完一个节点的槽位,海外跨机房10个小时才能迁完一个节点
- 又不敢中断,怕中断后槽位分配出现问题,之后很难调整
从早上10点迁到晚上8点才迁完一个节点的,实在是慢的不行;还考虑到万一夜里进程挂掉了,那时候处理起来更麻烦了。
所以决定主动出击,把问题尽快解决,为业务减少点损失,也给自己找条生路…
三、难点
这个问题主要是有两个难点:
- 怎么在海外机器上离线搭建redis-trib.rb环境(生产环境中的服务器不能连外网,不好直接下载东西)
- 中断
redis-trib rebalance
命令后,槽位分配万一出现问题,要怎么修复
四、解决
4.1 离线安装redis-trib环境
离线安装环境的主要参考如下:
还有一个的难点就是传文件,我这边的办法是:
- 先将需要的安装包下载到本地
- 然后通过终端,直接将文件拖动上传到内网办公的服务器
- 在服务器上使用
nc
命令将安装包发送到海外的服务器上
4.2 解决中断redis-trib rebalance
命令后槽位的修复问题
要解决redis-trib rebalance
中断后的问题,首先得知道动态扩容涉及到的过程,以及redis-trib
的执行原理。
4.2.1 动态扩容的过程
- 准备新节点
- 提前准备好新节点并运行在集群模式下
- 建议使用相同的配置文件,便于管理
- 加入集群
- 可用
cluster meet
命令 - 也可用
redis-trib.rb add-node
命令 - 线上环境建议使用
redis-trib.rb add-node
命令添加,避免将新节点加入到其他集群,造成集群‘融合’,导致数据丢失
- 迁移槽和数据
- 槽迁移计划
- 迁移数据
- 对目标节点发送cluster setslot{slot}importing{sourceNodeId}命令,让目标节点准备导入槽的数据
- 对源节点发送cluster setslot{slot}migrating{targetNodeId}命令,让源节点准备迁出槽的数据
- 源节点循环执行cluster getkeysinslot{slot}{count}命令,获取count个属于槽{slot}的键
- 在源节点上执行migrate{targetIp}{targetPort}""0{timeout}keys{keys…}命令,把获取的键通过流水线(pipeline)机制批量迁移到目标节点,批量迁移版本的migrate命令在Redis3.0.6以上版本提供,之前的migrate命令只能单个键迁移。对于大量key的场景,批量键迁移将极大降低节点之间网络IO次数
- 重复执行上述两个步骤,直到槽下所有的键值数据迁移到目标节点
- 向集群内所有主节点发送cluster setslot{slot}node{targetNodeId}命令,通知槽分配给目标节点。为了保证槽节点映射变更及时传播,需要遍历发送给所有主节点更新被迁移的槽指向新节点
- 添加从节点
- 使用cluster replicate{masterNodeId}命令为主节点添加对应从节点
4.2.2 redis-trib
的执行原理
主要参考如下:
4.2.3 实战记录
在了解了redis集群的动态扩容原理以及redis-trib的具体实现过程后,先在测试集群上做了实验,发现redis-trib.rb fix ip:port
是能修复rebalance
中断导致的槽位问题,所以就开始在线上开始操作。
- 按下
Ctrl+c
中断redis-trib.rb rebalance
进程 - 使用
redis-triib.rb check
检查集群的状态(发现23号槽位还在处理开放的状态)
...
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
[WARNING] Node 10.172.18.26:34564 has slots in migrating state (23).
[WARNING] Node 10.172.18.24:37571 has slots in importing state (23).
[WARNING] The following slots are open: 23
>>> Check slots coverage...
[OK] All 16384 slots covered.
- 使用
redis-triib.rb fix
修复集群的状态(把正在处于migrating和importing的那个槽位(23)接着处理完)
...
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
[WARNING] Node 10.172.18.26:34564 has slots in migrating state (23).
[WARNING] Node 10.172.18.24:37571 has slots in importing state (23).
[WARNING] The following slots are open: 23
>>> Fixing open slot 23
Set as migrating in: 10.172.18.26:34564
Set as importing in: 10.172.18.24:37571
Moving slot 23 from 10.172.18.26:34564 to 10.172.18.24:37571: ...........................................................
>>> Check slots coverage...
[OK] All 16384 slots covered.
- 再使用
redis-triib.rb check
检查集群的状态(这时候集群状态就正常,没有异常槽位)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
注意:有时候执行一遍redis-trib fix
之后,集群check之后发现有提示
Redis [ERR] Nodes don’t agree about configuration!
这应该是由于各个节点的槽位信息不一致导致的,需要调整各个节点槽位记录,让其保持一致。
最简单的方法是再执行一遍redis-trib fix
,让其自动校验调整下集群的槽位信息。
- 确认集群状态正常后,到海外的机器上再次执行
redis-trib.rb rebalance
命令,让其开始做槽位迁移
五、后续
之后在海外机器上做迁移果然快多了。。。
下次一定得注意r`edis-trib.rb
命令的跨机房使用,不光慢不说,还可能中断后槽位信息不一致导致集群不可用,那就GGL了。
还好提前处理了,不然又得写故障报告了@_@