我有一个春季应用程序,是我的kafka制作人,我想知道为什么avro是最好的选择。 我读到了它的全部内容,但是为什么我不能序列化我用杰克逊创建的POJO并将其发送给kafka?
之所以这样说,是因为avro产生的POJO并不那么直接。 最重要的是,它需要Maven插件和一个.avsc文件。
例如,我在我的kafka制作人上创建了一个名为用户的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用户并反序列化消息。 这是空间问题吗?以这种方式进行序列化和反序列化还不是更快吗?更不用说维护架构注册表的开销。
答案 0 :(得分:4)
这是速度和存储的问题。序列化数据时,通常需要传输实际的模式,因此,这会导致有效负载大小增加。
Total Payload Size
+-----------------+--------------------------------------------------+
| Schema | Serialised Data |
+-----------------+--------------------------------------------------+
模式注册表提供了用于模式和元数据的集中式存储库,以便所有模式都在中央系统中注册。这种集中式系统使生产者可以仅包括模式的ID,而不是完整的模式本身(以文本格式)。
Total Payload Size
+----+--------------------------------------------------+
| ID | Serialised Data |
+----+--------------------------------------------------+
因此,序列化变得更快。
此外,通过架构注册表版本控制,可以实施数据策略,这可能有助于防止较新的架构破坏与现有版本的兼容性,这可能会导致停机或管道中的其他任何重大问题。
this article by Confluent中详细说明了Schema Registry的其他优点。
答案 1 :(得分:2)
您不需要AVSC you can use an AVDL file,它基本上与仅包含字段的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。例如,您的can use Jackson(不仅适用于JSON),仅需要为Kafka创建一个JacksonAvroSerializer
,或者查找是否存在。
Avro也有built-in library based on reflection。
这个问题-为什么选择Avro(对于Kafka)?
嗯,拥有一个架构是一件好事。考虑一下RDBMS表,您可以解释该表,然后看到所有列。移至NoSQL文档数据库,它们实际上可以包含任何内容,这就是Kafka的JSON世界。
让我们假设您在Kafka集群中有一些消费者,他们不知道主题中的内容,他们必须确切地知道是谁/主题产生了什么。他们可以尝试使用控制台使用者,如果它是JSON之类的纯文本格式,那么他们必须找出他们感兴趣的某些字段,然后一次又一次地执行类似HashMap之类的.get("name")
操作,然后才能运行字段不存在时的NPE。使用Avro,您清楚地定义默认值和可为空的字段。
不需要使用,但是它为RDBMS类推提供了explain topic
语义类型。这也使您无需将架构与每条消息一起发送,也省去了Kafka主题上额外带宽的开销。该注册表不仅对Kafka有用,因为它可用于Spark,Flink,Hive等,用于围绕流数据提取的所有数据科学分析。
假设您确实要使用JSON,然后try using MsgPack instead,您很可能会发现Kafka吞吐量有所增加,并节省了代理上的磁盘空间
您还可以使用其他格式,例如Protobuf或Thrift,as Uber has compared
答案 2 :(得分:0)
首先-Kafka不知道键/值的内容。它操作字节,由客户(生产者/消费者)负责反序列化。
到目前为止,最常见的选项似乎是JSON,protobuf和Avro。
我个人喜欢Avro的原因,以及为什么我通常使用它并向他人推荐:
1)这是一个足够紧凑的二进制序列化,具有模式和逻辑类型(有助于区分常规的long
和timestamp in long millis
)
2)Avro模式具有很强的描述性和完善的文档记录
3)必须在大多数广泛使用的编程语言中提供广泛的支持!
4)Confluent(及其他)提供架构的存储库,即所谓的“模式注册表”,以为您的架构提供集中存储。在Avro中,该消息仅包含架构版本ID,而不包含架构本身。
5)如果您使用的是Java,则可以从模式中使用POJO基类生成。
当然可以使用其他选项来包含其中的一部分。您应该尝试比较适合您的用例的所有选项。
P.S。我非常个人的建议是:如果不是String
,请选择Avro。同时适用于键和值。