繁体   English   中英

Kafka在一个主题中流化多个对象并反序列化

[英]Kafka Streams multiple objects in a topic and deserizalization

在我的kafka stream应用程序中,我将一个主题用于多种对象类型,并以JSON序列化。 我使用类名作为关键字,我的想法是,消费者将仅通过关键字过滤传入条目的子集,然后从JSON反序列化它们。 我假设我可以在不定义Serdes的情况下应用初始过滤,但是在这种情况下,源流被推断为<Object,Object> ,并且以下代码无法编译:

 return streamsBuilder.stream("topic")
            .filter((k, v) -> k.equals("TestClassA"))
            .groupByKey()
            .reduce((oldValue, newValue) -> newValue,
                    Materialized.<String, TestClassA, KeyValueStore<Bytes, byte[]>>as(StoreManager.STORE_NAME)
                    .withKeySerde(Serdes.String())
                    .withValueSerde(new JsonSerde<>(TestClassA.class)));

如果将类型添加到流定义中,它将编译:

return streamsBuilder.stream(businessEntityTopicName, Consumed.with(Serdes.String(), new JsonSerde<>(TestClassA.class))) {...}

但是在这种情况下,例如当TestClassB的对象出现在主题中时,我会遇到运行时异常。 在这种情况下的最佳做法是什么?我应该对不同的对象使用不同的主题吗?

如果您未在#stream()指定任何Serde并且未覆盖StreamsConfig的默认StreamsConfig Kafka Streams将使用字节数组Serdes。 因此,您将获得

KStream<byte[], byte[]> streams = builder.<byte[], byte[]>stream("topicName");

请注意,如果您没有在右侧显示如上所示的正确类型,则Java本身会退回到KStream<Object, Object> 但是在两种情况下,运行时的实际类型都是byte[]

因此,您可以应用过滤器,但是它需要处理byte[]数据类型。

我想,您实际要做的只是为密钥指定一个StringSerde

KStream<String, byte[]> streams = builder.<String, byte[]>("topicName", Consumed.with(Serdes.String(), null)); // null with fall back to defaul Serde from StreamConfig

这允许您在groupByKey()操作之前基于String键应用filter()

我有一个类似的用例。 我让所有可能的对象继承一个公共接口(事件),并使用@JsonTypeInfo进行注释,以便jackson可以正确地反序列化该对象。

streamsBuilder.stream("topic")//need to add some sort of JSONSerde<Event> to this stream call, i use personally use the one bundled with spring
            .filter((k, v) -> v instanceOf testClassA)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM