数据序列化格式比较:JSON、Protobuf、MessagePack
序列化是将数据结构转换为可以存储或传输并在之后重建的格式。格式的选择影响性能、负载大小、互操作性和开发者体验。本指南比较了最流行的选项。
格式概览
| 格式 | 类型 | 模式 | 人类可读 | 二进制 |
|---|---|---|---|---|
| JSON | 文本 | 可选(JSON Schema) | 是 | 否 |
| Protocol Buffers | 二进制 | 必需(.proto) | 否 | 是 |
| MessagePack | 二进制 | 无 | 否 | 是 |
| CBOR | 二进制 | 可选(CDDL) | 否 | 是 |
| Avro | 二进制 | 必需(JSON 模式) | 否 | 是 |
| YAML | 文本 | 可选 | 是 | 否 |
| XML | 文本 | 可选(XSD) | 是 | 否 |
JSON:通用默认选择
JSON 是使用最广泛的序列化格式,在浏览器和几乎所有编程语言中都有原生支持。
{
"name": "Alice",
"age": 30,
"roles": ["admin", "editor"],
"active": true
}
优势:通用支持、人类可读、无需模式、调试方便。 劣势:冗长、不支持二进制数据、无模式强制、比二进制格式解析更慢。 大小:此示例 = 74 字节。
使用我们的 JSON 格式化工具 格式化 JSON。
Protocol Buffers (Protobuf)
Google 的二进制序列化格式。需要模式定义:
message User {
string name = 1;
int32 age = 2;
repeated string roles = 3;
bool active = 4;
}
优势:非常紧凑、非常快速、通过模式实现强类型、向前/向后兼容、代码生成。 劣势:不可人类可读、需要模式定义、需要代码生成步骤、调试更困难。 大小:相同数据 ≈ 28 字节(比 JSON 小 62%)。
MessagePack
一种结构上等同于 JSON 的二进制格式——相同类型、无需模式:
const msgpack = require('msgpack-lite');
const packed = msgpack.encode({name: "Alice", age: 30, roles: ["admin", "editor"], active: true});
// Result: Buffer of ~45 bytes
优势:JSON 的直接替代品(相同数据模型)、比 JSON 更小、解析更快、无需模式。 劣势:不可人类可读、不如 Protobuf 紧凑、无模式验证。 大小:相同数据 ≈ 45 字节(比 JSON 小 39%)。
CBOR(简洁二进制对象表示)
IETF 标准(RFC 8949)的二进制数据格式。目标与 MessagePack 类似但功能更丰富:
优势:IETF 标准、支持扩展类型标签(日期、BigInt)、确定性编码、适合受限设备(IoT)。 劣势:生态系统不如 MessagePack 丰富、不可人类可读。 大小:与 MessagePack 类似。
Apache Avro
在大数据生态系统(Hadoop、Kafka)中大量使用:
优势:模式演进(安全添加/删除字段)、紧凑编码、内置压缩、适合流式数据。 劣势:读写都需要模式、不太适合请求-响应式 API。 大小:当模式单独共享时非常紧凑。
性能比较
基准测试因实现而异,但典型的相对性能:
| 格式 | 序列化速度 | 反序列化速度 | 大小 |
|---|---|---|---|
| JSON | 1x(基准) | 1x(基准) | 1x(基准) |
| MessagePack | 快 2-4 倍 | 快 2-4 倍 | 0.6x |
| Protobuf | 快 3-10 倍 | 快 3-10 倍 | 0.3-0.5x |
| Avro | 快 2-5 倍 | 快 2-5 倍 | 0.3-0.5x |
| CBOR | 快 2-4 倍 | 快 2-4 倍 | 0.6x |
实际数字在很大程度上取决于数据结构、语言实现以及模式编译是否被摊销。
选择正确的格式
在以下情况使用 JSON:
- 构建 Web API(浏览器原生支持)
- 人类可读性很重要(配置文件、调试)
- 互操作性是优先项(每种语言都支持 JSON)
- 需要模式灵活性(可变的文档结构)
在以下情况使用 Protobuf:
- 性能至关重要(高吞吐量服务)
- 需要严格类型(强制模式)
- 你同时控制生产者和消费者
- 使用 gRPC 进行服务通信
在以下情况使用 MessagePack:
- 想要更小的负载且无需模式开销
- 需要 JSON 的直接替代品
- 使用对 MessagePack 支持良好的语言
- Redis 或其他系统原生使用 MessagePack
在以下情况使用 Avro:
- 处理大数据管道(Kafka、Hadoop)
- 模式演进很重要
- 数据长期存储(模式注册表帮助未来读取者)
在文本格式之间转换时,我们的 JSON 转 YAML 转换器 处理最常见的转换需求。
常见问题
我可以在 Web 浏览器中使用二进制格式吗?
可以,但有注意事项。MessagePack 和 CBOR 有在浏览器中运行的 JavaScript 库。Protobuf 需要 protobufjs 库。然而,JSON 仍然是 Web API 的默认选择,因为它有原生浏览器支持、可以与 fetch 配合使用,并且可以在浏览器 DevTools 中调试。
我应该将 API 从 JSON 切换到 Protobuf 吗?
只有当你已经测量到 JSON 序列化造成的性能瓶颈时才应这样做。对于大多数 Web 应用,JSON 足够快,开发者体验的好处(可读性、调试、工具)超过了二进制格式的性能提升。Protobuf 在高吞吐量微服务通信中表现出色,而非典型的 Web API。
相关资源
- JSON 格式化工具 — 格式化和验证 JSON
- YAML vs JSON — 比较基于文本的格式
- CSV vs JSON vs XML — 选择数据交换格式