Redis集群间的无感数据迁移方案
一、迁移工具的安装与部署
1、获取RedisShake开源工具源码包
git clone https://github.com/alibaba/RedisShake
2、获取源码包后,会生成 RedisShake目录,进入RedisShake目录 运行软件编译命令
cd RedisShake
sh build.sh
(注意事项:在编译软件之前,需要将yum库update,更新完成后,需要用yum安装golong构建编译环境)
yum update
yum install -y golang
3、编译命令执行完成后,会在RedisShake目录下生成bin目录,说明编译、部署成功,此时进入bin目录可直接使用
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4djRulQs-1665630380472)(images/image-20220922145754453.png)]
二、Redis_shake的使用
1.基础用法
1>编辑bin目录下自带的sync.toml或restore.toml文件,或手动编辑自行创建后缀名为toml的迁移配置文件
2>构建并执行数据同步进程
格式:./bin/redis-shake xxxx.toml
例如:
./bin/redis-shake redis-shake.toml
# or
./bin/redis-shake xxxx.toml
2.检查数据同步状态,核对数据同步情况
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wtKyWT6Q-1665630380473)(images/image-20220922155725765.png)]
3、步骤流程
创建xx.toml配置文件 ---> 编写toml配置文件同步规则 ---> 执行redis-shake进程 ---> 核对数据同步情况
4、不同场景下toml文件的编写方式
单机->单机配置格式:
[source] #数据源配置
type = "sync"
address = "xxx.xxx.xxx.xxx:端口号"
password = "xxxxxxx"
[target] #目的源配置
type = "standalone" #这里type属性设置一定为standalone
address = "xxx.xxx.xxx.xxx:端口号"
password = "xxxxxxx"
单机->集群配置格式:
[source] #数据源配置
type = "sync"
address = "xxx.xxx.xxx.xxx:端口号"
password = "xxxxxxx"
[target] #目的源配置
type = "cluster"
address = "xxx.xxx.xxx:端口号" # 这里写集群中的任意一个节点的地址即可
password = "xxxxxxx"
集群->集群配置格式:
在 RedisShake V3系列版本,也就是当前使用最多的版本中,集群与集群之间的redis数据同步,统一在单机到集群的基础上,为每一个数据源端的redis master节点建立一个shake进程。
例:二个集群3主3从之间的数据同步只需为数据源端的每一个master建立一个shake进程,既需要建立3个单机至集群的shake进程用于二个Redis集群间的无感数据迁移与同步
5.二套Redis集群3主3从无感数据迁移示例
测试准备:
Redis集群-源:
redis-node-1 master 6381
redis-node-2 master 6382
redis-node-3 master 6383
redis-node-4 slave 6384
redis-node-5 slave 6385
redis-node-6 slave 6386
Redis集群-目的端:
redis-node-71 master 7381
redis-node-72 master 7382
redis-node-73 master 7383
redis-node-74 slave 7384
redis-node-75 slave 7385
redis-node-76 slave 7386
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7rGlZDlT-1665630380474)(images/image-20220922163654774.png)]
源端集群的数据情况:
redis-node-1 master 1330138条
redis-node-2 master 1330647条
redis-node-3 master 1330433条
对于上述集群的迁移,可以采用官方给出的源端每一个master一个shake的方式进行数据迁移,其原理是,无论那套Redis集群,其所有的master节点一定保存了当前集群的所有数据,故在数据迁移过程中,只需将其每一个master节点的数据写入新的集群即可完成迁移,这种方式下,只需要维护三个shake,而不需要集群与集群之间做复杂处理校验,大大降级集群数据传输间的难度,节省大量计算资源,且更加稳定、更加安全
接下来编写三个shake 的toml运行即可:
第一个 shake 的toml:
[source]
type="sync"
address="172.22.44.144:6381" #第一个源端master节点
[target]
type="cluster"
address="172.22.44.144:7381" #这里目的端的节点只需要随意写集群其中一个就可以了,我这里写法一一对应, #一个master对应另一个集群的master,方便后续核对数据
第二个 shake 的toml:
[source]
type="sync"
address="172.22.44.144:6382" #第二个源端master节点
[target]
type="cluster"
address="172.22.44.144:7382" #这里目的端的节点只需要随意写集群其中一个就可以了,我这里写法一一对应, #一个master对应另一个集群的master,方便后续核对数据
第三个 shake 的toml:
[source]
type="sync"
address="172.22.44.144:6383" #第三个源端master节点
[target]
type="cluster"
address="172.22.44.144:7383" #这里目的端的节点只需要随意写集群其中一个就可以了,我这里写法一一对应, #一个master对应另一个集群的master,方便后续核对数据
完成上述三个toml文件的编写后,就可以使用bin目录下的redis-shake脚本启动shake进程进行数据同步了
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-A0mHCP7D-1665630380474)(images/image-20220922171929270.png)]
启动完成后需要检查三个shake进程是否正常运行
当三个进程运行正常时,其底层先会进行一次全量同步,待全量同步完成后会进行增量同步,全量同步完成后,其三个shake不同停止,仍会继续运行来保持增量数据迁移,即实时同步,源集群增加数据,目标集群也会增加,虽然RedisShake能够进行实时数据同步,但是官方建议不能将其用做数据长时间同步场景,仅用于迁移就似乎即可,因为点位很难准确地接受包。故只至整个集群整个业务迁移完成,手动杀掉进程即可
观察日志,当所有master节点的shake全量数据同步完成后,我们需要进行数据核对,看看有没有数据丢失
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-53Nn8QDN-1665630380475)(images/image-20220922174025271.png)]
可以看到3主3从的二套Redis集群之前的数据迁移已经完全完成,且没有数据丢失,接下来还可以测一下,实时同步,我们去源端的6381节点上添加一条数据,去目的端去查询是否是实时同步
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LRrK1oNI-1665630380476)(images/image-20220922174444921.png)]
可以看到我们数据也是实时增量同步,这时业务全部切换完成后,只需将三个做增量的shake 进程杀了即可,故使用RedisShake做Redis迁移上云是目前最佳的技术方案
6.注意事项
NO1:如果RedisShake服务在外部,而Redis集群是使用K8s搭建的,需要开放源端所有K8s内部Redis master节点的地址端口访问映射,不然RedisShake无法连接Redis 集群master节点做数据迁移
NO2:如果RedisShake部署在K8s上,与二套Redis集群在同一套k8s环境中,则不需要开放外部访问
三、其他
1.版本详情
目前 redis-shake 有两个主版本:
redis-shake 2.x:功能最丰富,支持 rump 模式。存在已知问题,官方已不再维护,遇到问题可以尝试 3.0 版本。
redis-shake 3.x:全新 codebase,性能较佳。功能不断完善中,官方定期维护
2.数据过滤
redis-shake 支持使用 lua 脚本自定义过滤规则。redis-shake 可以使用以下命令启动:
./bin/redis-shake sync.toml filter/xxx.lua
目录中提供了以下一些过滤器模板filter
:
1. filter/print.lua:打印所有命令
2. filter/swap_db.lua:交换db0和db1的数据
自定义过滤规则
参考filter/print.lua
新建lua脚本,在lua脚本中实现过滤功能。该函数的参数是:
- id:命令编号
- is_base:是从dump.rdb文件中读取的命令
- group:命令组,见redis/src/commands下的描述文件
- cmd_name:命令名称
- 键:命令中的键
- 插槽:命令中的插槽
- db_id:数据库标识
- timestamp_ms:命令的时间戳,以毫秒为单位。当前版本不支持。
返回值为:
- 代码
- 0:允许该命令通过
- 1:该命令不允许通过
- 2:这个命令不应该出现,让redis-shake退出报错
- db_id:重定向的 db_id
stable/src/commands)
- cmd_name:命令名称
- 键:命令中的键
- 插槽:命令中的插槽
- db_id:数据库标识
- timestamp_ms:命令的时间戳,以毫秒为单位。当前版本不支持。
返回值为:
- 代码
- 0:允许该命令通过
- 1:该命令不允许通过
- 2:这个命令不应该出现,让redis-shake退出报错
- db_id:重定向的 db_id