2

我有两个 Redis 实例(或两个各自的 dump.rdb 文件),我想将它们组合成一个带有两个 dbs 的实例,一个用于每个各自的初始实例。

我可以使用 MIGRATE 来做到这一点,但它仅在 Redis 2.6.0 中可用,我当前的 Redis 服务器不支持它。

4

3 回答 3

9

编辑

对于较新版本的 redis,此答案不再准确。由于历史原因留下了答案。


如果您愿意尝试一下二进制文件,您可以轻松地将两个 dump.rdb 文件合并为一个。

假设:

  1. 每个转储只有一个数据库 - 默认数据库
  2. 您使用的是 Redis 2.4.x,因此转储版本为 2 或 3

如果您在十六进制编辑器中打开文件,这是 RDB 文件的格式 -

REDIS000x FE 00 <actual data > FF

这里 -

  • 000x是 rdb 版本号。在您的情况下,它很可能是 0002 或 0003
  • FE是数据库选择器,00是数据库编号
  • <actual data>是当前数据库中的键值对。您可以将其视为当前目的的二进制 blob。
  • FF是文件中的最后一个字节,表示 rdb 文件的结尾

因此,要合并两个 rdb 文件,请执行以下操作 -

  1. 创建一个新的目标文件
  2. 复制除最后一个文件之外的第一个文件中的所有内容FF
  3. 复制两个字节FE 01以指示第二个数据库的开始
  4. 注意:如果您确定两个数据库没有重复的键,并且您想将它们组合成一个数据库,只需跳过FE 01上面提到的两个字节。
  5. 从第二个文件中,跳过前 11 个字节 - 即跳过REDIS000x FE 00
  6. 复制第二个文件的其余部分,包括最后一个字节FF

您现在可以将这个新的 dump.rdb 复制到 redis 中的相应目录并重新启动。

如果您有兴趣,这里是 redis 转储文件格式的完整文档,但是对于这个简单的用例,您不需要了解所有内容。

于 2012-04-10T10:18:42.050 回答
3

这是我用来将 4 个 Redis 服务器(运行 2.4.x)合并为 2 个的技术(我,两次,将 2 个单独的 Redis 实例(每个在 db0 中的数据)合并为 1 个包含两个单独的 dbs):

  1. 使新实例 Foo 成为您的实例 A 的从属(即编辑redis.conf和使用slaveof)。
  2. 一旦 Foo 从 A 完成同步,删除 slaveof 使其成为 master。所有数据都将在 db0 中。
  3. 使用redis-dump(Ruby 库,但具有命令行实用程序)导出或转储实例 B 中的所有数据。这将创建一个 JSON 文件。
  4. 如果数据在实例 B 的 db0 中,您现在需要编辑第 3 步生成的 JSON 文件。这是 b/c,您不想将 B 的数据导入 Foo 的 db0,它现在包含 A 的数据。
    • redis-dump 的格式包含每个键的源数据库;因此,您需要编辑文档以将 db 从 0 更改为其他值 - 1、2 等。
    • 我的 JSON 文件很大,所以我使用了 sed:sed -e 's/\"db\":0/\"db\":3/' orig.json > db_3.json
  5. 使用 redis-dump 的redis-load命令将包含实例 B 中数据的 JSON 文件导入到 Foo 中。
    • 如果您编辑了 JSON 文件并将数据库更改为不同的内容,例如 3,那么您需要将数据导入该数据库,即<new.json redis-load -u host:port -d 3
    • 如果您有足够的数据(我正在导入 GB),则可能需要数小时。您可以通过在与目标 Redis 实例 (Foo) 相同的框上运行此过程来加快速度。

现在您有一个 Redis 实例 (Foo),其中 A 的数据在 db0 中,B 的数据在 db1 中。

于 2012-06-28T18:33:10.107 回答
0

我遇到了很多麻烦,所以我创建了一个使用转储和恢复的 python 脚本。它将一个数据库序列化为一个字典对象并对其进行图片化。使用不同的开关加载 picled 文件并将数据上传到其他 redis 实例。

https://gist.github.com/romanmah/9664407

于 2014-03-20T14:04:52.253 回答