# 一:前言
迁移键功能非常重要,因为有时候我们只想把部分数据由一个 Redis 迁移到另一个 Redis(例如从生产环境迁移到测试环境),Redis 发展历程中提供了 move
、dump + restore
、migrate
三组迁移键的方法,它们的实现方式以及使用的场景不太相同。
# 二:迁移键
# 2.1 move
move key db
move命令用于在Redis内部进行数据迁移,Redis内部可以有多个数据库,彼此在数据上是相互隔离的,move key db
就是把指定的键从源数据库移动到目标数据库中,多数据库功能不建议在生产环境使用
# 2.2 dump+restore
dump key
restore key ttl value
2
dump+restore 可以实现在不同的 Redis 实例之间进行数据迁移的功能,整个迁移的过程分为两步:
- 在源 Redis 上,
dump
命令会将键值序列化,格式采用的是 RDB 格式。 - 在目标 Redis 上,
restore
命令将上面序列化的值进行复原,其中 ttl 参数代表过期时间,如果ttl=0
代表没有过期时间。
有关dump+restore有两点需要注意:
- 整个迁移过程并非原子性的,而是通过客户端分步完成的;
- 迁移过程是开启了两个客户端连接,所以dump的结果不是在源Redis和目标Redis之间进行传输。
例子
- 在源Redis上执行dump:
> set hello world
OK
> dump hello
"\x00\x05world\x06\x00\x8f<T\x04%\xfcNQ"
2
3
4
- 在目标Redis上执行restore:
> get hello
OK
> restore hello 0 "\x00\x05world\x06\x00\x8f<T\x04%\xfcNQ"
OK
> get hello
"world"
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点不太相同:
- 整个过程是原子执行的,不需要在多个 Redis 实例上开启客户端的,只需要在源Redis 上执行 migrate 命令即可;
- migrate 命令的数据传输直接在源Redis 和目标Redis 上完成的;
- 目标 Redis 完成 restore 后会发送OK给源Redis,源Redis 接收后会根据 migrate 对应的选项来决定是否在源Redis 上删除对应的键。
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
2
情况二:源Redis 和目标Redis 都有键hello:
> get hello
"world"
> get hello
"redis"
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
2
3
4
情况三:源Redis 没有键hello。如下所示,此种情况会收到 nokey
的提示:
> migrate 127.0.0.1 6380 hello 0 1000
NOKEY
2
例子,多个键
## 源Redis批量添加多个键
> mset key1 value1 key2 value2 key3 value3
OK
> migrate 127.0.0.1 6380 "" 0 5000 keys key1 key2 key3
OK
2
3
4
5
# 三:异同点
move、dump+restore、migrate三个命令比较
命令 | 作用域 | 原子性 | 支持多个键 |
---|---|---|---|
move | Redis 实例内部 | 是 | 否 |
dump + restore | Redis 实例之间 | 否 | 否 |
migrate | Redis 实例之间 | 是 | 是 |
# 四:参考文献
- 《Redis深度历险:核心原理和应用实践 - 钱文品》
- 《Redis 开发与运维 - 付磊、张益军》
- 官方文档 (opens new window)