如何在kafka中定义多个序列化程序?

时间:2016-05-02 00:51:36

标签: apache-kafka kafka-consumer-api kafka-producer-api

说,我发布并使用不同类型的java对象。对于每个我必须定义自己的序列化器实现。 我们如何在“serializer.class”属性下的kafka使用者/生产者属性文件中提供所有实现?

2 个答案:

答案 0 :(得分:2)

一个选项是 Avro 。 Avro允许您定义记录类型,然后可以轻松地序列化和反序列化。

这是一个根据文档改编的示例模式:

{"namespace": "example.avro",
 "type": "record",
 "name": "User",
 "fields": [
     {"name": "name", "type": "string"},
     {"name": "favorite_number", "default": null, "type": ["null","int"]},
     {"name": "favorite_color", "default": null, "type": ["null","string"]}
 ]
}

Avro区分所谓的SpecificDataGenericData。使用SpecificData读者和编写者,您可以轻松地序列化和反序列化已知的Java对象。缺点是SpecificData需要编译时对类进行模式转换的知识。

另一方面,GenericData读者和作者可以让你处理在编译时你不知道的记录类型。虽然显然非常强大,但这有点笨拙 - 你将不得不花时间在粗糙的边缘进行编码。

还有其他选择 - Thrift浮现在脑海中 - 但据我所知,其中一个主要区别是Avro能够使用GenericData

另一个好处是多语言兼容性。我知道Avro在许多平台上都支持很多语言。其他选项也是如此,我敢肯定 - 可能任何现成的选项都比在多语言支持方面更好地推出自己的选项,这只是程度问题。

答案 1 :(得分:2)

我们在不同主题中有不同对象的类似设置,但在一个主题中始终使用相同的对象类型。我们使用Java API 0.9.0.1附带的ByteArrayDeserializer,这意味着消息使用者只获得byte[]作为消息的值部分(我们始终使用String键)。特定于主题的消息使用者做的第一件事是调用正确的反序列化器来转换byte[]。您可以使用apache commons helper class。很简单。

如果您希望让KafkaConsumer为您进行反序列化,您当然可以编写自己的Deserializer。您需要实现的deserialize方法将主题作为第一个参数。使用它作为地图的一个键,提供必要的解串器,然后离开。我的预感是,在大多数情况下,无论如何你只需要进行正常的Java反序列化。

第二种方法的缺点是,您需要为所有消息对象提供一个公共超类才能正确地参数化ConsumerRecord<K,V>。但是,第一种方法无论如何都是ConsumerRecord<String, byte[]>。但是你将byte[]转换为恰当位置所需的对象,并且只需要一个演员。