之前自搭建的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 json

# 读取JSON文件
with open('dump.json', 'r') as f:
data = json.load(f)

redis_commands = []

# 根据不同的类型生成对应的Redis命令
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)

# 将Redis命令写入文件
with open('redis_commands.txt', 'w') as f:
f.write("\n".join(redis_commands))

将python脚本与json文件放进同一个目录,然后执行。

1
python3 import.py

我们就看到了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"

执行命令