Redis 4.x系列(二十一):Redis 数据迁移(单实例/集群间迁移)
可能因某些原因,需要移动或复制存储在 Redis 实例中的数据,就需要进行数据迁移。数据迁移是数据存储系统运维的一项非常重要的工作,更多概念见百度词条数据迁移。
Redis 的数据迁移主要依赖于主从复制和数据持久化功能。
单实例之间数据迁移
单实例之间数据迁移主要用两种方式,分别是主从复制方式和持久化文件迁移方式。
主从复制迁移
采用主从复制方式,实现将主实例的数据复制到从实例,再将从实例提升为主实例。Redis 自带了主从复制的方案,详见Redis 4.x系列(十五):Redis 主从复制、调优和故障分析,下面是简单示例:
- 查看主实例的键空间
1
2
3127.0.0.1:6379> info keyspace
# Keyspace
db0:keys=4,expires=0,avg_ttl=0 - 将当前服务器转变为指定服务器的从实例
1
2
3
4
5
6127.0.0.1:6380> slaveof 127.0.0.1 6379
ok
127.0.0.1:6380> info keyspace
# Keyspace
db0:keys=4,expires=0,avg_ttl=0 - 主从同步完成后,将从服务器提升为主服务器
1
2
3//关闭复制功能,并将从服务器提升为主服务器
127.0.0.1:6379> slaveof no one
ok
持久化迁移方式
Redis 支持 RDB 持久化、AOF 持久化和混合持久化。可以使用 AOF 持久化文件进行数据迁移。
源实例和目标实例都开启 AOF 持久化,并开启混合持久化(设置 aof-use-rdb-preamble=yes),同时利用 AOF 和 RDB 的优点。
- 开启 AOF 和混合持久化
1
2
3
4
5
6
7
8
9127.0.0.1:6379> config set appendonly yes
OK
127.0.0.1:6379> config set aof-use-rdb-preamble yes
OK
127.0.0.1:6380> config set appendonly yes
OK
127.0.0.1:6380> config set aof-use-rdb-preamble yes
OK - 在源实例中重写 AOF
1
2127.0.0.1:6379> BGREWRITEAOF
Background append only file rewriting started - 停止目标实例
1
127.0.0.1:6379> shutdown
- 将源实例的 AOF 持久化文件拷贝目标实例的数据目录,并重启目录实例。
单实例与集群间数据迁移
单实例不足因业务发展,搭建了 Redis 集群,需要将单实例的数据迁移到集群来使用。
单实例与集群间数据迁移主要依赖持久化功能,把持久化的数据文件放到集群节点的数据目录完成迁移;还有种方式是使用redis-trip.rb脚本将单实例的数据导入到集群中。
下面总结了单实例数据向集群进行数据迁移的三种方式。
迁移后重新分片
复制-单节点迁移:把数据迁移到集群中的单个主节点,再重新分片。需要关六从实例,并将所有槽移到该主实例。
- 首先该集群中只有主实例且每个主实例没有从实例。出于迁移的目的,必须将所有的槽移到一个主实例。
- 启用 AOF 持久化,并设置混合持化化 aof-use-rdb-preamble=yes。
- 在后台进行 AOF 重写,并查看持久化信息来检查是否已完成。
1
2
3
4
5127.0.0.1:6379> BGREWRITEAOF
127.0.0.1:6379> info persistence
# Persistence
aof_rewrite_in_progress:0 - 关闭拥有所有槽的主实例,将 AOF 文件复制到这个 Redis 实例的数据目录。
- 启动这个 Redis 实例,执行 info keyspace命令检查 AOF 文件是否已加载。
- 使用redis-trib.rb reshard脚本对数据集重新分片。
redis-trib.rb是个 Ruby 脚本,可以通过ruby redis-trib.rb help来查看使用帮助。Redis 脚本依赖的 Ruby 的版本必须是 2.2.2版本及以上。
7. 在一个集群节点上使用CLUSTER NODES命令检查所有的槽是否已按预期的进行了分片。
8. 也可向集群的每个主节点发送DBSIZE命令统计所有键的数量总,与数据在单实例时使用info keyspace得到的键总数比较,来确定数据迁移是否成功。
9. 最后,为每个主节点添加从节点作为备份。
迁移后修复数据槽
复制-多节点修复:将持久化 AOF
文件拷贝到集群节点的数据目录,获取位于集群其它节点上的数据会报错,通过 redis-trib.rb
脚本对集群节点数据进行修复。
- Redis 集群中的所有主节点已完成槽分配。
- 关闭集群中的一个节点,将 AOF 文件拷贝到该节点的数据目录,重启该节点。
- 使用
redis-cli -c
连接到集群,获取集群中其它节点的键,将会报错。 - 使用
redis-trib.rb
的fix
命令修复这个问题,然后在每个节点上执行dbsize
命令。[root@192 src]# ./redis-trib.rb fix 192.168.1.100:6379
[root@192 src]# ./redis-trib.rb call 192.168.1.100:6379 dbsize - 重新获取键验证下,可以成功获取。
redis-trib.rb 脚本迁移
执行 redis-trib.rb import命令将源实例的数据导入到集群中:
> [root@192 src]# ./redis-trib.rb import –replace –from host1:port1 host2:port2
该方法内部实际使用了SCAN
和MIGRATE
命令从源实例向集群的一个节点复制键,内部执行了 DUMP
, 并在目的实例中执行了 RESTORE
。 通过计算键和槽的映射,redis-trib.rb 脚本直接把键发送到相应的槽,所以不需要重新定位键或进行槽分片。
MIGRATE 命令有两个选项,COPY 和 REPLACE,用于决定这个命令的行为。关于MIGRATE
的使用,请参阅译:MIGRATE
- COPY:源实例中的数据中迁移后不会被删除。
- REPLACE:会在迁移过程中覆盖目的实例中已有的键。
相关参考
Redis 数据迁移也有其它第三方的优秀工具,如来自 CodisLabs的redis-port
工具,**VIPShop(唯品会)**的 redis-migrate-tool
工具。这两个工具都是开源的,可以从 GitHub 获取。
Redis 4.x系列(二十一):Redis 数据迁移(单实例/集群间迁移)