Redis 基础教程

Redis 命令

Redis 高级教程

Redis 笔记

original icon
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.knowledgedict.com/tutorial/redis-command-migrate.html

Redis MIGRATE 命令

Redis 键(Keys) Redis 键(Keys)


Redis MIGRATE 命令将 redis 中的 key 原子性地从当前实例传送(迁移)到目标实例的指定数据库上,一旦传送成功,相应的 key 保证会出现在目标实例上,而当前实例上的 key 会被删除。

命令格式

MIGRATE host port key|"" destination-db timeout [COPY] [REPLACE] [KEYS key [key ...]]

可用版本:>=2.6.0

时间复杂度:这个命令在源实例上实际执行 DUMP 命令和 DEL 命令,在目标实例上执行 RESTORE 命令,查看以上命令的文档可以看到详细的复杂度说明。key 数据在两个实例之间传输的复杂度为 O(n)。

MIGRATE 命令是一个原子操作,它在执行的时候会阻塞进行迁移的两个实例,直到以下任意结果发生:

  • 迁移成功
  • 迁移失败
  • 等待超时

MIGRATE 命令的内部实现是这样的,主要分为 3 个步骤:

  1. 它在当前实例对给定 key 执行 DUMP 命令,将它序列化,然后传送到目标实例;
  2. 目标实例再使用 RESTORE 对数据进行反序列化,并将反序列化所得的数据添加到数据库中;
  3. 当前实例就像目标实例的客户端那样,只要看到 RESTORE 命令返回 OK,它就会调用 DEL 命令删除自己数据库上的 key。

MIGRATE 命令需要在给定的时间规定内完成 IO 操作。如果在传送数据时发生 IO 错误,或者达到了超时时间,那么命令会停止执行,并返回一个特殊的错误 IO ERR。

当 IO ERR 出现时,有以下 2 种可能:

  • key 可能存在于两个实例。
  • key 可能只存在于当前实例。

唯一不可能发生的情况就是丢失 key,因此,如果一个客户端执行 MIGRATE 命令,并且不幸遇上 IO ERR 错误,那么这个客户端唯一要做的就是检查自己数据库上的 key 是否已经被正确地删除。

如果有其他错误发生,那么 MIGRATE 保证 key 只会出现在当前实例中(当然,目标实例的给定数据库上可能有和 key 同名的键,不过这和 MIGRATE 命令没有关系)。

命令参数

  • host:目标实例的 host。
  • port:目标实例的端口号。
  • key|"":传具体 key 表示迁移该 key;在 3.2 及更高版本中,可以结合空字符串("")和 KEYS 子句来指定要迁移的 key,并可以在 MIGRATE 的单个调用中对多个 key 进行流水线处理。
  • destination-db:目标实例的数据库。
  • timeout:指定当前实例和目标实例进行沟通的最大间隔时间,单位为毫秒。这说明操作并不一定要在 timeout 内完成,只是说数据传送的时间不能超过这个 timeout 值。
  • COPY:不移除源实例上的 key,3.0 及更高版本开始可用。
  • REPLACE:替换目标实例上已存在的 key,3.0 及更高版本开始可用。
  • KEYS 子句:如果 key 参数是一个空字符串,该命令将改为迁移遵循 KEYS 选项的所有键,参照如上 key|"" 的说明。3.0.6 及更高版本开始可用。

从 Redis 3.0.6开始,MIGRATE 支持新的批量迁移模式,该模式使用 pipeline 操作以在实例之间迁移多个 key,而不会产生往返时间延迟以及使用单个 MIGRATE 调用迁移每个 key 时的其他开销。

为了启用该功能,使用 KEYS 选项,并将普通键参数设置为空字符串。实际的键名将在 KEYS 参数后面提供。

命令返回值

MIGRATE 命令返回有 2 种情况:

  • 返回 OK,当迁移成功时。
  • 返回 NOKEY,如果在源实例中没有要迁移的 key,如 key 过期了,所以 NOKEY 不是一个错误。

示例

127.0.0.1:6379> SET mgr test
OK
127.0.0.1:6379> SET mgr1 test1
OK
127.0.0.1:6379> MIGRATE 127.0.0.1 6380 "" 0 2000 COPY KEYS mgr mgr1 # 批量迁移key
OK

127.0.0.1:6380> GET mgr
"test"
127.0.0.1:6380> GET mgr1
"test1"

127.0.0.1:6379> SET mgr1 test_replace
OK
127.0.0.1:6379> MIGRATE 127.0.0.1 6380 mgr1 0 2000 COPY REPLACE     # 单个key迁移且替换目标已存在的key
OK

127.0.0.1:6380> GET mgr1
"test_replace"

127.0.0.1:6379> MIGRATE 127.0.0.1 6380 mgr_nokey 0 2000 COPY        # 迁移不存在的key,返回NOKEY
NOKEY

Redis 键迁移

想将一个 Redis 的数据迁移到另一个 Redis 中,Redis 提供了三种方式来满足数据迁移的需求:

  • MOVE
  • DUMP+RESTORE
  • MIGRATE

MOVE 命令

Redis 支持多数据库,多数据库之间彼此在数据上是隔离的。move key db 就是把指定的键从源数据库迁移到目标数据库中。由于多数据库在生产环境中不建议使用,所以此命令很少使用到。MOVE 命令的更详细内容,参考 Redis MOVE 命令

DUMP+RESTORE 命令

DUMP+RESTORE 可以实现 Redis 不同实例之间的数据迁移。

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

整个迁移过程并非原子性的,而是通过客户端分布完成的。

迁移过程是开启了两个实例的 Redis 客户端,将源 Redis 序列化后的值放到目标 Redis 实例客户端进行操作,并不是在源 Redis 和目标 Redis 之间进行传输。