MessagePack Format
Что такое MessagePack
MessagePack — бинарный формат сериализации, позиционируемый как «JSON, но быстрее и компактнее». Schemaless — не требует предварительного определения схемы (в отличие от Protobuf и Thrift). Формат самоописывающий: первый байт каждого значения определяет его тип.
Поддержка языков — одна из самых широких: официальные библиотеки для 50+ языков (Python msgpack 1.1.2, Go, Rust, Java, C++, JavaScript, Ruby, PHP, C#, Swift, и др.).
MessagePack — не замена Protobuf или Thrift. Это замена JSON для сценариев, где schema management не нужен, но JSON слишком медленный или объёмный: Redis serialization, WebSocket payloads, game state, IPC между процессами, кэширование.
Определение типа по первому байту
Ключевая идея MessagePack: первый байт каждого значения определяет его тип и (иногда) содержит само значение:
Format Families
MessagePack организует типы в families — каждая family покрывает диапазон размеров одного логического типа:
Integer: выбор формата по значению
Integers: от -2^63 до 2^64-1. MessagePack автоматически выбирает самый компактный формат.Полный пример кодирования
Wire: 82 A2 69 64 CC 96 A4 6E 61 6D 65 A2 41 6C (14 байт)
Итого: 1 + 3 + 2 + 5 + 3 = 14 байт. JSON = 23 байта. MessagePack на 39% компактнее. Но Protobuf = 7 байт — вдвое компактнее (нет ключей на wire).Protobuf кодирует User(id=150, name="Al") в 7 байт. MessagePack — в 14 байт. Разница — ключи: MessagePack хранит имена полей (“id”, “name”) на wire, Protobuf — только field numbers. Schema-based форматы всегда компактнее schemaless при одинаковых данных.
Bool, Float, Binary
Extension Types
MessagePack поддерживает пользовательские типы через extension types — type code (int8) + raw data:
Extension: type code (int8) + data bytes
Extension = type byte (application-defined) + data. Позволяет добавлять кастомные типы без изменения формата. Type codes 0-127 для application, -1 to -128 для spec-defined.Timestamp Extension Type
Единственный spec-defined extension type — Timestamp (type code -1):
Timestamp 64 упаковывает наносекунды и секунды в одно 64-битное значение: (nanosec << 34) | seconds. Старшие 30 бит — наносекунды (0–999999999), младшие 34 бита — секунды. Это хитрая оптимизация: если наносекунды = 0, всё значение = seconds (timestamp 32 поведение в timestamp 64 формате).
MessagePack vs JSON: когда выбирать
Нужна human readability?
Основной вопрос: нужна ли human readability? Если да — JSON. Если нет — MessagePack может быть лучше.