redis:迁移键

迁移键功能非常重要,有时候我们只想把部分数据从一个redis迁移到另一个redis(例如从生产环境迁移到测试环境) redis发展过程中提供了move、dump+restore、migrate三组迁移键的方法,它们的实现场景和使用场景不一样
在这里插入图片描述

move

move key db
  • move命令只用于在redis内部进行迁移,redis内部有多个数据库,彼此之间在数据上是隔离的,move key db就是把指定的键从源数据库移动到目标数据库中
  • 使用建议:不建议在生产环境中使用,因此这个命令只需要了解即可

在这里插入图片描述

dump+restore

dump key
restore key ttl value

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

  • 在源redis上,dump命令会将键值序列化,格式采用的是rdb格式
  • 在模板redis上,restore命令会将上面序列化的值进行复原,采用ttl代表过期时间,如果ttl=0代表没有过期时间

注意:

  • 整个迁移过程不是原子性的,而是通过客户端分布完成的
  • 迁移过程中是开启了两个客户端连接,所以dump的结构不是在源redis和目标redis之间进行传输

演示

  1. 在源redis上执行dump
redis-source> set hello world
OK
redis-source> dump hello
"\x00\x05world\x06\x00\x8f<T\x04%\xfcNQ"
  1. 在模板redis上执行restore
redis-target> get hello
(nil)
redis-target> restore hello 0 "\x00\x05world\x06\x00\x8f<T\x04%\xfcNQ"
OK
redis-target> get hello
"world"

上面2步对应的伪代码如下:

Redis sourceRedis = new Redis("sourceMachine", 6379);  
Redis targetRedis = new Redis("targetMachine", 6379);  
targetRedis.restore("hello", 0, sourceRedis.dump(key)); 

在这里插入图片描述

migrate(推荐)

语法

migrate host port key|"" destination-db timeout [copy] [replace] [keys key1 key2 ...]
  • host:目标Redis的IP
  • port:目标Redis的端口
  • key|"":在Redis3.0.6版本之前,migrate只支持迁移一个键,所以此处是要迁移的键,但Redis3.0.6版本之后支持迁移多个键,如果当前需要迁移多个键,此处为空字符串""
  • destination-db:目标Redis的数据库索引,例如0号数据库,这里就写0
  • timeout:迁移的超时时间(毫秒)
  • [copy]:如果添加此选项,迁移后不删除源键
  • [replace]:替换目标实例上已存在的 key
  • [keys key1 key2…]:迁移多个键,例如要迁移key1、key2,此处填keys key1 key2

作用

  • 将key原子性的从当前实例传送到目标实例的指定数据库上,一旦传送成功,key保证会出现在目标实例上,而当前实例上的key会被删除
  • 这个命令是一个原子操作,它在执行的时候会阻塞进行迁移的两个实例,直到下面任意结果发生:
    • 迁移成功
    • 迁移失败
    • 等待超时
  • 实际上migrate命令就是将dump、restore、del三个命令进行组合,命令的内部实现是这样的:
    • 它在当前实例对给定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 命令没有关系)。

在这里插入图片描述

返回值

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

VS dump+restore

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

示例

实例

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

$ ./redis-server &
[1] 3557

...

$ ./redis-server --port 7777 &
[2] 3560

...

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

$ ./redis-cli

redis 127.0.0.1:6379> flushdb
OK

redis 127.0.0.1:6379> SET greeting "Hello from 6379 instance"
OK

redis 127.0.0.1:6379> MIGRATE 127.0.0.1 7777 greeting 0 1000
OK

redis 127.0.0.1:6379> EXISTS greeting                           # 迁移成功后 key 被删除
(integer) 0

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

$ ./redis-cli -p 7777

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

实例:

  • 源Redis有键hello,目标Redis没有
127.0.0.1:6380> migrate 127.0.0.1 6379 hello 0 1000
OK

实例:

  • 源Redis和目标Redis都有键hello
  • 如果命令没有加replace选项会收到错误提示,加了replace会返回OK表示成功
127.0.0.1:6379> migrate 127.0.0.1 6379 hello 0 1000
(error) ERR Target instance replied with error: BUSYKEY Target key name already

127.0.0.1:6379> migrate 127.0.0.1 6379 hello 0 1000 replace
OK

实例

  • 源Redis没有键hello
  • 这种情况使用migrate会收到nokey的提示:
127.0.0.1:6379> migrate 127.0.0.1 6380 hello 0 1000
NOKEY

实例

Redis3.0.6版本后迁移多个键

127.0.0.1:6379> migrate 127.0.0.1 6380 "" 0 5000 keys key1 key2 key3
OK
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python可以使用redis-py库来实现Redis数据迁移。以下是一个简单的示例代码,演示如何从一个Redis实例复制数据到另一个Redis实例。 首先,确保你已经安装了redis-py库。可以使用以下命令来安装: ``` pip install redis ``` 然后,使用以下代码实现数据迁移: ```python import redis def migrate_data(source_host, source_port, source_password, destination_host, destination_port, destination_password): # 连接源Redis source_redis = redis.Redis(host=source_host, port=source_port, password=source_password) # 连接目标Redis destination_redis = redis.Redis(host=destination_host, port=destination_port, password=destination_password) # 获取所有 keys = source_redis.keys() # 迁移数据 for key in keys: key_type = source_redis.type(key) if key_type == b'string': value = source_redis.get(key) destination_redis.set(key, value) elif key_type == b'list': values = source_redis.lrange(key, 0, -1) for value in values: destination_redis.rpush(key, value) elif key_type == b'set': values = source_redis.smembers(key) for value in values: destination_redis.sadd(key, value) elif key_type == b'zset': values = source_redis.zrange(key, 0, -1, withscores=True) for value, score in values: destination_redis.zadd(key, {value: score}) elif key_type == b'hash': items = source_redis.hgetall(key) for field, value in items.items(): destination_redis.hset(key, field, value) print("数据迁移完成!") # 示例用法 migrate_data('source_host', 6379, 'source_password', 'destination_host', 6379, 'destination_password') ``` 请确保替换示例中的源Redis和目标Redis的主机、端口和密码信息。这段代码会将源Redis中的所有和对应的值迁移到目标Redis中。 请注意,该示例代码只迁移了常见的Redis数据类型(字符串、列表、集合、有序集合和哈希)。如果你使用了其他数据类型,你需要相应地进行修改。 希望对你有所帮助!如有其他问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值