Redis15-redis集群间的数据迁移
1、准备两个redis集群
- redis版本是:redis-5.0.14
1、查看新旧集群的节点(redis实例)
- 注意,旧集群在一台机器上,新集群在三台机器上。
//旧集群 ]# redis-cli -h 10.1.1.13 -p 8001 -a admin 10.1.1.13:8001> cluster nodes 0d16af555f59c703e06faf1ed35228c6fd379ecd 10.1.1.13:8001@18001 myself,master - 0 1675152310000 1 connected 0-5460 deed95db95df42100d4736783af101483531b01e 10.1.1.13:8002@18002 master - 0 1675152309000 2 connected 5461-10922 fb8cfed07e8af1a3aaefd5967312d1c54a78e963 10.1.1.13:8003@18003 master - 0 1675152309899 3 connected 10923-16383 af0fbd9877e11e78572c7c01a54ef51459f37ed6 10.1.1.13:8004@18004 slave fb8cfed07e8af1a3aaefd5967312d1c54a78e963 0 1675152310916 4 connected 7c23a23e57d404c024a2dc3a633768cdf9766cdc 10.1.1.13:8005@18005 slave 0d16af555f59c703e06faf1ed35228c6fd379ecd 0 1675152309000 5 connected 7e7823a8948d421c1176a07ef09bf7b0384c417f 10.1.1.13:8006@18006 slave deed95db95df42100d4736783af101483531b01e 0 1675152308000 6 connected //新集群 ]# redis-cli -h 10.1.1.11 -p 7001 -a admin 10.1.1.11:7001> cluster nodes 471bfcf3bcdfc0a794eee25c547bec6e4dcb1fb7 10.1.1.11:7001@17001 myself,master - 0 1675152342000 1 connected 0-5460 7b91a5eaf084ad566c182dc91269ec37c16e7cb4 10.1.1.12:7001@17001 master - 0 1675152342374 3 connected 5461-10922 a5a7f7bc528d509af1b9df8a0926ec5999706552 10.1.1.13:7001@17001 master - 0 1675152343000 5 connected 10923-16383 d0a1f380a20add265f08cf2ba6ff0e0510df3ce0 10.1.1.11:7002@17002 slave a5a7f7bc528d509af1b9df8a0926ec5999706552 0 1675152343399 5 connected a36f84864e5ee8d947d911f88e796d085783b80f 10.1.1.12:7002@17002 slave 471bfcf3bcdfc0a794eee25c547bec6e4dcb1fb7 0 1675152344420 4 connected 1b62eb8bd0e71f4e03840cc522806bf4af98ca88 10.1.1.13:7002@17002 slave 7b91a5eaf084ad566c182dc91269ec37c16e7cb4 0 1675152344000 6 connected
2、向旧集群中写入模拟数据
]# redis-cli -h 10.1.1.13 -p 8001 -a admin -c 10.1.1.13:8001> set hh1 hh1 -> Redirected to slot [5691] located at 10.1.1.13:8002 OK 10.1.1.13:8002> set hh2 hh2 OK 10.1.1.13:8002> set hh3 hh3 -> Redirected to slot [13945] located at 10.1.1.13:8003 OK 10.1.1.13:8003> set hh4 hh4 -> Redirected to slot [1694] located at 10.1.1.13:8001 OK
2、使用dump.rdb文件实现数据迁移
- 适用于将数据迁移到一个全新的redis集群。
- 迁移前要停止向旧集群中写数据,以避免数据丢失。
- 迁移后要将所有的应用指向新的redis集群。
1、关闭新集群的所有节点
//(1)先停止所有从节点 ]# systemctl stop redis-7002.service //(2)再停止所有主节点 ]# systemctl stop redis-7001.service
2、持久化旧集群的数据
- 在旧集群上,依次持久化所有主节点的数据。以8001节点为例,操作如下。
//(1)持久化数据 ]# redis-cli -h 10.1.1.13 -p 8001 -a admin bgsave //(2)查看bgsave命令是否已经执行完成(0是已经完成) ]# redis-cli -h 10.1.1.13 -p 8001 -a admin info Persistence | grep 'rdb_bgsave_in_progress' rdb_bgsave_in_progress:0
3、检查旧集群的dump.rdb文件
- 在旧集群上,依次查看其所有主节点的持久化文件。以8001节点为例,操作如下。
//(1)查看dump.rdb文件的目录 ]# redis-cli -h 10.1.1.13 -p 8001 -a admin config get dir 1) "dir" 2) "/data/redis-data-8001" //(2)检测RDB文件 ]# redis-check-rdb /data/redis-data-8001/dump.rdb
4、迁移数据
- 将旧集群的主节点的持久化文件dump.rdb对应的迁移到新集群的主节点的数据目录中(对应是指数据槽要对应)
]# scp /data/redis-data-8001/dump.rdb root@10.1.1.11:/data/redis-data-7001/ ]# scp /data/redis-data-8002/dump.rdb root@10.1.1.12:/data/redis-data-7001/ ]# scp /data/redis-data-8003/dump.rdb root@10.1.1.13:/data/redis-data-7001/
5、重新启动新集群的所有节点
- 在新集群上,启动主节点前,要关闭AOF数据持久化。以一台机器为例,操作如下。
]# vim /usr/local/redis-7001/conf/redis-7001.conf appendonly no
- 在新集群上,启动主节点时,其的数据目录中不能有appendonly.aof文件。以一台机器为例,操作如下。
]# rm -f /data/redis-data-7001/appendonly.aof
- 启动所有节点
//(1)先启动所有主节点 ]# systemctl start redis-7001.service //(2)再启动所有从节点 ]# systemctl start redis-7002.service
6、核对新旧集群的keys的数量是否一致
- 注意,两种方法都只能查询当前redis实例。
//dbsize显示当前库key的数量 10.1.1.12:7001> dbsize (integer) 2 //info keyspace可以看到所有库key的数量 10.1.1.12:7001> info keyspace # Keyspace db0:keys=2,expires=0,avg_ttl=0
7、重新开启新集群的AOF持久化
- 重新开启新集群各主节点的AOF持久化。以一台机器为例,操作如下。
]# redis-cli -h 10.1.1.11 -p 7001 -a admin config set appendonly yes ]# redis-cli -h 10.1.1.11 -p 7001 -a admin config rewrite
3、使用appendonly.aof文件实现数据迁移
1、持久化旧集群的数据
- 在旧集群上,依次持久化所有主节点的数据。以8001节点为例,操作如下。
//(1)关闭混合持久化(如果不关闭混合持久化,就要向迁移RDB一样迁移数据) ]# redis-cli -h 10.1.1.13 -p 8001 -a admin config set aof-use-rdb-preamble no //(2)持久化数据 ]# redis-cli -h 10.1.1.13 -p 8001 -a admin bgrewriteaof //(2)查看bgrewriteaof命令是否已经执行完成(0是已经完成) ]# redis-cli -h 10.1.1.13 -p 8001 -a admin info Persistence | grep 'aof_rewrite_in_progress' aof_rewrite_in_progress:0
2、检查旧集群的appendonly.aof文件
- 在旧集群上,依次查看其所有主节点的持久化文件。以8001节点为例,操作如下。
//(1)查看appendonly.aof文件的目录 ]# redis-cli -h 10.1.1.13 -p 8001 -a admin config get dir 1) "dir" 2) "/data/redis-data-8001" //(2)修复AOF文件,修复后使用diff-u对比数据的差异 ]# redis-check-aof --fix /data/redis-data-8001/appendonly.aof
3、迁移数据
- 将旧集群的主节点的持久化文件dump.rdb对应的迁移到新集群的主节点的中(对应是指数据槽要对应)
]# redis-cli -h 10.1.1.11 -p 7001 -a admin --pipe < /data/redis-data-8001/appendonly.aof ]# redis-cli -h 10.1.1.12 -p 7001 -a admin --pipe < /data/redis-data-8002/appendonly.aof ]# redis-cli -h 10.1.1.13 -p 7001 -a admin --pipe < /data/redis-data-8003/appendonly.aof
4、使用redis-shake工具实现数据迁移
4.1、redis-shake介绍
- 使用文档:https://github.com/alibaba/RedisShake/wiki
- redis-shake支持三种数据迁移模式:sync、restore 和 scan:
- sync模式:数据迁移
- 将某个Redis实例的数据实时迁移至其它Redis。(单机到单机、单机到集群或集群到集群)
- 如果源redis是集群,要启动多个Redis-Shake,从不同的redis实例中拉取数据,同时源端不能开启move slot功能。
- 支持全量同步和增量同步,增量同步在全量同步完成后自动开始。
- restore模式:从dump.rdb恢复数据
- 将Redis的备份文件(RDB文件)中的数据恢复到某个Redis(可以是单机也可以是集群)。
- scan模式:数据迁移
- 如果禁用了Redis的PSync命令,可以使用该模式进行数据迁移
- sync模式:数据迁移
- redis-shake的基本原理就是模拟一个从节点加入源redis集群,首先进行全量拉取并回放,然后进行增量的拉取(通过psync命令)。
4.2、安装redis-shake
1、安装redis-shake
- (1)下载:https://github.com/alibaba/RedisShake/releases/download/v3.1.5/redis-shake-linux-amd64.tar.gz
- (2)安装redis-shake,解压就可用
]# mkdir redis-shake ]# tar zvfx redis-shake-linux-amd64.tar.gz -C redis-shake
2、目录架构
]# tree redis-shake1 redis-shake1 ├── cluster_helper │ ├── cluster_helper.py │ ├── launcher.py │ └── requirements.txt ├── filters │ ├── aliyun.lua │ ├── aws.lua │ ├── key_prefix.lua │ ├── print.lua │ ├── skip_scripts.lua │ └── swap_db.lua ├── redis-shake #命令 ├── restore.toml #配置文件 ├── scan.toml #配置文件 └── sync.toml #配置文件
3、三种配置文件
- restore.toml配置文件常用指令
type = "restore" [source] #redis的版本号, such as 2.8, 4.0, 5.0, 6.0, 6.2, 7.0, ... version = 5.0 #dump.rdb文件的路径。绝对路径或相对路径。注意,相对路径是相对于dir。 rdb_file_path = "dump.rdb" [target] #redis的版本号, such as 2.8, 4.0, 5.0, 6.0, 6.2, 7.0, ... version = 5.0 #目标redis的模式:standalone或cluster type = "standalone" #当目标redis是集群模式时,也只写其中一个节点的地址。redis-shake会通过'cluster nodes'命令获取其他节点。 address = "127.0.0.1:6379" #如果不需要身份验证,则为空 password = ""
- scan.toml配置文件常用指令
type = "scan" [source] #redis的版本号, such as 2.8, 4.0, 5.0, 6.0, 6.2, 7.0, ... version = 5.0 #源redis address = "127.0.0.1:6379" #如果不需要身份验证,则为空 password = "" [target] #redis的版本号, such as 2.8, 4.0, 5.0, 6.0, 6.2, 7.0, ... version = 5.0 #目标redis的模式:standalone或cluster type = "standalone" #当目标redis是集群模式时,也只写其中一个节点的地址。redis-shake会通过'cluster nodes'命令获取其他节点。 address = "127.0.0.1:6380" #如果不需要身份验证,则为空 password = ""
- sync.toml配置文件常用指令
type = "sync" [source] #redis的版本号, such as 2.8, 4.0, 5.0, 6.0, 6.2, 7.0, ... version = 5.0 #源redis address = "127.0.0.1:6379" #如果不需要身份验证,则为空 password = "" #当source是ElastiCache时使用 elasticache_psync = "" [target] #redis的版本号, such as 2.8, 4.0, 5.0, 6.0, 6.2, 7.0, ... version = 5.0 #目标redis的模式:standalone或cluster type = "standalone" #当目标redis是集群模式时,也只写其中一个节点的地址。redis-shake会通过'cluster nodes'命令获取其他节点。 address = "127.0.0.1:6380" #如果不需要身份验证,则为空 password = ""
4.3、使用restore模式实现数据迁移
1、持久化旧集群的数据
- 在旧集群上,依次持久化所有主节点的数据。以8001节点为例,操作如下。
//(1)持久化数据 ]# redis-cli -h 10.1.1.13 -p 8001 -a admin bgsave //(2)查看bgsave命令是否已经执行完成(0是已经完成) ]# redis-cli -h 10.1.1.13 -p 8001 -a admin info Persistence | grep 'rdb_bgsave_in_progress' rdb_bgsave_in_progress:0
2、检查旧集群的dump.rdb文件
- 在旧集群上,依次查看其所有主节点的持久化文件。以8001节点为例,操作如下。
//(1)查看dump.rdb文件的目录 ]# redis-cli -h 10.1.1.13 -p 8001 -a admin config get dir 1) "dir" 2) "/data/redis-data-8001" //(2)检测RDB文件 ]# redis-check-rdb /data/redis-data-8001/dump.rdb
3、迁移数据
- 将旧集群的主节点的持久化文件dump.rdb对应的迁移到新集群的主节点的数据目录中(对应是指数据槽要对应)。以迁移8001节点的数据为例,操作如下。
- (1)修改restore.toml文件
]# cat ./redis-shake/restore.toml type = "restore" [source] version = 5.0 rdb_file_path = "/data/redis-data-8001/dump.rdb" #将该dump.rdb中的数据迁移到其他redis中 [target] type = "cluster" version = 5.0 address = "10.1.1.11:7001" #目标是集群,也只需一个redis实例 username = "" password = "admin" tls = false [advanced] dir = "data" ncpu = 3 pprof_port = 0 metrics_port = 0 log_file = "redis-shake.log" log_level = "info" # debug, info or warn log_interval = 5 # in seconds rdb_restore_command_behavior = "rewrite" # panic, rewrite or skip pipeline_count_limit = 1024 target_redis_client_max_querybuf_len = 1024_000_000 target_redis_proto_max_bulk_len = 512_000_000
- (2)进行数据迁移,将dump.rdb中的数据添加到新集群中
]# ./redis-shake/redis-shake ./redis-shake/restore.toml
4.4、使用sync模式实现数据迁移
- 不能在同一个目录启动多个redis-shake,因为redis-shake会在本地存储临时文件,多个redis-shake之间的临时文件会干扰。正确做法是建立多个目录,并cd进该目录,然后再启动。
- 如果源redis是集群,要为每个redis实例都创建一个redis-shake服务,进行实时数据同步。
1、为每一个redis实例都创建一个redis-shake
- 以8001节点为例,操作如下。
]# mkdir redis-shake-8001 ]# tar zvfx redis-shake-linux-amd64.tar.gz -C redis-shake-8001
2、修改配置文件sync.toml
- 以8001节点为例,操作如下。
- 将旧集群的8001实例中的数据迁移到新集群中。
]# cat redis-shake-8001/sync-8001.toml type = "sync" [source] version = 5.0 address = "10.1.1.13:8001" #一个源redis实例 username = "" password = "admin" #源redis的密码 tls = false elasticache_psync = "" [target] type = "cluster" #表示目标是一个redis集群 version = 5.0 address = "10.1.1.11:7001" #如果目标redis是一个集群,也只需要写集群中的一个节点即可,其他的节点会自动获取 username = "" password = "admin" #目标redis的密码 tls = false [advanced] dir = "data" #临时文件目录,在启动redis-shake时的当前目录中 ncpu = 4 pprof_port = 0 metrics_port = 0 log_file = "redis-shake.log" log_level = "info" log_interval = 5 rdb_restore_command_behavior = "rewrite" pipeline_count_limit = 1024 target_redis_client_max_querybuf_len = 1024_000_000 target_redis_proto_max_bulk_len = 512_000_000
3、启动redis-shake
- 以8001节点为例,操作如下。
//(1)一定要cd进相应的目录中再启动服务 ]# cd redis-shake-8001/ //(2)启动服务 ]# nohup ./redis-shake ./sync.toml-8001 &
1
# #