不能。RDB是Redis自研二进制格式,Python标准库无法直接解析;硬解易出错且版本兼容性差;推荐用redis-rdb-tools或redis-cli --rdb导出分析。

Redis RDB 文件能直接用 Python 读取吗?
不能。RDB 是 Redis 自研的二进制格式,不是 JSON 或 CSV,Python 标准库无法直接解析。硬解协议容易出错,且不同 Redis 版本(如 6.x 和 7.x)的 RDB 格式有细微差异,字段长度、压缩标记、辅助字段顺序都可能变化。
推荐做法是复用 Redis 官方维护的解析能力:
- 用
redis-cli --rdb <dump.rdb>导出为可读文本(仅限非压缩、非加密的 RDB),适合快速查看键类型和过期时间,但不带值内容(--rdb默认只输出元信息) - 更可靠的是使用
redis-rdb-tools:它用 Python 实现了完整 RDB 解析器,支持 v6/v7,能提取 key、type、db、expire、value(包括 string/list/set/zset/hash 的结构化表示) - 安装:
pip install redis-rdb-tools;基础分析命令:rdb -c memory dump.rdb(统计内存分布),rdb -c protocol dump.rdb > dump.txt(转成 RESP 协议格式,可被其他工具消费)
如何从 RDB 提取特定业务键并做聚合统计?
直接遍历全部 key 再用 Python 过滤效率低,且 redis-rdb-tools 的 -f 参数支持正则匹配,能跳过无关 key,大幅减少内存占用。
例如,想统计所有以 user:profile: 开头的 hash 类型 key 的字段数:
rdb -c protocol -f '^user:profile:[0-9]+$' dump.rdb | \
awk '/^$hash$/ {in_hash=1; next} /^$end$/ {in_hash=0; print count; count=0; next} in_hash && /^\$/ {count++}'
关键点:
-
-f必须写完整正则,开头加^、结尾加$,避免误匹配(比如user:profile:123:ext不会被捕获) -
rdb -c protocol输出的是 RESP 格式,每行一个元素,$hash表示 hash 类型开始,$end表示结束,中间每行$xxx是字段或值 - 如果需要真正结构化处理(比如计算每个 user profile 的 age 字段平均值),建议用
rdb -c json输出 JSON 流,再用jq或 Python 的jsonlines库逐行解析
RDB 含有 LZF 压缩或启用了 RDB checksum 怎么办?
redis-rdb-tools 默认支持 LZF 解压(依赖 lzf Python 包),但不校验 checksum —— 这反而是好事:离线分析时,只要 RDB 主体能解出,checksum 失败(比如文件传输损坏但关键数据完好)不应中断流程。
若遇到报错 Unsupported RDB encoding: 14,说明 Redis 使用了新编码(如 v7.0+ 的 LZ4 或 ZSTD),此时 redis-rdb-tools 当前版本(v0.4.0)尚不支持,必须降级处理:
- 用对应版本的
redis-server启动临时实例:redis-server --dbfilename dump.rdb --port 0 --save "" --appendonly no(禁用持久化,避免覆盖原文件) - 然后用
redis-cli -p <temp_port> --rdb /dev/stdout > dump.uncompressed.rdb导出未压缩 RDB - 再用
redis-rdb-tools处理这个新文件
注意:该方法要求本地有匹配的 Redis 二进制,且不能用于 AES 加密的 RDB(Redis 7.0+ 支持 RDB 加密,此时必须先用 redis-cli --rdb-decrypt 提供密码)。
离线分析时 value 被截断或乱码怎么办?
RDB 中的 string 值默认按原始字节存储,没有字符集声明。如果你的业务存的是 UTF-8 字符串,但部分 key 存了二进制 protobuf 或 msgpack,直接当字符串 decode 就会报 UnicodeDecodeError 或显示乱码。
安全做法是分类型处理:
- 对
string类型,先用try: val.decode('utf-8') except UnicodeDecodeError: val = f"<binary:{len(val)} bytes>" - 对
hash/zset等复合类型,其 field 和 value 都可能混用编码,需单独判断;redis-rdb-tools的 JSON 输出里,二进制值会 base64 编码(如"value": "YmFy"),解码后才是原始字节 - 如果知道某类 key 固定存 JSON,可在解析后加一层
json.loads(),但务必包try/except,避免单个坏数据中断整个流程
真正棘手的是压缩值(如业务层用 gzip 存的 string)——RDB 本身不感知这一层,你得在分析脚本里约定解压逻辑,否则永远看到一串不可读字节。


















