[redis] redis在线系统热迁移的方案与记录
一 前言
如图,是我的环境。
这里边有三个系统,1 业务系统。2 redis cluster集群。3 redis cluster集群的管理系统。
系统1,会对redis中进行秒级的数据添加,读取,删除操作。系统3,是redis集群的增加节点减少节点,节点failover功能进行管理。
如图目前,我的系统里,redis共占用了a1,b1,c1,d1四台物理设备。我的目的是,在不影响业务系统运行的情况下,
将redis集群迁移到a2,b2,c2,d2四台物理设备上去。
二 预备知识
目标系统的redis版本是4.0,之所以强调版本,是因为新版本中,拥有了命令
redis-cli --cluster。4.0版本中并没有,它的前任是脚本,redis-trib.rb。二者
大同小异,没有本质区别。
下面是,进行中使用到的几个操作
1. 查看当前集群拓扑的方法
redis-cli -c cluster nodes redis-cli -c cluster slots
拓扑关系
a51459f9cf9b5611cefe137dfcfbd9d9fdb03cfe 10.1.3.168:6379@16379 slave c3ac54ffd1efd366fdf70b3ba0e4185bee49840e 0 1584705659599 6 connected 8ea700c80aa9bebbcd87549cad4538cfeb13dc5f 10.1.4.40:6379@16379 master - 0 1584705662628 1 connected 0-5460 d1fb28322822546c76800cee00fc08ea30eee3d9 10.1.4.39:6379@16379 slave 38dcb1adf11ca19bc66d2d2e887588fb65537c9e 0 1584705658000 4 connected f4f3aa15073de7f6efc0ee104d4b51de8d5e5ff5 10.1.3.165:6379@16379 slave 8ea700c80aa9bebbcd87549cad4538cfeb13dc5f 0 1584705660606 5 connected 38dcb1adf11ca19bc66d2d2e887588fb65537c9e 10.1.3.170:6379@16379 myself,master - 0 1584705659000 3 connected 10923-16383 c3ac54ffd1efd366fdf70b3ba0e4185bee49840e 10.1.3.169:6379@16379 master - 0 1584705661622 2 connected 5461-10922
2 查看数据分布的方法
redis-trib.rb info 127.0.0.1:6379
数据分别是指,那些数据存储在那些节点上。
我这里的集群组织方式是,一对一对的组织。每一对有一个master,一个slave。slave作为master的数据冗余和failover节点。可以从上一个命令的输出里,见到他们的关系,
而,数据的分布如下所示,关注keys信息。可以看见,那些那些key,在那些那些地方。当正在进行数据迁移时,我们能看见keys前边的数值在一点点减少。
[root@redis6st caotong]# redis-trib.rb info 127.0.0.1:6379 127.0.0.1:6379 (38dcb1ad...) -> 1998 keys | 5461 slots | 1 slaves. 10.1.4.40:6379 (8ea700c8...) -> 2012 keys | 5461 slots | 1 slaves. 10.1.3.169:6379 (c3ac54ff...) -> 1999 keys | 5462 slots | 1 slaves. [OK] 6009 keys in 3 masters. 0.37 keys per slot on average.
3 查看集群实时状态的方法
redis-trib.rb check 127.0.0.1:6379
这个输出,重点关心的是一下额外的信息, 如xxx is migrating 字样
[root@redis6st caotong]# redis-trib.rb check 127.0.0.1:6379 >>> Performing Cluster Check (using node 127.0.0.1:6379) M: 38dcb1adf11ca19bc66d2d2e887588fb65537c9e 127.0.0.1:6379 slots:10923-16383 (5461 slots) master 1 additional replica(s) S: a51459f9cf9b5611cefe137dfcfbd9d9fdb03cfe 10.1.3.168:6379 slots: (0 slots) slave replicates c3ac54ffd1efd366fdf70b3ba0e4185bee49840e M: 8ea700c80aa9bebbcd87549cad4538cfeb13dc5f 10.1.4.40:6379 slots:0-5460 (5461 slots) master 1 additional replica(s) S: d1fb28322822546c76800cee00fc08ea30eee3d9 10.1.4.39:6379 slots: (0 slots) slave replicates 38dcb1adf11ca19bc66d2d2e887588fb65537c9e S: f4f3aa15073de7f6efc0ee104d4b51de8d5e5ff5 10.1.3.165:6379 slots: (0 slots) slave replicates 8ea700c80aa9bebbcd87549cad4538cfeb13dc5f M: c3ac54ffd1efd366fdf70b3ba0e4185bee49840e 10.1.3.169:6379 slots:5461-10922 (5462 slots) master 1 additional replica(s) [OK] All nodes agree about slots configuration. >>> Check for open slots... >>> Check slots coverage... [OK] All 16384 slots covered.
三 思路
两个思路。
1,把集群节点迁走,集群还是那个集群只不过他们的各种节点都被更新了。
2,把数据迁走,幸运的是我的业务系统有重连机制,并且支持热修改集群信息。所以只要保证数据的增删改查都能成功并正确。切换一个全新的cluster同样对业务无感知。
四 方案一
我这里,采用的迁移方案,是先扩容再缩容。这样是热的,online的。对在线系统无感知的。
把你想迁入的目标作为扩容资源扩进来,然后再将你想缩容的资源作为迁出目标缩掉,即可。
我会先增加一对主备节点,然后理由上面提到的两个命令,来观察:
(1)迁移的过程是否正常,(2)数据是否正常流动,(3)迁移是否已经进行完成
迁移进行完成指的是数据流动已经完成。
过程是否正常:1 通过前文的check命令查看runtime状态。2.通过info命名查看数据流动进程。
最终的状态,可以通过nodes命令观察,是否出现fail的节点。以及是否每个master都结对一个slave,
包括谁和谁是一对的这种对应关系。
增减动作通过前文中的管理系统接口完成的,没有命令的细节。 该系统只是对redis -cli和redis-trib.rb的封装,
附加了他自己的逻辑在里边。
redis-cli --cluster help可以看见更多细节,包括add node,add slot之类的常用命令。
删除一个节点的方法:
redis-trib.rb del-node host:port node_id
参考: https://www.cnblogs.com/ivictor/p/9768010.html
然而,该方案并没有实施成功,因为该管理系统的bug,导致其自己进入不可跳出的管理状态里。
这里不在赘述,进入方案二
五 方案二
如前文述,方案二的思路是数据迁移。管理系统在节点变更是存在问题。但是全新创建的话,仍然是可用的。
于是,现在我们可用绕可它来达到目标。
需要强调的是,本人是新手,完成100台以下的数据迁移工作只有三天时间,并之前几乎没有好好接触过redis。
所以整体目标是安全与快速。故选用以下四个方法,并排列优先级:
可选有四种方法,要求必须满足online的数据无缝热迁移:
1 python工具:https://github.com/p/redis-dump-load
该工具简单使用后发现不支持集群,只支持单点设备。工作量大,留做备选。
2 ruby工具: https://github.com/delano/redis-dump
该工具测试之后发现有一个bug。用的话,需要修复一下bug。会增加额外工作,留作备选。报错如下
CROSSSLOT Keys in request don't hash to the same slot redis dump
另外,这个东西安装有点麻烦,还有安装ruby环境。安装ruby的环境与包管理工具的方法:
yum install rubygems
3 C工具:https://github.com/tanruixing88/redis-migrate-tool
该方法可以。并最后成功了。后边详述。另,这是唯品会工具的一个fork,说是唯品会的只支持3.0,这个支持高版本,见:
https://cco.xyz/post/redis-migrae-tool/
4 RDB与AOF方案:使用bgsave命令,已经修改配置文件等方法。
这是保底方案,是官方正规方法,并且一点可以成功。但是很显然更花时间。有额外的学习成本,也有额外的时间成本。
redis-migrate-tool的详细操作步骤
1 配置文件: 所有节点的IP + Port,包括slave和master
[source] type: redis cluster servers: - 10.1.0.12:6379 - 10.1.0.6:6379 - 10.1.0.24:6379 - 10.1.0.11:6379 - 10.1.0.5:6379 - 10.1.0.9:6379 - 10.1.0.8:6379 - 10.1.0.7:6379 - 10.1.0.13:6379 - 10.1.0.10:6379 [target] type: redis cluster servers: - 10.1.0.50:6379 - 10.1.0.46:6379 - 10.1.0.48:6379 - 10.1.0.47:6379 - 10.1.0.45:6379 - 10.1.0.51:6379 - 10.1.0.49:6379 - 10.1.0.19:6379 [common] listen: 0.0.0.0:8888
快速生成以上ip串的小技巧:
redis-cli -c cluster nodes |awk '{print $2}' |awk -F'@' '{print "- "$1}'
2 启动方法:
./redis-migrate-tool -c migrate.conf -o log -d
3 停止方法
使用下面的命令行进入管理界面:
redis-cli -h 127.0.0.1 -p 8888
然后执行shutdown命令。
迁移步骤:
1 新建一个全新的redis 集群,并确保集群建立成功,集群状态up。
2 配置 redis-migrate-tool工具的配置文件
3 启动工具,这个时候能观察到新group中的key书目在不断增加。直到超过旧集群的key总数。
这里需要说明的时候,因为旧group依然是业务在线的。所以key实际上处于有增有减的动态过程中。而迁移工具实际上做的时候一个不断copy的工作,
所以,新集群实际上是旧集群里所有key的累加结果。被删掉的旧集群上的key并不会被一起上新集群里删掉。
4 这里有两个假设,
1 迁移工具的迁移速度大于旧集群中key的新增速度。
2 业务系统必须容忍这样一直失败场景:刚存入的key,在小于迁移速度的时间内有可能获取失败。
在满足以上两个条件的前提下,进行第五步操作:
迁移业务系统:使用命令解绑旧的业务系统与redis 集群的绑定关系,绑定新的集群。
6 在第五步完成之后,可以观察到旧集群中的key数量将不在变化,没有新的key增加,也没有旧的key删除。
再观察迁移工具,发现全部的key迁移已经完成了。
这块时候可以停止迁移工具了。
7 删除旧的集群
8 (4)中提到的那些没有被删除的旧key,会在n天后超时自己删掉自己。
我的业务系统对每一个key丢进行了超时配置。不过即使没有这个附件条件,依然没有关系,我们可以通过一下方法来达到这个目的,
以使得我的方案更具有处理一般问题的普适性。
对所有可以,设置超时的方法:
redis-cli -c keys '*yourKEYWORD*' |xargs -l -I {} redis-cli -c set {} 123 ex 3
至此,数据热迁移完成。对业务无感知。
六 完
[classic_tong @ 20200321 https:////www.cnblogs.com/hugetong/p/12584107.html]
完。