データシリアライゼーションフォーマット比較: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(Concise Binary Object Representation)
バイナリデータの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 to YAML変換ツールが最も一般的な変換ニーズに対応します。
FAQ
ブラウザでバイナリフォーマットを使えますか?
はい、ただし注意点があります。MessagePackとCBORにはブラウザで動作するJavaScriptライブラリがあります。Protobufにはprotobufjsライブラリが必要です。ただし、JSONはネイティブブラウザサポートがあり、fetchで動作し、ブラウザのDevToolsでデバッグ可能なため、Web APIのデフォルトであり続けています。
APIをJSONからProtobufに切り替えるべきですか?
JSONシリアライゼーションが原因のパフォーマンスボトルネックを計測した場合にのみ検討してください。ほとんどのWebアプリケーションでは、JSONは十分に高速であり、開発者体験の利点(可読性、デバッグ、ツール)がバイナリフォーマットのパフォーマンス向上を上回ります。Protobufは一般的なWeb APIではなく、高スループットのマイクロサービス通信で真価を発揮します。
関連リソース
- JSONフォーマッター — JSONの整形と検証
- YAML vs JSON — テキストベースフォーマットの比較
- CSV vs JSON vs XML — データ交換フォーマットの選び方