首页 > 解决方案 > Kafka Stream:KTable物化

问题描述

如何识别主题的 KTable 物化何时完成?

例如,假设 KTable 有几百万行。伪代码如下:

KTable<String, String> kt = kgroupedStream.groupByKey(..).reduce(..); //Assume this produces few million rows

在某个时间点,我想安排一个线程来调用以下内容,写入主题: kt.toStream().to("output_topic_name");

我想确保所有数据都作为上述调用的一部分写入。此外,一旦调用了上述“to”方法,是否可以在下一个计划中调用它,或者第一个调用是否始终保持活动状态?

后续问题:

约束
1) 好的,我看到一旦 kafkastream 启动,kstream 和 ktable 是无限的/无限的。但是,ktable 物化(到压缩主题)不会在指定时间段内为同一个键发送多个条目。

因此,除非压缩过程尝试清理这些并仅保留最新的,否则下游应用程序将消耗来自主题的相同键查询的所有可用条目,从而导致重复。即使压缩过程进行了某种程度的清理,在给定的时间点,随着压缩过程的追赶,总是不可能有一些键具有多个条目。

我假设 KTable 对于 RocksDB 中的给定键只有一条记录。如果我们有办法安排实现,这将有助于避免重复。此外,减少主题中持久化的数据量(增加存储),增加网络流量,清理压缩过程的额外开销。

2) 也许 ReadOnlyKeyValueStore 将允许从存储中进行受控检索,但它仍然缺乏安排检索键、值和写入主题的方法,这需要额外的编码。

是否可以改进 API 以实现受控实现?

标签: apache-kafkaapache-kafka-streams

解决方案


KTable 物化永远不会完成,您也不能“调用”a to()

当您使用 Streams API 时,您“插入”了一个 DAG 运算符。实际的方法调用,不会触发任何计算,而是修改操作符的 DAG。

只有在您开始计算后,KafkaStreams#start()才会处理数据。请注意,您指定的所有运算符将在计算开始后连续并发运行。

没有“计算结束”,因为输入预计是无界/无限的,因为上游应用程序可以随时将新数据写入输入主题。因此,您的程序永远不会自行终止。KafkaStreams#close()如果需要,您可以通过虽然停止计算。

在执行期间,您无法更改 DAG。如果要更改它,则需要停止计算并创建一个KafkaStreams以修改后的 DAG 作为输入的新实例

跟进:

是的。您必须将 KTable 视为随着条目更新而随时间演变的“版本化表”。因此,所有更新都写入更改日志主题并作为更改记录发送到下游(请注意,KTables 也会进行一些缓存,以“消除重复”对同一键的连续更新:参见https://docs.confluent .io/current/streams/developer-guide/memory-mgmt.html)。

将消耗来自主题的相同键查询的所有可用条目,从而导致重复。

我不会将它们视为“重复”,而是将其视为更新。是的,应用程序需要能够正确处理这些更新。

如果我们有办法安排实现,这将有助于避免重复。

物化是一个持续的过程,只要输入主题中有新的输入记录并进行处理,就会更新 KTable。因此,在任何时间点都可能会更新特定密钥。因此,即使您可以完全控制何时向变更日志主题和/或下游发送更新,稍后也可能会有新的更新。这就是流处理的本质。

此外,减少主题中持久化的数据量(增加存储),增加网络流量,清理压缩过程的额外开销。

如上所述,缓存是用来节省资源的。

是否可以改进 API 以实现受控实现?

如果提供的 KTable 语义不符合您的要求,您始终可以将自定义运算符编写为Processoror Transformer,将键值存储附加到它,然后实现您需要的任何内容。


推荐阅读