Learning Platform
Глоссарий Troubleshooting
Урок 07.03 · 20 мин
Средний
ProtobufJSON SchemaFormat ComparisonSchema Registry

Protobuf и JSON Schema

Schema Registry поддерживает три формата сериализации: Avro, Protocol Buffers и JSON Schema. В Уроке 02 мы подробно разобрали Avro. В этом уроке разберём два альтернативных формата — их преимущества, ограничения и правила эволюции — а затем сравним все три.


Protocol Buffers в Schema Registry

Protocol Buffers (Protobuf) — бинарный формат сериализации от Google, исходно разработанный для межсервисного взаимодействия (gRPC). Схема описывается в .proto файлах.

syntax = "proto3";
package com.example.kafka;

message Order {
  int32 id = 1;
  string product = 2;
  double amount = 3;
  int64 timestamp_millis = 4;
  optional string metadata = 5;
}

Ключевая особенность Protobuf: каждое поле имеет номер поля (field number), который кодируется в бинарный payload вместо имени поля. Это делает бинарное представление максимально компактным и — что критически важно для совместимости — независимым от имён полей.

Schema Registry хранит .proto файл как текст. При регистрации указывается schemaType: "PROTOBUF".


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

Наименьший размер бинарного payload для сложных вложенных структур. Protobuf использует varint-кодирование для чисел и не хранит имена полей — только номера. Для сообщения с большим числом числовых полей Protobuf компактнее Avro.

Мощная экосистема инструментов. protoc — компилятор схем, поддерживает генерацию кода для 10+ языков. Плагины для gRPC, REST, JSON mapping. Первоклассная поддержка в Bazel, Maven, Gradle.

Первоклассная gRPC-интеграция. Если вы строите микросервисы на gRPC, Protobuf — естественный выбор. Kafka-события могут использовать те же .proto определения, что и gRPC-сервисы, без преобразования схем.

Поддержка oneof, map, вложенных message. Богатая система типов с семантикой из коробки.


Правила эволюции Protobuf

Совместимость в Protobuf строится на нескольких строгих правилах:

Никогда не переиспользуйте номера полей. Если поле 5: string metadata было удалено, номер 5 нельзя использовать для нового поля. Старые клиенты могут прочитать байты под номером 5 с неправильной интерпретацией типа.

Используйте reserved для удалённых полей:

message Order {
  reserved 5;
  reserved "metadata";  // запрещает случайное переиспользование имени

  int32 id = 1;
  string product = 2;
  double amount = 3;
  int64 timestamp_millis = 4;
  // поле 5 удалено
}

Добавление новых полей всегда совместимо при правильной нумерации. В proto3 все поля опциональны по умолчанию. Старые клиенты игнорируют неизвестные номера полей (unknown fields preservation).

Изменение типа опасно. Protobuf позволяет изменить тип только внутри совместимых wire types (например, int32int64 — wire type 0 в обоих случаях). Изменение между несовместимыми wire types ломает декодирование.

oneof нельзя добавить к существующему полю. Если поле string metadata = 5 существует, нельзя сделать его частью oneof. Нужно удалить и создать новую структуру с новым номером.


JSON Schema в Schema Registry

JSON Schema описывает структуру JSON-документа в стандарте Draft 7 (Confluent Schema Registry 7.9.x использует JSON Schema Draft 7 или 2019-09).

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "Order",
  "type": "object",
  "properties": {
    "id": {"type": "integer"},
    "product": {"type": "string"},
    "amount": {"type": "number"},
    "timestamp_millis": {"type": "integer"},
    "metadata": {"type": ["string", "null"]}
  },
  "required": ["id", "product", "amount"]
}

При регистрации: "schemaType": "JSON". Payload — обычный JSON-текст, без бинарного кодирования. Wire format тот же: magic byte + schema ID + JSON bytes.


Преимущества и ограничения JSON Schema

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

Человекочитаемый payload. Сообщения можно читать и отлаживать без инструментов десериализации. kafka-console-consumer показывает читаемый JSON.

Нулевой порог входа. Разработчик, знакомый с JSON, понимает JSON Schema без дополнительного обучения. Идеально для web-native команд.

Нет кодогенерации. JSON Schema валидирует данные на лету — не нужны предварительно сгенерированные классы.

Ограничения:

Нет бинарного кодирования. Каждое сообщение — это JSON-текст. При высоком throughput это значительно хуже Avro и Protobuf по size и CPU.

Слабые гарантии эволюции. JSON Schema не имеет формального механизма совместимости уровня Avro reader/writer schema resolution. Confluent Schema Registry реализует ограниченный набор проверок совместимости для JSON Schema, но они менее строгие.

additionalProperties: false блокирует расширение. Если схема запрещает дополнительные поля, любое добавление нового поля в producer будет отклонено на стороне потребителя при валидации.

TIP

Если вы не уверены, какой формат выбрать — используйте Avro. Это стандарт де-факто для Kafka и Schema Registry с лучшей поддержкой инструментов, самым строгим контролем совместимости и зрелой экосистемой.


Сравнение трёх форматов

ХарактеристикаAvroProtobufJSON Schema
КодированиеБинарноеБинарноеТекст (JSON)
Схема в payloadНет (только ID)Нет (только ID)Нет (только ID)
Гарантии совместимостиСтрогиеСтрогиеСлабые
Размер сообщенияМалыйНаименьшийБольшой
ЭкосистемаKafka-nativegRPC-nativeWeb-native
Инструментыavro-tools, GenericRecordprotoc, generated classesjsonschema validators
КодогенерацияОпциональная (SpecificRecord)ОбязательнаяНе нужна
Читаемость payloadНет (бинарный)Нет (бинарный)Да
Нулевой порог входаСреднийВысокийНизкий

Когда выбирать каждый формат

Avro — для Kafka-first систем. Наилучшая интеграция со Schema Registry, строжайший контроль совместимости, компактный размер, зрелые Java-библиотеки. Выбор по умолчанию для любого нового Kafka-проекта без специфических требований.

Protobuf — для gRPC-heavy микросервисов. Если ваши сервисы общаются по gRPC с теми же данными, которые публикуются в Kafka, использование одних и тех же .proto файлов устраняет дублирование схем. Наименьший размер payload при сложных вложенных структурах.

JSON Schema — для отладки и web-native интеграций. Когда читаемость payload важнее эффективности. Для интеграций с внешними партнёрами, где JSON является общим языком. Для команд без Java/Scala опыта, где кодогенерация является барьером.

Проверка знанийKnowledge check
Команда строит микросервисы на gRPC и хочет публиковать те же события в Kafka без преобразования схем. Какой формат сериализации оптимален и почему?
ОтветAnswer
Protobuf. Он является нативным форматом gRPC — `.proto` файлы могут быть одновременно gRPC-контрактами и Kafka-схемами в Schema Registry. Это устраняет дублирование определений схем между двумя системами, обеспечивает генерацию кода для одного языка из одного источника истины и даёт наименьший размер бинарного payload для сложных вложенных структур, типичных для gRPC-сервисов.

Проверьте понимание

Результат: 0 из 0
Аналитический
Вопрос 1 из 4. В Protobuf-схеме было поле `string metadata = 5`. Команда удалила это поле из схемы и хочет добавить новое поле `string notes` под тем же номером 5. Что произойдёт при чтении старых данных новым decoder?

Закончили урок?

Отметьте его как пройденный, чтобы отслеживать свой прогресс

Войдите чтобы оценить урок

Прогресс модуля
0 из 6