[英]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 |
+----+--------------------------------------------------+
因此,序列化变得更快。
此外,架构注册表版本控制可以实施数据策略,这些策略可能有助于防止较新的架构破坏与现有版本的兼容性,这些版本可能会导致停机或管道中的任何其他重大问题。
你不需要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吞吐量增加并节省了代理上的磁盘空间
首先 - 卡夫卡不知道关键/价值内容。 它操作字节,它的客户端(生产者/消费者)负责照顾de / serialization。
到目前为止,最常见的选项似乎是JSON,protobuf和Avro。
我个人喜欢Avro以及为什么我经常使用它并推荐给其他人:
1)这是一个足够紧凑的二进制序列化,具有模式和逻辑类型 (有助于区分timestamp in long millis
的常规long
和timestamp in long millis
)
2)Avro模式非常具有描述性并且完整记录
3)大多数广泛使用的编程语言都是必须的!
4)Confluent(和其他)为模式提供存储库,即所谓的“模式注册表”,以便为模式提供集中存储。 在Avro中,消息仅包含架构版本ID,而不包含架构本身。
5)如果您使用的是Java,那么使用模式中的POJO基类生成可以获得很大的好处。
当然,您可以将其中的一部分与其他选项一起使用。 您应该尝试比较适合您的用例的所有选项。
PS我非常个人的建议是:如果不是String
,请选择Avro。 适用于键和值。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.