这篇文章说明了恢复丢失的Docker容器Redis数据的步骤:使用HDT3213/rdb工具导出JSON格式的Redis数据,通过Python脚本生成导入命令,和在Docker中执行数据恢复流程。
此内容根据文章生成,并经过人工审核,仅用于文章内容的解释与总结
投诉 之前自搭建的busuanzi发现很多数据都消失了,尝试恢复备份后发现key过期造成无法导入也无法使用。所以这个流程是我尝试恢复docker容器中redis数据的过程。
将redis数据导出为json 这里使用这个工具:https://github.com/HDT3213/rdb/
我是使用linux服务器来进行转换的,因为mac版不好使,win和linux都可用。
将在release 中下载的rdb-linux-amd64改名为rdb
后放入/usr/local/bin
目录
(记得rdb文件数据备份)
然后cd进放入rdb文件的目录,然后执行
1 rdb -c json -o dump.json dump.rdb
这个命令的意思就是将dump.rdb转为dump.json
我们就可以得到数据。
busuanzi是集合类型,样子例如:
1 2 3 4 5 6 7 8 [ {"db":0,"key":"hash","size":64,"type":"hash","hash":{"ca32mbn2k3tp41iu":"ca32mbn2k3tp41iu","mddbhxnzsbklyp8c":"mddbhxnzsbklyp8c"}}, {"db":0,"key":"string","size":10,"type":"string","value":"aaaaaaa"}, {"db":0,"key":"expiration","expiration":"2022-02-18T06:15:29.18+08:00","size":8,"type":"string","value":"zxcvb"}, {"db":0,"key":"list","expiration":"2022-02-18T06:15:29.18+08:00","size":66,"type":"list","values":["7fbn7xhcnu","lmproj6c2e","e5lom29act","yy3ux925do"]}, {"db":0,"key":"zset","expiration":"2022-02-18T06:15:29.18+08:00","size":57,"type":"zset","entries":[{"member":"zn4ejjo4ths63irg","score":1},{"member":"1ik4jifkg6olxf5n","score":2}]}, {"db":0,"key":"set","expiration":"2022-02-18T06:15:29.18+08:00","size":39,"type":"set","members":["2hzm5rnmkmwb3zqd","tdje6bk22c6ddlrw"]} ]
将json导入到docker容器中的redis python脚本import.py
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 import jsonwith open ('dump.json' , 'r' ) as f: data = json.load(f) redis_commands = [] for item in data: command_delete = f"DEL {item['key' ]} " redis_commands.append(command_delete) if item['type' ] == 'string' : command_add = f"SET {item['key' ]} {item['value' ]} " redis_commands.append(command_add) elif item['type' ] == 'list' : for val in item['values' ]: command_add = f"RPUSH {item['key' ]} {val} " redis_commands.append(command_add) elif item['type' ] == 'set' : command_add = f"SADD {item['key' ]} " + " " .join(item['members' ]) redis_commands.append(command_add) elif item['type' ] == 'hash' : for k, v in item['hash' ].items(): command_add = f"HSET {item['key' ]} {k} {v} " redis_commands.append(command_add) elif item['type' ] == 'zset' : for entry in item['entries' ]: command_add = f"ZADD {item['key' ]} {entry['score' ]} {entry['member' ]} " redis_commands.append(command_add) elif item['type' ] == 'stream' : for entry in item['entries' ]: for msg in entry['msgs' ]: fields = " " .join([f"{k} {v} " for k, v in msg['fields' ].items()]) command_add = f"XADD {item['key' ]} {msg['id' ]} {fields} " redis_commands.append(command_add) with open ('redis_commands.txt' , 'w' ) as f: f.write("\n" .join(redis_commands))
将python脚本与json文件放进同一个目录,然后执行。
我们就看到了redis_commands.txt
这个文件
移动txt文件到docker内部
1 docker cp redis_commands.txt <容器名>:/tmp/
授予权限
1 2 3 docker exec -it <容器名> /bin/sh chmod 644 /tmp/redis_commands.txt exit
执行导入
1 docker exec -it <容器名> /bin/sh -c "/usr/local/bin/redis-cli < /tmp/redis_commands.txt"