java - 使用不同 Avro 类型向 Kafka 发送消息的性能 – SpecificRecordBase 与带有 Schema Registry 的 GenericRecord

标签 java apache-kafka avro confluent-platform confluent-schema-registry

我正在尝试查找一些有关使用两种不同 Avro 类型发送 Kafka 消息的性能和(缺点)优点的信息。 根据我的研究,可以创建一个基于 avro 的 Kafka 消息的有效负载:

任一:

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. 如果我向 Kafka 发送 GenericRecord 实例,底层架构是否也会被发送?
    如果没有,什么时候被删除?哪个类/方法负责从 GenericRecord 中提取字节并删除底层架构,以便它不会与有效负载一起发送? 如果是,架构注册表的意义何在?

  2. 如果类扩展了SpecificRecord,底层模式也会被发送,不是吗?这意味着,如果我采用一个接收 Kafka 消息并计算其字节数的函数,我应该期望特定记录消息中的字节数比通用记录消息中的字节数多,对吗?

  3. SpecificRecord 实例为我提供了更多控制权,并且使用时更不容易出错。如果模式不是使用 GenericRecord 发送而是使用 SpecificRecord 发送,那么我们需要进行权衡。 一方面(SpecificRecord),由于有清晰的 API 可用,因此使用起来很简单(不必熟记所有字段,并编写 get("X")、get("Y") 等) ,另一方面,有效负载的大小会增加,因为架构必须与其一起发送。如果我有一个相对较大的架构(50 个字段),我应该选择在架构注册表的帮助下发送 GenericRecords,否则性能将会受到负面影响,因为架构必须随每条消息一起发送,对吗?

最佳答案

在通用或特定情况下,模式均由生产者发送和缓存

就性能而言,虽然我没有对它进行基准测试,但我估计两者的序列化时间大致相同,而通用的反序列化会更快,因为字段访问和类型转换将推迟到您自己的代码而不是经过验证对于每个字段

注意:还有 ReflectData 记录,由于使用反射,它可能会变慢

关于java - 使用不同 Avro 类型向 Kafka 发送消息的性能 – SpecificRecordBase 与带有 Schema Registry 的 GenericRecord,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58344763/

相关文章:

scala - Spark : Writing to Avro file

python - 在 Mac OS X 中安装 Avro

spring-boot - Spring Kafka ConsumerConfig 错误地为 value.deserializer 列出了 StringDeserializer 而不是 KafkaAvroDeserializer

java - 如何使用 JVM 参数在终端中通过 maven 运行 junit 测试

apache-kafka - 我不能跑动物园管理员

java - Apache Kafka 0.9 Java API 使用主题开头的所有消息

docker - Kafka docker镜像中的可配置延迟

java - Java 方法引用稳定吗?

Java 客户端拒绝连接到远程服务器

java - 如何在浏览器(Windows)中打开Java控制台输出窗口以进行Applet调试?