msgpack-python:比 JSON 更快的二进制序列化方案

做后端开发,数据序列化基本是绕不开的。JSON 用得多,主要是因为可读性好、生态成熟。但在性能敏感的场景,JSON 文本解析的开销和体积都是瓶颈。msgpack 走了一条不一样的路,用二进制格式来做这件事。

msgpack-python 就是这个格式在 Python 上的实现,目前 GitHub 上已经有 2,090 Star。它做的事情很直接:把 Python 对象序列化成紧凑的二进制数据,反序列化时再还原回来。和 JSON 相比,体积更小,速度更快,而且支持的数据类型也更丰富。

正文顶部截图

安装和基础用法

安装一条命令搞定:

pip install msgpack

API 设计和 json 模块几乎一致,上手没有门槛:

import msgpack
msgpack.packb([1, 2, 3])
msgpack.unpackb(_)

packbunpackb 是核心方法,dumpsloads 也支持,完全兼容习惯。packdump 可以写到文件对象,unpackload 从文件对象读取。如果你已经熟悉 JSON 的处理流程,换过来几乎不用改代码。

几个实用的特性

流式解包

处理大量数据时,一次性加载到内存不现实。Unpacker 支持流式处理,可以从一个数据流里逐个解包对象:

unpacker = msgpack.Unpacker(buf)
for unpacked in unpacker:
    print(unpacked)

这个设计在处理网络数据流或者大文件时特别有用,不需要等全部数据到齐才开始处理。

自定义类型支持

二进制格式的好处是扩展性强。msgpack 允许通过 defaultobject_hook 处理自定义类型,比如 datetime

def encode_datetime(obj):
    if isinstance(obj, datetime.datetime):
        return {'__datetime__': True, 'as_str': obj.strftime("%Y%m%dT%H:%M:%S.%f")}
    return obj

packed = msgpack.packb(data, default=encode_datetime)

反过来解包时用 object_hook 还原。除此之外,ExtType 机制支持更底层的扩展类型,用类型码加原始字节的方式封装任意数据,适合有特定序列化需求的场景。

安全默认

从 1.0 版本开始,msgpack 加了两个安全相关的默认值。max_buffer_size 默认限制在 100 MiB,防止恶意数据导致内存耗尽。strict_map_key 默认开启,只允许 bytes 和 str 类型的 map 键,防范哈希 DoS 攻击。这两个设置对大多数正常场景没有影响,但在处理不可信来源的数据时多了一层保护。

纯 Python fallback

CPython 上有 C 扩展加速,PyPy 上则自动回退到纯 Python 实现。不需要额外配置,一套代码在两个运行时上都能正常工作。

什么时候用它?

如果你的场景是配置文件、API 文档这种人类经常要读的,JSON 仍然更合适。msgpack 的优势在机器之间的数据交换:微服务通信、缓存存储、日志序列化、消息队列 payload 这些地方。

体积小意味着网络传输更快,二进制解析意味着 CPU 开销更低。实测中 msgpack 的序列化速度通常比 JSON 快几倍,数据体积也能小 20% 到 50%,具体取决于数据结构。

README区域截图

一点历史

这个包在 PyPI 上原名 msgpack-python,0.5 版本后改名为 msgpack。如果你是从旧版本升级,需要先卸载旧包。1.0 版本正式放弃了 Python 2 支持,同时把 use_bin_typeraw 的默认值调整到了更合理的状态,bytes 走 bin 类型,str 走 string 类型,行为更符合预期。

总的来说,msgpack-python 是一个成熟稳定的序列化库。如果你正在找 JSON 的替代方案,又不想引入复杂的依赖,它值得列入考虑。

期。

总的来说,msgpack-python 是一个成熟稳定的序列化库。如果你正在找 JSON 的替代方案,又不想引入复杂的依赖,它值得列入考虑。

更多推荐