apache-kafka - Kafka Streams:处理来自不同分区的消息时的事件时间偏差
问题描述
让我们考虑一个具有多个分区和按事件时间顺序编写的消息的主题,而没有任何特定的分区方案。Kafka Streams 应用程序对这些消息进行一些转换,然后按某个键进行分组,然后通过具有给定宽限期的事件时间窗口聚合消息。
每个任务可以以不同的速度处理传入的消息(例如,因为在具有不同性能特征的服务器上运行)。这意味着在 groupBy shuffle 之后,当消息来自不同任务时,将不会在内部主题的同一分区中的消息之间保留事件时间排序。一段时间后,此事件时间偏差可能会变得大于宽限期,这将导致丢弃源自滞后任务的消息。
增加宽限期似乎不是一个有效的选项,因为它会延迟发出最终聚合结果。Apache Flink 通过在分区合并时发出最低水印来处理这个问题。
这应该是一个真正的问题,尤其是在处理大量历史数据时,还是我错过了什么?Kafka Streams 是否提供处理这种情况的解决方案?
更新我的问题不是关于 KStream-KStream 连接,而是关于单个 KStream 事件时间聚合,然后是流洗牌。
考虑这个代码片段:
stream
.mapValues(...)
.groupBy(...)
.windowedBy(TimeWindows.of(Duration.ofSeconds(60)).grace(Duration.ofSeconds(10)))
.aggregate(...)
我假设无论出于何种原因,某些任务的 mapValues() 操作可能会很慢,因此任务确实以不同的速度处理消息。当操作员发生 shuffle 时aggregate()
,任务 0 可能已经处理了消息,t
而任务 1 仍然在t-skew
,但是来自两个任务的消息最终交错在内部主题的单个分区中(对应于分组键)。
我担心的是,当 skew 足够大(在我的示例中超过 10 秒)时,来自滞后任务 1 的消息将被丢弃。
解决方案
基本上,一个任务/处理器维护一个流时间,它被定义为已经轮询的任何记录的最高时间戳。然后,这个流时间在 Kafka Streams 中用于不同的目的(例如:Punctator、Windowded Aggregation 等)。
[窗口聚合]
正如您所提到的,流时间用于确定是否应接受记录,即 record_accepted = end_window_time(current record) + grace_period > observed stream_time
。
正如您所描述的,如果多个任务并行运行以基于分组键对消息进行混洗,并且某些任务比其他任务慢(或某些分区处于脱机状态),这将创建无序消息。不幸的是,恐怕解决这个问题的唯一方法就是增加grace_period
.
这实际上是可用性和一致性之间的永恒权衡。
[ KafkaStream 和 KafkaStream/KTable Join 的行为
当您使用 Kafka Streams 执行连接操作时,内部任务将分配给多个共同分区主题的“相同”分区。例如,任务 0 将分配给 Topic1-Partition0 和 TopicB-Partition0。
提取的记录按分区缓冲到由任务管理的内部队列中。因此,每个队列都包含等待处理的单个分区的所有记录。
然后,从队列中逐一轮询记录并由拓扑实例处理。但是,这是来自非空队列的记录,具有从轮询返回的最低时间戳。
此外,如果队列为空,则任务可能会在一段时间内变得空闲,从而不再从队列中轮询记录。您实际上可以配置任务保持空闲的最长时间,可以使用流配置定义:max.task.idle.ms
这种机制允许同步共定位分区。Bu,默认max.task.idle.ms
设置为 0。这意味着任务永远不会等待来自分区的更多数据,这可能导致记录被过滤,因为流时间可能会更快地增加。
推荐阅读
- azure-functions - 禁止直接从 Visual Studio Code 发布 Azure Function
- c# - 启动延迟任务
- kendo-ui-angular2 - 如何在 Kendo Scheduler 中隐藏当月以外的日期?(剑道 UI 角度)
- visual-studio-2019 - Visual Studio 开始调试弹出选择 json 架构窗口
- antlr - ANTLR4 语法 - 字段和扩展表达式中的“点”问题
- python - python字典操作面临的问题
- r - 使用 quantmod 使用 R 下载多个股票月度价格
- fft - 为什么 Tensorflow.js fftSize 与 Web Audio API fftSize 相差两倍?
- jdbc - 如何保护与 Teradata DB 的 jdbc 连接
- autohotkey - 按进程名称在窗口上激活 WinActivate?