繁体   English   中英

为什么将Avro与Kafka一起使用 - 如何处理POJO

[英]Why use Avro with Kafka - How to handle POJOs

我有一个春季应用程序,是我的kafka制作人,我想知道为什么avro是最好的方式去。 我读到了它以及它所提供的一切,但为什么我不能将我自己用杰克逊创建的POJO序列化并将其发送给kafka?

我这样说是因为avro的POJO代并不是那么直截了当。 最重要的是,它需要maven插件和.avsc文件。

所以例如我在我的kafka制作人上创建了一个名为User的POJO:

public class User {

    private long    userId;

    private String  name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public long getUserId() {
        return userId;
    }

    public void setUserId(long userId) {
        this.userId = userId;
    }

}

我将其序列化并将其发送到我在kafka中的用户主题。 然后我有一个消费者,它本身有一个POJO用户并反序列化该消息。 这是空间问题吗? 以这种方式序列化和反序列化也不是更快吗? 更不用说维护模式注册表有一个开销。

这是速度和存储的问题。 在序列化数据时,您经常需要传输实际模式,因此会导致有效负载大小的增加。

                            Total Payload Size
+-----------------+--------------------------------------------------+
|     Schema      |                 Serialised Data                  |
+-----------------+--------------------------------------------------+

Schema Registry为模式和元数据提供集中存储库,以便所有模式都在中央系统中注册。 这个集中式系统使生产者只能包含模式的ID而不是完整模式本身(文本格式)。

                      Total Payload Size
+----+--------------------------------------------------+
| ID |                 Serialised Data                  |
+----+--------------------------------------------------+

因此,序列化变得更快。

此外,架构注册表版本控制可以实施数据策略,这些策略可能有助于防止较新的架构破坏与现有版本的兼容性,这些版本可能会导致停机或管道中的任何其他重大问题。


Confluent本文中详细解释了Schema Registry的一些其他好处。

你不需要AVSC, 你可以使用AVDL文件 ,它基本上看起来像只有字段的POJO

@namespace("com.example.mycode.avro")
protocol ExampleProtocol {
   record User {
     long id;
     string name;
   }
}

当使用Maven插件的idl-protocol目标时,将为您创建此AVSC,而不是您自己编写它。

{
  "type" : "record",
  "name" : "User",
  "namespace" : "com.example.mycode.avro",
  "fields" : [ {
    "name" : "id",
    "type" : "long"
  }, {
    "name" : "name",
    "type" : "string"
  } ]
}

它还会在您的类路径中放置一个SpecificData POJO User.java ,以便在您的代码中使用。


如果您已经有POJO,则无需使用AVSC或AVDL文件。 有转换POJO的库。 例如,你可以使用 Jackson ,它不仅仅是JSON,你只需要为Kafka创建一个JacksonAvroSerializer ,或者查找是否存在。

Avro还具有基于反射的内置库


那么问题 - 为什么Avro(对于Kafka)?

好吧,拥有一个架构是一件好事 想想RDBMS表,你可以解释一下表,然后你会看到所有的列。 转移到NoSQL文档数据库,它们可以包含任何内容,这就是Kafka的JSON世界。

假设您的Kafka群集中的消费者不知道主题中的内容,他们必须确切地知道主题中产生了谁/什么。 他们可以尝试控制台消费者,如果它是像JSON这样的明文,那么他们必须弄清楚他们感兴趣的一些字段,然后一次又一次地执行类似HashMap的.get("name")操作,只运行当一个字段不存在时进入NPE。 使用Avro,您可以清楚地定义默认值和可空字段。

不需要使用模式注册表,但它为RDBMS类比提供了这种类型的explain topic语义。 它还使您无需发送架构以及每条消息,以及Kafka主题上额外带宽的费用。 注册表不仅对Kafka有用,因为它可以用于Spark,Flink,Hive等所有围绕流数据摄取的数据科学分析。


假设您确实想要使用JSON,那么请尝试使用MsgPack ,您可能会看到Kafka吞吐量增加并节省了代理上的磁盘空间


你可以使用其他格式,如Protobuf或Thrift, 正如Uber所做的那样

首先 - 卡夫卡不知道关键/价值内容。 它操作字节,它的客户端(生产者/消费者)负责照顾de / serialization。

到目前为止,最常见的选项似乎是JSON,protobuf和Avro。

我个人喜欢Avro以及为什么我经常使用它并推荐给其他人:

1)这是一个足够紧凑的二进制序列化,具有模式和逻辑类型 (有助于区分timestamp in long millis的常规longtimestamp in long millis

2)Avro模式非常具有描述性并且完整记录

3)大多数广泛使用的编程语言都是必须的!

4)Confluent(和其他)为模式提供存储库,即所谓的“模式注册表”,以便为模式提供集中存储。 在Avro中,消息仅包含架构版本ID,而不包含架构本身。

5)如果您使用的是Java,那么使用模式中的POJO基类生成可以获得很大的好处。

当然,您可以将其中的一部分与其他选项一起使用。 您应该尝试比较适合您的用例的所有选项。

PS我非常个人的建议是:如果不是String ,请选择Avro。 适用于键和值。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM