Производительность использования различных типов Avro для отправки сообщений в Kafka - SpecificRecordBase или GenericRecord с реестром схемы - PullRequest
0 голосов
/ 11 октября 2019

Я пытаюсь найти некоторую информацию о производительности и (или) преимуществах использования двух разных типов Avro для отправки сообщений Kafka. Согласно моим исследованиям, можно создать полезную нагрузку сообщения Кафки на основе avro:

EITHER :

GenericRecord , экземпляр которого можно создать, вызвав new GenericData.Record и передача схемы, считанной из реестра схем, в качестве параметра:

Примерно:

private CachedSchemaRegistryClient schemaRegistryClient;
private Schema valueSchema;
// Read a schema
//…
this.valueSchema = schemaRegistryClient.getBySubjectAndID("TestTopic-value",1);
// Define a generic record according to the loaded schema

GenericData.Record record = new GenericData.Record(valueSchema);
// Send to kafka

ListenableFuture<SendResult<String, GenericRecord>> res;
res = avroKafkaTemplate
        .send(MessageBuilder
                .withPayload(record)
                .setHeader(KafkaHeaders.TOPIC, TOPIC)
                .setHeader(KafkaHeaders.MESSAGE_KEY, record.get("id"))
                .build());

ИЛИ :

Класс, который расширяет SpecificRecordBase и генерируется с помощью Maven (из файла, содержащего схему Avro)

/..
public class MyClass extends org.apache.avro.specific.SpecificRecordBase implements org.apache.avro.specific.SpecificRecord

/..
MyClass myAvroClass = new MyClass();

ListenableFuture<SendResult<String, MyClass>> res;
res = avroKafkaTemplate
        .send(MessageBuilder
                .withPayload(myAvroClass)
                .setHeader(KafkaHeaders.TOPIC, TOPIC)
                .setHeader(KafkaHeaders.MESSAGE_KEY, myAvroClass.getId())
                .build());

Когда фрагмент кода, который содержитэкземпляр класса, который расширяет GenericRecord отлажен, можно видеть, что есть включенная схема.

На этот счет у меня есть несколько вопросов:

  1. Если я отправляю экземпляр GenericRecord в Kafka, отправляется ли базовая схема?
    Если нет, когда он удаляется? Какой класс / метод отвечает за извлечение байтов из GenericRecord и удаление базовой схемы, чтобы она не отправлялась вместе с полезной нагрузкой? Если да, какой смысл в реестре схемы?

  2. В случае класса, который расширяет SpecificRecord , базовая схема также отправляется, не так лиЭто? Это означает, что, если я возьму функцию, которая получает сообщение Кафки и подсчитывает количество его байтов, я должен ожидать больше байтов в сообщении о конкретной записи, чем в сообщении об общей записи, верно?

  3. A SpecificRecord экземпляр дает мне больше контроля, а использование менее подвержено ошибкам. Если схема не отправляется с GenericRecord и с SpecificRecord , то мы имеем компромисс. С одной стороны (SpecificRecord), есть простота использования, так как доступен понятный API (не нужно знать все поля наизусть, писать get («X»), get («Y») и т. Д.)с другой стороны, размер полезной нагрузки увеличивается, поскольку схема должна отправляться вместе с ней. Если у меня относительно большая схема (50 полей), я должен выбрать отправку GenericRecords с помощью реестра схем, в противном случае на производительность будет оказано негативное влияние, поскольку схема должна отправляться с каждым сообщением, верно?

1 Ответ

0 голосов
/ 13 октября 2019

Схемы отправляются и кэшируются производителем в обоих случаях: общая или специфическая.

В отношении производительности, хотя я не проверял ее, я бы оценил, что время сериализации примерно одинаково для обоих, в то время как десериализация будетБыстрее для Generic, потому что доступ к полю и приведение типов будут откладываться на ваш собственный код, а не проверяться для каждого поля

Примечание: есть также записи ReflectData, которые могут быть медленнее из-за использования отражения

...