为什么将 Avro 与 Kafka 一起使用 - 如何处理 POJO
Why use Avro with Kafka - How to handle POJOs
我有一个 spring 应用程序,它是我的 kafka 生产者,我想知道为什么 avro 是最好的选择。
我阅读了它及其提供的所有内容,但为什么我不能序列化我自己用 jackson 创建的 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 用户并反序列化消息。
是space的问题吗?这样序列化和反序列化不是也更快吗?更不用说维护架构注册表的开销了。
这是速度和存储的问题。序列化数据时,您通常需要传输实际模式,因此这会导致负载大小增加。
Total Payload Size
+-----------------+--------------------------------------------------+
| Schema | Serialised Data |
+-----------------+--------------------------------------------------+
Schema Registry 为模式和元数据提供了一个集中存储库,以便所有模式都在中央系统中注册。这个集中式系统使生产者能够只包含模式的 ID 而不是完整的模式本身(文本格式)。
Total Payload Size
+----+--------------------------------------------------+
| ID | Serialised Data |
+----+--------------------------------------------------+
因此,序列化变得更快。
此外,架构注册表版本控制可以强制执行数据策略,这可能有助于防止较新的架构破坏与现有版本的兼容性,这可能会导致停机或管道中出现任何其他重大问题。
this article by Confluent 中详细解释了 Schema Registry 的更多好处。
首先 - Kafka 不知道 key/value 内容。它操作字节,它的客户端 (producer/consumer) 负责处理 de/serialization.
到目前为止最常见的选项似乎是 JSON、protobuf 和 Avro。
我个人喜欢 Avro 的地方以及为什么我经常使用它并推荐给其他人:
1) 这是一个足够紧凑的二进制序列化,具有模式和 逻辑类型 (这有助于区分常规 long
和 timestamp in long millis
)
2) Avro 模式非常具有描述性和完美的文档
3) 必须得到大多数广泛使用的编程语言的广泛支持!
4) Confluent(和其他)为模式提供了一个存储库,即所谓的 "schema registry",以便为您的模式提供集中存储。在 Avro 中,消息仅包含架构版本 ID,而不包含架构本身。
5) 如果您使用的是 Java,则可以从架构中使用 POJO 基础 class 生成获得很大的好处。
当然,您可以将其中的一部分与其他选项一起使用。您应该尝试比较适合您的用例的所有选项。
P.S。我非常个人的固执己见的建议是:如果它不是 String
,请选择 Avro。适用于键和值。
您不需要 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 tables,你可以解释 table,你会看到所有的列。转向 NoSQL 文档数据库,它们几乎可以包含任何内容,这就是 Kafka 的 JSON 世界。
假设您的 Kafka 集群中有消费者不知道主题中有什么,他们必须确切地知道 who/what 已生成主题。他们可以尝试console consumer,如果是像JSON这样的明文,那么他们就得弄清楚一些他们感兴趣的字段,然后一次又一次地执行flaky HashMap-like .get("name")
操作,只有当字段不存在时将 运行 转换为 NPE。使用 Avro,您可以清楚地定义 默认值和可为空的字段。
您不需要 使用架构注册表,但它为 RDBMS 类比提供了那种类型的 explain topic
语义。它还使您无需将模式与每条消息一起发送,以及 Kafka 主题的额外带宽费用。不过,注册表不仅对 Kafka 有用,因为它可用于 Spark、Flink、Hive 等围绕流数据摄取的所有数据科学分析。
假设您确实想使用 JSON,然后 try using MsgPack instead,您可能会看到 Kafka 吞吐量增加并在代理上节省磁盘 space
您还可以使用其他格式,例如 Protobuf 或 Thrift,正如 Uber 所比较的那样
我有一个 spring 应用程序,它是我的 kafka 生产者,我想知道为什么 avro 是最好的选择。 我阅读了它及其提供的所有内容,但为什么我不能序列化我自己用 jackson 创建的 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 用户并反序列化消息。 是space的问题吗?这样序列化和反序列化不是也更快吗?更不用说维护架构注册表的开销了。
这是速度和存储的问题。序列化数据时,您通常需要传输实际模式,因此这会导致负载大小增加。
Total Payload Size
+-----------------+--------------------------------------------------+
| Schema | Serialised Data |
+-----------------+--------------------------------------------------+
Schema Registry 为模式和元数据提供了一个集中存储库,以便所有模式都在中央系统中注册。这个集中式系统使生产者能够只包含模式的 ID 而不是完整的模式本身(文本格式)。
Total Payload Size
+----+--------------------------------------------------+
| ID | Serialised Data |
+----+--------------------------------------------------+
因此,序列化变得更快。
此外,架构注册表版本控制可以强制执行数据策略,这可能有助于防止较新的架构破坏与现有版本的兼容性,这可能会导致停机或管道中出现任何其他重大问题。
this article by Confluent 中详细解释了 Schema Registry 的更多好处。
首先 - Kafka 不知道 key/value 内容。它操作字节,它的客户端 (producer/consumer) 负责处理 de/serialization.
到目前为止最常见的选项似乎是 JSON、protobuf 和 Avro。
我个人喜欢 Avro 的地方以及为什么我经常使用它并推荐给其他人:
1) 这是一个足够紧凑的二进制序列化,具有模式和 逻辑类型 (这有助于区分常规 long
和 timestamp in long millis
)
2) Avro 模式非常具有描述性和完美的文档
3) 必须得到大多数广泛使用的编程语言的广泛支持!
4) Confluent(和其他)为模式提供了一个存储库,即所谓的 "schema registry",以便为您的模式提供集中存储。在 Avro 中,消息仅包含架构版本 ID,而不包含架构本身。
5) 如果您使用的是 Java,则可以从架构中使用 POJO 基础 class 生成获得很大的好处。
当然,您可以将其中的一部分与其他选项一起使用。您应该尝试比较适合您的用例的所有选项。
P.S。我非常个人的固执己见的建议是:如果它不是 String
,请选择 Avro。适用于键和值。
您不需要 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 tables,你可以解释 table,你会看到所有的列。转向 NoSQL 文档数据库,它们几乎可以包含任何内容,这就是 Kafka 的 JSON 世界。
假设您的 Kafka 集群中有消费者不知道主题中有什么,他们必须确切地知道 who/what 已生成主题。他们可以尝试console consumer,如果是像JSON这样的明文,那么他们就得弄清楚一些他们感兴趣的字段,然后一次又一次地执行flaky HashMap-like .get("name")
操作,只有当字段不存在时将 运行 转换为 NPE。使用 Avro,您可以清楚地定义 默认值和可为空的字段。
您不需要 使用架构注册表,但它为 RDBMS 类比提供了那种类型的 explain topic
语义。它还使您无需将模式与每条消息一起发送,以及 Kafka 主题的额外带宽费用。不过,注册表不仅对 Kafka 有用,因为它可用于 Spark、Flink、Hive 等围绕流数据摄取的所有数据科学分析。
假设您确实想使用 JSON,然后 try using MsgPack instead,您可能会看到 Kafka 吞吐量增加并在代理上节省磁盘 space
您还可以使用其他格式,例如 Protobuf 或 Thrift,正如 Uber 所比较的那样