Зачем нужен реестр схем Avro для языков со статической типизацией?

Я задавался вопросом о необходимости реестра схемы Avro при использовании сообщений из темы Kafka с использованием статически типизированного языка, такого как Java. Я получаю сообщения из настройки темы Kafka следующим образом:

    Properties props = new Properties();
    props.setProperty(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, String.join(",", kafkaProperties.getServers()));
    props.setProperty(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, ByteArrayDeserializer.class.getName());
    props.setProperty(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, KafkaAvroDeserializer.class.getName());

    props.setProperty(KafkaAvroDeserializerConfig.SCHEMA_REGISTRY_URL_CONFIG, kafkaProperties.getSchemaRegistryUrl());
KafkaConsumer<byte[], FooClass> kafkaConsumer = new KafkaConsumer<>(props);;

В моем проекте есть .avsc файла, которые определяют схему для класса FooClass. Я также настроил avro-maven-plugin для генерации класса FooClass для меня во время сборки.

Почему мне все еще нужно указывать URL-адрес реестра схемы? Разве мой потребитель не может десериализовать значения моих сообщений Kafka, используя файл .avsc в моем проекте?


person Mustafa    schedule 20.04.2020    source источник


Ответы (3)


Вы используете библиотеки Confluent (io.confluent.kafka .serializers.KafkaAvroDeserializer), которые определяют свои собственный формат Confluent Avro и обязательное использование реестра Confluent Schema Registry.

Технически вам не нужен реестр для Apache Avro.

Avro нужна схема писателей для декодирования сообщения, и хотя она включена в файлы Avro, что делает их самоописывающими, она не включена в формат потоковой передачи или Confluent Avro.

Итак, клиенту нужен способ найти схему. Это либо решается реестром Confluent Schema Registry для формата Confluent Avro, либо может быть решено вашим собственным org.apache.avro.message.SchemaStore. См. этот пример, где я использую SchemaStore.Cache предварительно заполнен известными схемами.

Обратите внимание, что в примере используется формат Apache Avro, несовместимый с Confluent Avro.

Десериализатору Confluent Avro требуется реестр конфлюентных схем, и у него нет API для «работы с известными схемами».

person eik    schedule 20.04.2020
comment
Спасибо @eik, это ответ на мой вопрос. - person Mustafa; 21.04.2020

Цель Schema Registry - сделать схемы доступными для всех производителей и потребителей, без необходимости связывания их вместе посредством распространения и управления чем-то вроде файла .avsc. Такой файл подходит для отдельного проекта, но Kafka часто используется несколькими приложениями, возможно, между командами или даже организационными подразделениями, и поэтому важна возможность более свободно связывать то, как совместно используется схема.

Ссылка: https://docs.confluent.io/current/schema-registry/index.html

person Robin Moffatt    schedule 20.04.2020
comment
Спасибо, Робин. Но предположим, что все наши производители и потребители написаны на Java и должны иметь avsc файлы во время сборки. Нужен ли нам реестр для создания и использования сообщений? Почему недостаточно avsc файлов, которые уже распространены в эти приложения? - person Mustafa; 20.04.2020
comment
Но реестр схемы не передает нам схему во время сборки, поэтому нам все равно нужно предоставить файл avsc при сборке нашего приложения. Разве это не противоречит цели создания реестра? - person Mustafa; 20.04.2020
comment
Если ваше приложение записывает данные, то да, оно должно предоставить схему (через avsc или как-то иначе). Назначение реестра - сделать схему доступной для приложений-потребителей. См. docs.confluent.io/current/schema-registry/. - person Robin Moffatt; 20.04.2020

Узнав больше о формате avro и роли реестра схем, я понял, почему реестр схем необходим даже для статически типизированного языка, такого как java. И краткий ответ - эволюция схемы.

Допустим, вы сегодня создали приложение, которое потребляет сообщения типа A, написанные с использованием схемы SA. Во время создания приложения у вас может быть файл a.avsc, который вы используете для создания классов для десериализации сообщений. До этого момента вы бы не подумали, что для получения SA необходимо обращаться в реестр схем, и имеет смысл указать класс десериализатора на файл a.avsc, с помощью которого вы строите свое приложение. Но с десериализатором avro вы не можете этого сделать (т.е. ему нужен реестр). Что заставляет задуматься, почему?

Неделю спустя производитель, создающий сообщения типа A, решает добавить новое поле в A. Когда это произойдет, ваш класс десериализатора avro, используя схему, с которой вы построили свое приложение (если это было возможно), не сможет десериализуйте эти новые сообщения, если оно встретится. В то же время код, созданный с использованием старой схемы, по-прежнему будет работать (если изменение схемы будет обратно совместимо). Но для того, чтобы ваш десериализатор мог читать сообщения, написанные с помощью новой схемы, ему нужна новая схема.

Фактически это означает, что код вашего Java-приложения, созданный с использованием старой схемы, по-прежнему будет работать с сообщениями, написанными с использованием развитой схемы. Но без новой схемы (предоставленной реестром) ваш десериализатор avro не сможет десериализовать новые сообщения.

Итак, теоретически, если бы схемы не изменились, вы могли бы обойтись без предоставления схемы во время сборки.

person Mustafa    schedule 09.08.2020