【问题标题】:Combine two Redis instances into a single instance with two dbs将两个 Redis 实例合并为一个具有两个 dbs 的实例
【发布时间】:2023-04-06 07:56:01
【问题描述】:

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

我可以使用 MIGRATE 执行此操作,但它仅在 Redis 2.6.0 中可用,我当前的 Redis 服务器不支持。

【问题讨论】:

    标签: redis


    【解决方案1】:

    编辑

    对于较新版本的 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 中的相应目录并重新启动。

    如果您有兴趣,here is complete documentation of redis dump file format,但对于这个简单的用例,您不需要了解所有内容。

    【讨论】:

    • 这个答案太旧了,可能会误导。现在redis转储文件不再以FF结尾,而是一个字节的“FF”和一个八字节的校验和。注意不要错误地截断 rdb 文件。
    【解决方案2】:

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

    1. 使新实例 Foo 成为实例 A 的从属(即编辑 redis.conf 并使用 slaveof)。
    2. 一旦 Foo 从 A 完成同步,删除 slaveof 使其成为主控。所有数据都将在 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 文件并将 db 更改为不同的值,例如 3,那么您需要将数据导入该 db,即 <new.json redis-load -u host:port -d 3
      • 如果您有足够的数据(我正在导入 GB),可能需要几个小时。您可以通过在与目标 Redis 实例 (Foo) 相同的盒子上运行此过程来加快速度。

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

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-05-27
        • 1970-01-01
        • 1970-01-01
        • 2018-02-15
        • 1970-01-01
        相关资源
        最近更新 更多