Redis 4.x系列(二十一):Redis 数据迁移(单实例/集群间迁移)

  可能因某些原因,需要移动或复制存储在 Redis 实例中的数据,就需要进行数据迁移。数据迁移是数据存储系统运维的一项非常重要的工作,更多概念见百度词条数据迁移

  Redis 的数据迁移主要依赖于主从复制数据持久化功能。

单实例之间数据迁移

单实例之间数据迁移主要用两种方式,分别是主从复制方式和持久化文件迁移方式。

主从复制迁移

采用主从复制方式,实现将主实例的数据复制到从实例,再将从实例提升为主实例。Redis 自带了主从复制的方案,详见Redis 4.x系列(十五):Redis 主从复制、调优和故障分析,下面是简单示例:

  1. 查看主实例的键空间
    1
    2
    3
    127.0.0.1:6379> info keyspace
    # Keyspace
    db0:keys=4,expires=0,avg_ttl=0
  2. 将当前服务器转变为指定服务器的从实例
    1
    2
    3
    4
    5
    6
    127.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
  3. 主从同步完成后,将从服务器提升为主服务器
    1
    2
    3
    //关闭复制功能,并将从服务器提升为主服务器
    127.0.0.1:6379> slaveof no one
    ok

持久化迁移方式

Redis 支持 RDB 持久化、AOF 持久化和混合持久化。可以使用 AOF 持久化文件进行数据迁移。
源实例和目标实例都开启 AOF 持久化,并开启混合持久化(设置 aof-use-rdb-preamble=yes),同时利用 AOF 和 RDB 的优点。

  1. 开启 AOF 和混合持久化
    1
    2
    3
    4
    5
    6
    7
    8
    9
    127.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
  2. 在源实例中重写 AOF
    1
    2
    127.0.0.1:6379> BGREWRITEAOF
    Background append only file rewriting started
  3. 停止目标实例
    1
    127.0.0.1:6379> shutdown
  4. 将源实例的 AOF 持久化文件拷贝目标实例的数据目录,并重启目录实例。

单实例与集群间数据迁移

单实例不足因业务发展,搭建了 Redis 集群,需要将单实例的数据迁移到集群来使用。

单实例与集群间数据迁移主要依赖持久化功能,把持久化的数据文件放到集群节点的数据目录完成迁移;还有种方式是使用redis-trip.rb脚本将单实例的数据导入到集群中。

下面总结了单实例数据向集群进行数据迁移的三种方式。

迁移后重新分片

复制-单节点迁移:把数据迁移到集群中的单个主节点,再重新分片。需要关六从实例,并将所有移到该主实例。

  1. 首先该集群中只有主实例且每个主实例没有从实例。出于迁移的目的,必须将所有的移到一个主实例。
  2. 启用 AOF 持久化,并设置混合持化化 aof-use-rdb-preamble=yes
  3. 在后台进行 AOF 重写,并查看持久化信息来检查是否已完成。
    1
    2
    3
    4
    5
    127.0.0.1:6379> BGREWRITEAOF

    127.0.0.1:6379> info persistence
    # Persistence
    aof_rewrite_in_progress:0
  4. 关闭拥有所有槽的主实例,将 AOF 文件复制到这个 Redis 实例的数据目录。
  5. 启动这个 Redis 实例,执行 info keyspace命令检查 AOF 文件是否已加载。
  6. 使用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脚本对集群节点数据进行修复。

  1. Redis 集群中的所有主节点已完成槽分配。
  2. 关闭集群中的一个节点,将 AOF 文件拷贝到该节点的数据目录,重启该节点。
  3. 使用redis-cli -c连接到集群,获取集群中其它节点的键,将会报错。
  4. 使用redis-trib.rbfix命令修复这个问题,然后在每个节点上执行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

  5. 重新获取键验证下,可以成功获取。

redis-trib.rb 脚本迁移

执行 redis-trib.rb import命令将源实例的数据导入到集群中:
> [root@192 src]# ./redis-trib.rb import –replace –from host1:port1 host2:port2

该方法内部实际使用了SCANMIGRATE命令从源实例向集群的一个节点复制键,内部执行了 DUMP, 并在目的实例中执行了 RESTORE。 通过计算键和槽的映射,redis-trib.rb 脚本直接把键发送到相应的槽,所以不需要重新定位键或进行槽分片。

MIGRATE 命令有两个选项,COPYREPLACE,用于决定这个命令的行为。关于MIGRATE的使用,请参阅译:MIGRATE

  • COPY:源实例中的数据中迁移后不会被删除。
  • REPLACE:会在迁移过程中覆盖目的实例中已有的键。

相关参考

Redis 数据迁移也有其它第三方的优秀工具,如来自 CodisLabsredis-port工具,**VIPShop(唯品会)**的 redis-migrate-tool工具。这两个工具都是开源的,可以从 GitHub 获取。

  1. Redis cluster tutorial
  2. Redis commands migrate
  3. CodisLabs/redis-port
  4. vipshop/redis-migrate-tool

Redis 4.x系列(二十一):Redis 数据迁移(单实例/集群间迁移)

http://blog.gxitsky.com/2018/12/22/Redis-21-data-migrate/

作者

光星

发布于

2018-12-22

更新于

2022-08-14

许可协议

评论