java - 为什么将 Avro 与 Kafka 一起使用 - 如何处理 POJO
问题描述
我有一个 spring 应用程序,它是我的 kafka 生产者,我想知道为什么 avro 是最好的方法。我阅读了它以及它所提供的所有内容,但是为什么我不能序列化我用杰克逊自己创建的 POJO 并将其发送到 kafka?
我这么说是因为 avro 的 POJO 生成并不是那么直接。最重要的是,它需要 maven 插件和 .avsc 文件。
因此,例如,我的 kafka 制作人有一个 POJO,我自己创建了一个名为 User:
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 用户并反序列化消息。是空间的问题吗?以这种方式序列化和反序列化也不是更快吗?更不用说维护模式注册表的开销了。
解决方案
您不需要 AVSC,您可以使用 AVDL 文件,它基本上看起来与 POJO 相同,只有字段
@namespace("com.example.mycode.avro")
protocol ExampleProtocol {
record User {
long id;
string name;
}
}
哪个,当使用idl-protocol
Maven 插件的目标时,将为您创建这个 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,您可能只需要JacksonAvroSerializer
为 Kafka 创建一个,或者查找是否存在。
Avro 还具有基于反射的内置库。
那么问题来了——为什么是 Avro(对于 Kafka)?
好吧,拥有架构是一件好事。想想 RDBMS 表,您可以解释该表,并且您会看到所有列。转移到 NoSQL 文档数据库,它们几乎可以包含任何内容,这就是 Kafka 的 JSON 世界。
假设您的 Kafka 集群中有消费者不知道主题中的内容,他们必须确切知道主题中产生了谁/什么。他们可以尝试控制台消费者,如果是像 JSON 这样的明文,那么他们必须找出他们感兴趣的一些字段,然后一次又一次地执行类似 HashMap 的片状.get("name")
操作,只有在字段不存在时才会遇到 NPE不存在。使用 Avro,您可以清楚地定义默认值和可为空的字段。
您不需要使用模式注册表,但它为explain topic
RDBMS 类比提供了这种类型的语义。它还使您无需将模式与每条消息一起发送,以及 Kafka 主题的额外带宽费用。不过,注册表不仅对 Kafka 有用,因为它可以用于 Spark、Flink、Hive 等,用于围绕流数据摄取的所有数据科学分析。
假设您确实想使用 JSON,然后尝试改用 MsgPack,您可能会看到 Kafka 吞吐量增加并节省代理上的磁盘空间
您还可以使用其他格式,如 Uber 比较过的 Protobuf 或 Thrift
推荐阅读
- python - 使用python连续处理日志文件并提取所需数据
- typescript - 如何在 TypeScript 中正确合并来自 NPM 模块的接口?
- reactjs - 持久复选框位置
- android - 如何通过 Android 应用程序向 Google IoT 核心创建设备?
- javascript - 在提交 JavaScript 时重定向到另一个页面
- javascript - 从d3中的节点获取转换
- angular - 如何在 Angular 8 中进行嵌套自定义验证
- javascript - Vue 道具在 $router.go(-1) 上变为空
- c# - 如何避免转换到特定接口
- javascript - 如何减小从 react-native-image-picker 获取的 base64 图像的大小,以使用 react native 将其保存在 firebase