[redis] redis在线热迁移的方案与记录

时间:2020-03-27
本文章向大家介绍[redis] redis在线热迁移的方案与记录,主要包括[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] 

完。

参考:https://yq.aliyun.com/articles/726005 

原文地址:https://www.cnblogs.com/hugetong/p/12584107.html