【问题标题】:Does using JSON serializer in kafka streams cause a performance hit compared to AVRO?与 AVRO 相比,在 kafka 流中使用 JSON 序列化程序会导致性能下降吗?
【发布时间】:2020-02-21 15:05:29
【问题描述】:

我在我的 Kafka Streams 应用程序中使用以下 JSON 配置,

properties.put(StreamsConfig.DEFAULT_KEY_SERDE_CLASS_CONFIG,
            Serdes.String().getClass());
properties.put(StreamsConfig.DEFAULT_VALUE_SERDE_CLASS_CONFIG,
            GenericJSONSerde.class);
properties.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG,
            com.buy.json.JsonSerializer.class);
properties.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG,
            com.buy.json.JsonDeserializer.class);
properties.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG,
            com.buy.json.JsonSerializer.class);

为了衡量性能,我删除了所有逻辑以及从 IN 主题收到的所有内容,我只是将其推送到 OUT 主题。处理350,000条记录需要3分钟

但是当我使用 AVRO 时,相同的流应用程序在 1 分钟内处理了 300 万条记录。这是我的 AVRO 配置,

  `properties.put(StreamsConfig.DEFAULT_KEY_SERDE_CLASS_CONFIG,
            Serdes.String().getClass());
    properties.put(StreamsConfig.DEFAULT_VALUE_SERDE_CLASS_CONFIG,
            GenericAvroSerde.class);
    properties.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG,
            io.confluent.kafka.serializers.KafkaAvroSerializer.class);
    properties.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG,
            io.confluent.kafka.serializers.KafkaAvroSerializer.class);
    properties.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG,
            io.confluent.kafka.serializers.KafkaAvroDeserializer.class);
    properties.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG,
            io.confluent.kafka.serializers.KafkaAvroDeserializer.class);` 

我正在编写的流应用程序应该同时支持 AVRO/JSON。我会在启动流应用程序时决定。

我的问题是:在 Streams 应用程序中使用 JSON 是否会影响性能?请澄清。

【问题讨论】:

  • 除了我的回答之外,我建议您只坚持使用 AVRO,因为它已经为您提供了类似于 JSON 的数据模式表示以及性能!
  • 对于 AVRO,我们需要专门设置一个单独的主题,但在我的情况下,在单个主题中我需要支持多种格式,这就是我们使用 JSON 的主要原因。有什么方法可以提高性能。将序列化器和反序列化器保持为字符串并在流应用程序内转换为 JSON?我迫切需要提高性能。任何帮助将不胜感激!
  • 您可以拥有一个包装类,并使用杰克逊或类似库将您的对象转换为逻辑层中的字符串。使用 AVRO 发布包装对象,并在消费者端使用 jackson 将字符串值转换为对象。对于正确的转换,您可以在包装器对象中保存一个类名。另外,我建议您针对相同的问题发布不同的问题。
  • 如果任何一个答案给出了你的答案,请标记它。

标签: json apache-kafka apache-kafka-streams


【解决方案1】:

注意:在 Confluent 的模式注册表中,模式首先通过 HTTP 发送,如 cmets 中所述。

AVRO 显然很快,因为它提供了一种紧凑的二进制数据格式。在序列化过程中有一个动态类型和标记数据的概念。

在 AVRO 的情况下,数据和模式(以 JSON 的形式)总是在一起,因此反序列化期间数据类型信息的大小会变小,更好地处理静态数据类型并减少代码生成。

这在 JSONSerializer 的情况下不存在。

【讨论】:

  • 不过,当使用架构注册表时,架构是通过 HTTP 向外部发送的,因此初始往返调用的性能会略有下降。
  • @cricket_007 这意味着如果负载较小,性能结果可能会有所不同?
  • 负载是可变的,当然。我只是参考您关于 Avro JSON 模式与消息一起发送的评论,在使用 Confluent Avro 序列化程序时这是不正确的
【解决方案2】:

与 AVRO 相比,JSON 通常可能较慢,因为 JSON 是基于文本的格式,而 AVRO 是二进制格式。这独立于 Kafka Streams。

JSON 编码的数据量一般较大,影响网络传输吞吐量。 AVRO 通常可能比 JSON 更快地反序列化。

有关更多信息,请参阅以下 2017 年的比较:https://labs.criteo.com/2017/05/serialization/

【讨论】:

  • 在序列化期间,基于文本的格式也会转换为二进制文件。唯一的区别是 AVRO 在其二进制版本中“更”紧凑,因为数据模式也可用,这会导致更少的处理和更快的结果
猜你喜欢
  • 1970-01-01
  • 2018-08-11
  • 1970-01-01
  • 2020-06-25
  • 2013-05-17
  • 2019-11-18
  • 2017-08-31
  • 1970-01-01
  • 2021-03-11
相关资源
最近更新 更多