В каких форматах передаются данные в Kafka и как используется Avro Protocol?
Что проверяют
Понимаете ли вы, что Kafka передаёт байты, а формат это договорённость между продюсером и консьюмером, и как Schema Registry позволяет менять схему, не ломая чтение. Следом спрашивают про режимы совместимости и о том, что будет при добавлении поля.
Как отвечать
Сообщение в Kafka это ключ, значение и заголовки в виде массивов байт. Брокер содержимое не разбирает, объект в байты превращают клиенты через key.serializer и value.serializer. Популярные варианты:
- String и JSON: читаемо и просто, но схему никто не проверяет, а имена полей повторяются в каждом сообщении;
- Avro: компактный бинарный формат, схема описывается в JSON-файле
.avsc, Java-классы генерируетavro-maven-plugin; - Protobuf и JSON Schema: тоже поддерживаются Schema Registry, Protobuf удобен, если он уже есть в gRPC.
Как Avro работает с Kafka. KafkaAvroSerializer регистрирует схему в Schema Registry (Confluent или совместимые Apicurio и Karapace) и пишет в сообщение не схему, а магический байт, 4-байтовый id схемы и затем данные. KafkaAvroDeserializer по id берёт схему писателя из реестра и кэширует её. С specific.avro.reader=true он возвращает сгенерированный класс, иначе GenericRecord.
Эволюция схемы держится на правилах совместимости, по умолчанию BACKWARD: новая схема обязана читать старые данные. Новое поле добавляется только со значением default, а обновлять первыми нужно консьюмеров. Есть ещё FORWARD, FULL, NONE и транзитивные варианты.
Avro Protocol в строгом смысле это описание RPC в файлах .avpr и .avdl, с Kafka он не используется. Если спросили именно так, уточните, что речь про схемы.
Где спотыкаются
Говорят, что схема едет в каждом сообщении. В файлах Avro так и есть, а в Kafka только её id.
Добавляют поле без default: такая схема не прочитает старые сообщения, и при BACKWARD реестр её отклонит, а без реестра сломаются консьюмеры.
Оставляют на проде auto.register.schemas=true, и любой продюсер регистрирует новую версию схемы в обход ревью.