将两个Redis实例合并为一个包含两个dbs的实例

时间:2012-04-10 05:19:14

标签: redis

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

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

3 个答案:

答案 0 :(得分:9)

修改

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


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

假设:

  1. 每个转储只有一个数据库 - 默认数据库
  2. 您使用的是Redis 2.4.x,因此转储版本为2或3
  3. 如果在十六进制编辑器中打开文件,则这是RDB文件的格式 -

    REDIS000x FE 00 <actual data > FF

    这里 -

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

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

    1. 创建新的目标文件
    2. 复制除最后一个FF
    3. 之外的第一个文件中的所有内容
    4. 复制两个字节FE 01以指示第二个数据库的开始
    5. 注意:如果您确定这两个数据库没有重复的密钥,并且您希望将它们组合到一个数据库中,则只需跳过上面提到的两个字节FE 01
    6. 从第二个文件中跳过前11个字节 - 即跳过REDIS000x FE 00
    7. 复制第二个文件的其余部分,包括最后一个字节FF
    8. 现在可以将这个新的dump.rdb复制到redis中的相应目录并重新启动。

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

答案 1 :(得分:3)

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

  1. 将新实例Foo作为实例A的奴隶(即编辑redis.conf并使用slaveof)。
  2. 一旦Foo完成从A同步,删除slaveof使其成为主。所有数据都将在db0中。
  3. 使用redis-dump(Ruby库但具有命令行util)来导出或转储来自实例B的所有数据。这将创建一个JSON文件。
  4. 如果数据在实例B中的db0中,您现在需要编辑步骤#3中生成的JSON文件。这是b / c你不想将B的数据导入到现在包含A数据的Foo的db0中。
    • redis-dump的格式包含每个密钥的源数据库;因此,您需要编辑文档以将数据库从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)相同的框上运行此过程来加快速度。
  6. 现在你有一个Redis实例(Foo),db1中的A数据和db1中的B数据。

答案 2 :(得分:0)

我遇到了很多麻烦,所以我创建了一个使用转储和恢复的python脚本。 它将一个db序列化为一个字典对象并将其打包。使用不同的交换机,将加载picled文件,并将数据上载到其他redis实例。

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