資料序列化格式比較:JSON、Protobuf、MessagePack
序列化是將資料結構轉換為可儲存或傳輸的格式,以便日後重建的過程。格式的選擇會影響效能、酬載大小、互通性和開發者體驗。本指南比較最受歡迎的幾種方案。
格式概覽
| 格式 | 類型 | Schema | 人類可讀 | 二進位 |
|---|---|---|---|---|
| JSON | 文字 | 可選(JSON Schema) | 是 | 否 |
| Protocol Buffers | 二進位 | 必需(.proto) | 否 | 是 |
| MessagePack | 二進位 | 無 | 否 | 是 |
| CBOR | 二進位 | 可選(CDDL) | 否 | 是 |
| Avro | 二進位 | 必需(JSON schema) | 否 | 是 |
| YAML | 文字 | 可選 | 是 | 否 |
| XML | 文字 | 可選(XSD) | 是 | 否 |
JSON:通用的預設選擇
JSON 是使用最廣泛的序列化格式,瀏覽器原生支援,且幾乎所有程式語言都支援。
{
"name": "Alice",
"age": 30,
"roles": ["admin", "editor"],
"active": true
}
優勢:通用支援、人類可讀、不需要 schema、除錯方便。 劣勢:冗長、不支援二進位資料、無 schema 強制、解析速度比二進位格式慢。 大小:此範例 = 74 位元組。
使用我們的 JSON 格式化工具格式化 JSON。
Protocol Buffers(Protobuf)
Google 的二進位序列化格式。需要 schema 定義:
message User {
string name = 1;
int32 age = 2;
repeated string roles = 3;
bool active = 4;
}
優勢:非常精簡、非常快速、透過 schema 實現強型別、向前/向後相容、程式碼自動產生。 劣勢:非人類可讀、需要 schema 定義、需要程式碼產生步驟、除錯較困難。 大小:相同資料 ≈ 28 位元組(比 JSON 小 62%)。
MessagePack
一種在結構上等同於 JSON 的二進位格式 — 相同的型別,不需要 schema:
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 更小、解析更快、不需要 schema。 劣勢:非人類可讀、沒有 Protobuf 精簡、無 schema 驗證。 大小:相同資料 ≈ 45 位元組(比 JSON 小 39%)。
CBOR(精簡二進位物件表示法)
一個 IETF 標準(RFC 8949)的二進位資料格式。目標與 MessagePack 相似但有額外功能:
優勢:IETF 標準、支援擴充型別標籤(日期、BigInt)、確定性編碼、非常適合受限裝置(IoT)。 劣勢:生態系統比 MessagePack 小、非人類可讀。 大小:與 MessagePack 相似。
Apache Avro
在大數據生態系統中被大量使用(Hadoop、Kafka):
優勢:schema 演進(安全地新增/移除欄位)、精簡編碼、內建壓縮、非常適合串流資料。 劣勢:讀寫都需要 schema、較不適合請求-回應式 API。 大小:當 schema 單獨共享時非常精簡。
效能比較
基準測試因實作而異,但典型的相對效能為:
| 格式 | 序列化速度 | 反序列化速度 | 大小 |
|---|---|---|---|
| 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 |
實際數字在很大程度上取決於資料結構、語言實作,以及 schema 編譯是否被攤銷。
選擇正確的格式
在以下情況使用 JSON:
- 建構 Web API(瀏覽器原生支援)
- 人類可讀性很重要(配置檔案、除錯)
- 互通性是首要考量(所有語言都支援 JSON)
- 需要 schema 彈性(不同結構的文件)
在以下情況使用 Protobuf:
- 效能至關重要(高吞吐量服務)
- 需要嚴格型別(強制 schema)
- 你同時控制生產者和消費者
- 使用 gRPC 進行服務通訊
在以下情況使用 MessagePack:
- 想要更小的酬載但不需要 schema 開銷
- 需要直接替換 JSON
- 使用的語言有良好的 MessagePack 支援
- Redis 或其他系統原生使用 MessagePack
在以下情況使用 Avro:
- 使用大數據管線(Kafka、Hadoop)
- schema 演進很重要
- 資料需要長期儲存(schema 註冊表幫助未來的讀取者)
如需在文字格式之間轉換,我們的 JSON 轉 YAML 轉換器能處理最常見的轉換需求。
常見問題
可以在網頁瀏覽器中使用二進位格式嗎?
可以,但有一些限制。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 — 選擇資料交換格式