MIGRATE

Posted winnerren

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MIGRATE相关的知识,希望对你有一定的参考价值。

MIGRATE host port key destination-db timeout [COPY] [REPLACE]

将key原子性地从当前实例传送到目标实例地指定数据库上,一旦传送成功,key保证会出现在目标实例上,而当前实例上地的key会被删除。

此命令是一个原子操作,在执行时会阻塞进行迁移的两个实例,until一下任意结果发生:迁移成功,迁移失败,等待超时。

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

timeout参数以毫秒为格式,指定当前实例和目标实例进行沟通的最大间隔时间。这说明操作并不一定要在timeout毫秒内完成,只是说数据传送的时间不能超过这个timeout数。

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

当IOERR出现时,有以下两种可能:

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

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

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

可选项:

  • copy:不移除源实例上的key。
  • REPLACE:替换目标实例上已存在的key。

版本:>=2.6.0

时间复杂度:

      这个命令在源实例上实际执行DUMP命令和DEL命令,在目标实例执行RESTORE命令,查看以上命令的文档可以看到详细的复杂度说明。

  key数据在两个实例之间传输的复杂度为O(N).

返回值:

      迁移成功时返回ok,否则返回相应的错误。

eg:

先启动两个redis实例,一个使用默认的6379端口,一个使用7777端口。

cd /usr/local/Cellar/redis/4.0.11
./redis-server &
[1] 87681



./redis-server --port 7777 &
[2] 87692

然后用客户端连上6379端口的实例,设置一个键,然后将它迁移到7777端口的实例上:

./redis-cli
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> KEYS *
(empty list or set)
127.0.0.1:6379> SET greeting "Hello from 6379 instance"
OK
127.0.0.1:6379> MIGRATE 127.0.0.1 7777 greeting 0 1000
OK
127.0.0.1:6379> EXISTS greeting     #迁移成功后key被删除
(integer) 0

使用另一个客户端,查看7777端口上的实例:

./redis-cli -p 7777

127.0.0.1:7777> GET greeting
"Hello from 6379 instance"


以上是关于MIGRATE的主要内容,如果未能解决你的问题,请参考以下文章

flask-migrate的使用

Django(21)migrate报错的解决方案

使用 rake db:migrate 迁移数据不会改变它

django迁移脚本

Flask 学习-15.flask-migrate数据迁移

Php artisan migrate - 语法错误,意外''(T字符串)