Открыть сервис

Protobuf: бинарный формат сериализации данных

Protocol Buffers (сокращённо protobuf) — это бинарный формат сериализации структурированных данных, разработанный компанией Google для обмена данными между системами и хранения данных. Формат основан на использовании интерфейсного описания языка (IDL) для определения структуры сообщений и генерации кода для различных языков программирования. Protobuf обеспечивает компактное представление данных и высокую скорость сериализации/десериализации по сравнению с текстовыми форматами, такими как XML и JSON.

История

Разработка Protocol Buffers началась внутри Google в начале 2000-х годов для решения проблемы обмена данными между внутренними сервисами компании. Официально формат был представлен публике в 2008 году с выпуском открытой версии. Первая публичная версия, известная как proto2, получила широкое распространение. В 2016 году была выпущена версия proto3, которая упростила синтаксис, убрала необходимость явного указания полей как обязательных и добавила поддержку большего количества языков. В 2020-х годах protobuf стал одним из ключевых компонентов экосистемы gRPC — высокопроизводительного фреймворка удалённого вызова процедур.

Архитектура и принцип работы

Работа с protobuf включает три основных этапа: определение структуры данных в .proto-файле, компиляцию этого файла в код целевого языка программирования и использование сгенерированных классов для сериализации и десериализации объектов.

Синтаксис .proto файлов

Файл описания начинается с указания синтаксиса (syntax = "proto3";), объявления пакета и определения сообщений. Сообщение представляет собой набор полей, каждое из которых имеет тип, имя и уникальный числовой номер. Номер поля используется в бинарном представлении для идентификации данных и не должен меняться в процессе эволюции схемы. Например:

``protobuf message Person { string name = 1; int32 id = 2; string email = 3; } ``

Генерация кода

Для компиляции .proto-файлов используется компилятор protoc, который поддерживает плагины для генерации кода на C++, Java, Python, Go, C#, JavaScript, Ruby, PHP и других языках. Сгенерированный код содержит классы сообщений с методами для сериализации (SerializeToString) и десериализации (ParseFromString).

Бинарное кодирование

При сериализации protobuf использует технику кодирования с тегами (tag-length-value). Каждое поле кодируется как пара «номер поля + тип данных» (ключ) и значение. Для целых чисел применяется переменная длина кодирования (varint), что позволяет использовать меньше байтов для небольших значений. Строки и вложенные сообщения кодируются с указанием длины. Отсутствующие поля не занимают места в бинарном представлении, а поля со значениями по умолчанию могут быть опущены. Это обеспечивает высокую компактность данных.

Версии и отличия proto2 и proto3

Основные различия между версиями:

  • В proto3 все поля являются необязательными по умолчанию, тогда как в proto2 требовалось явно указывать optional или required.
  • proto3 использует скалярные типы с более строгими правилами: отсутствует проверка на установку поля, а значения по умолчанию не сериализуются.
  • В proto3 введена поддержка типов Any, Timestamp и Duration, а также расширены возможности для работы с картами (map).
  • proto2 поддерживает расширения (extensions), которые в proto3 были заменены на типажи (well-known types).

Применение

Protocol Buffers применяются в системах, где критически важны производительность и размер передаваемых данных. Основные области использования:

  • Микросервисная архитектура: protobuf является стандартным форматом для gRPC-сервисов, обеспечивая строгую типизацию и высокую скорость обмена.
  • Хранение данных: используется для сериализации объектов в базах данных или файловых хранилищах.
  • Мобильная разработка: применяется в приложениях Android и iOS для уменьшения трафика и ускорения загрузки данных.
  • Потоковая обработка: Apache Kafka, Apache Flink и другие системы поддерживают protobuf для передачи событий.
  • Телекоммуникации и IoT: используется для обмена данными с устройствами с ограниченными ресурсами.

Преимущества и недостатки

Преимущества

  • Компактность: бинарное представление занимает значительно меньше места, чем XML или JSON.
  • Высокая скорость работы: сериализация и десериализация выполняются быстрее за счёт отсутствия парсинга текста.
  • Строгая типизация: структура данных описана явно, что снижает риск ошибок.
  • Обратная совместимость: добавление новых полей не нарушает работу старых клиентов.
  • Мультиязычность: поддержка большинства популярных языков программирования.

Недостатки

  • Отсутствие читаемости: бинарный формат невозможно просмотреть в текстовом редакторе без специальных инструментов.
  • Сложность отладки: для анализа передаваемых данных требуются дополнительные утилиты.
  • Необходимость компиляции: изменение схемы требует перекомпиляции кода и обновления всех зависимых систем.
  • Кривая обучения: разработчикам необходимо изучить синтаксис IDL и процесс генерации кода.

Инструменты и экосистема

Вокруг protobuf сформирована развитая экосистема инструментов. Компилятор protoc поддерживает множество плагинов, включая генераторы для gRPC. Существуют инструменты для преобразования protobuf в JSON и обратно (например, protobufjs для JavaScript). Для отладки и просмотра бинарных данных используются утилиты вроде protoc --decode_raw. Также доступны редакторы с подсветкой синтаксиса .proto-файлов и плагины для сред разработки.

Сравнение с альтернативами

Protobuf конкурирует с другими бинарными форматами, такими как Apache Avro, Apache Thrift и MessagePack. По сравнению с Avro, protobuf не требует наличия схемы при чтении данных (самодостаточность сообщений), но уступает в компактности при передаче больших массивов однотипных данных. Apache Thrift предоставляет аналогичный функционал, но имеет меньшую популярность в экосистеме облачных технологий. MessagePack проще в использовании, но не обеспечивает строгой типизации и обратной совместимости на уровне схемы.

Значение для индустрии

Protocol Buffers стали де-факто стандартом для внутреннего обмена данными в крупных распределённых системах. Формат используется в таких проектах, как Kubernetes, Docker, etcd, а также во многих публичных API, предоставляемых через gRPC. Вклад Google в открытый исходный код позволил широкому кругу разработчиков применять protobuf в коммерческих и открытых проектах, что способствовало стандартизации подходов к сериализации данных в индустрии.

BFOmetr — база данных и аналитика по компаниям России.

На главную BFOmetr →