Kafka 0.8V
我想发布/使用byte []对象,java bean对象,可序列化对象等等。
为此类型方案定义发布者和使用者的最佳方法是什么? 当我从消费者迭代器中使用消息时,我不知道它是什么类型的消息。 有人能指点我如何设计这样的场景吗?
答案 0 :(得分:4)
我根据Kafka主题强制执行单个架构或对象类型。这样,当您收到消息时,您确切地知道您将获得什么。
至少,您应该决定某个主题是保留binary
还是string
数据,并视具体情况而定,如何进一步编码。
例如,您可以将名为 Schema 的主题包含JSON
- 以字符串形式存储的编码对象。
如果您使用JSON
和JavaScript之类的松散类型的语言,那么在同一主题中存储具有不同模式的不同对象可能很诱人。使用JavaScript,您只需调用JSON.parse(...)
,即可查看生成的对象,并找出您要对其执行的操作。
但是你不能用像Scala这样的严格类型的语言来做到这一点。 Scala JSON解析器通常希望您将JSON解析为已定义的Scala类型,通常为case class
。它们不适用于此模型。
一种解决方案是保留一个模式/一个主题规则,但作弊一点:将对象包装在一个对象中。典型的示例是 Action 对象,其中您有一个描述操作的标头,以及一个具有依赖于标头中列出的操作类型的模式的有效负载对象。想象一下这个伪模式:
{name: "Action", fields: [
{name: "actionType", type: "string"},
{name: "actionObject", type: "string"}
]}
这样,即使是强类型语言,您也可以执行以下操作(同样这是伪代码):
action = JSONParser[Action].parse(msg)
switch(action.actionType) {
case "foo" => var foo = JSONParser[Foo].parse(action.actionObject)
case "bar" => var bar = JSONParser[Bar].parse(action.actionObject)
}
这种方法的一个巧妙之处在于,如果您的消费者只等待特定的action.actionType
,并且只是忽略所有其他消费者,那就很漂亮轻量级,它只解码标题并推迟解码action.actionObject
,直到需要时为止。
到目前为止,这一切都是关于字符串编码的数据。如果您想使用二进制数据,当然您也可以将其包装在JSON中,或者包含任何基于字符串的编码(如XML)。但是也有很多二进制编码系统,比如Thrift和 Avro 。实际上,上面的伪模式基于Avro。你甚至可以在Avro中做一些很酷的事情,比如模式演化,除了其他方面提供了一种非常灵活的方式来处理上面的Action
用例 - 你可以定义一个模式,而不是将一个对象包装在一个对象中。其他模式的子集,只解码您想要的字段,在本例中只是action.actionType
字段。以下是 schema evolution 的精彩描述。
简而言之,我建议的是: