Redis 迁移

12/3/2021 Redis

# 一:前言

迁移键功能非常重要,因为有时候我们只想把部分数据由一个 Redis 迁移到另一个 Redis(例如从生产环境迁移到测试环境),Redis 发展历程中提供了 movedump + restoremigrate 三组迁移键的方法,它们的实现方式以及使用的场景不太相同。

# 二:迁移键

# 2.1 move

move命令在Redis内部数据库之间迁移数据

move key db

move命令用于在Redis内部进行数据迁移,Redis内部可以有多个数据库,彼此在数据上是相互隔离的,move key db 就是把指定的键从源数据库移动到目标数据库中,多数据库功能不建议在生产环境使用

# 2.2 dump+restore

dump key 
restore key ttl value
1
2

dump+restore 可以实现在不同的 Redis 实例之间进行数据迁移的功能,整个迁移的过程分为两步:

  1. 在源 Redis 上,dump 命令会将键值序列化,格式采用的是 RDB 格式。
  2. 在目标 Redis 上,restore 命令将上面序列化的值进行复原,其中 ttl 参数代表过期时间,如果 ttl=0 代表没有过期时间。

dump+restore

有关dump+restore有两点需要注意:

  1. 整个迁移过程并非原子性的,而是通过客户端分步完成的;
  2. 迁移过程是开启了两个客户端连接,所以dump的结果不是在源Redis和目标Redis之间进行传输。

例子

  1. 在源Redis上执行dump:
> set hello world
OK
> dump hello
"\x00\x05world\x06\x00\x8f<T\x04%\xfcNQ"
1
2
3
4
  1. 在目标Redis上执行restore:
> get hello
OK
> restore hello 0 "\x00\x05world\x06\x00\x8f<T\x04%\xfcNQ"
OK
> get hello
"world"
1
2
3
4
5
6

# 2.3 migrate

migrate host port key|"" destination-db timeout [copy] [replace] [keys key [key ...]]

migrate 命令也是用于在 Redis 实例间进行数据迁移的,实际上 migrate 命令就是将 dump、restore、del 三个命令进行组合,从而简化了操作流程。migrate 命令具有原子性,而且从 Redis3.0.6 版本以后已经支持迁移多个键的功能,有效地提高了迁移效率。

实现过程和 dump+restore 基本类似,但是有3点不太相同

  1. 整个过程是原子执行的,不需要在多个 Redis 实例上开启客户端的,只需要在源Redis 上执行 migrate 命令即可;
  2. migrate 命令的数据传输直接在源Redis 和目标Redis 上完成的;
  3. 目标 Redis 完成 restore 后会发送OK给源Redis,源Redis 接收后会根据 migrate 对应的选项来决定是否在源Redis 上删除对应的键。

migrate

migrate 参数说明:

  • host:目标Redis 的IP地址;
  • port:目标Redis 的端口;
  • key|"":在 Redis3.0.6 版本之前,migrate 只支持迁移一个键,所以此处是要迁移的键,但 Redis3.0.6 版本之后支持迁移多个键,如果当前需要迁移多个键,此处为空字符串"";
  • destination-db:目标Redis 的数据库索引,例如要迁移到0号数据库,这里就写 0
  • timeout:迁移的超时时间(单位为毫秒);
  • [copy]:如果添加此选项,迁移后并不删除源键;
  • [replace]:如果添加此选项,migrate 不管目标 Redis 是否存在该键都会正常迁移进行数据覆盖;
  • ·[keys key[key...]]:迁移多个键,例如要迁移 key1、key2、key3,此处填写 keys key1 key2 key3

例子,源Redis 使用6379端口,目标Redis 使用6380端口,现要将源Redis 的键 hello 迁移到目标Redis 中,会分为如下几种情况:

情况一:源Redis 有键hello,目标Redis 没有:

> migrate 127.0.0.1 6380 hello 0 1000
OK
1
2

情况二:源Redis 和目标Redis 都有键hello:

> get hello
"world"
> get hello
"redis"
1
2
3
4

如果 migrate 命令没有加 replace 选项会收到错误提示,如果加了 replace 会返回 OK 表明迁移成功:

> migrate 127.0.0.1 6379 hello 0 1000
(error) ERR Target instance replied with error:BUSYKEY Target key name already
> migrate 127.0.0.1 6379 hello 0 1000 replace
OK
1
2
3
4

情况三:源Redis 没有键hello。如下所示,此种情况会收到 nokey 的提示:

> migrate 127.0.0.1 6380 hello 0 1000
NOKEY
1
2

例子,多个键

## 源Redis批量添加多个键
> mset key1 value1 key2 value2 key3 value3
OK
> migrate 127.0.0.1 6380 "" 0 5000 keys key1 key2 key3
OK
1
2
3
4
5

# 三:异同点

move、dump+restore、migrate三个命令比较

命令 作用域 原子性 支持多个键
move Redis 实例内部
dump + restore Redis 实例之间
migrate Redis 实例之间

# 四:参考文献

最后更新: 12/26/2023, 4:16:14 PM