首页 文章

Kafka流聚合:如何忽略Window的中间聚合结果

提问于
浏览
0

我们使用 kafka-stream 聚合和时间窗口来计算事件的结束总和 . 我们已经实现了我们的要求,但我们遇到了中间聚合结果的问题 . 根据Kafka内存管理文档(https://kafka.apache.org/11/documentation/streams/developer-guide/memory-mgmt.html),似乎没有办法丢弃影响最终结果的这些中间结果 . 请考虑以下来自上述文档的说明 .

使用以下示例来了解有和没有记录缓存的行为 . 在此示例中,输入是KStream <String,Integer>,其记录为<K,V>:<A,1>,<D,5>,<A,20>,<A,300> . 此示例中的焦点位于带有键== A的记录上 . 聚合计算输入的按键分组的记录值总和,并返回KTable <String,Integer> . 不进行缓存:为密钥A发出一系列输出记录,表示生成的聚合表中的更改 . 括号(())表示更改,左边的数字是新的聚合值,右边的数字是旧的聚合值:<A,(1,null)>,<A,(21,1)>,<A, (321,21)> . 使用缓存:为密钥A发出单个输出记录,该密钥可能会在缓存中被压缩,从而导致单个输出记录<A,(321,null)> . 此记录将写入聚合的内部状态存储并转发到任何下游操作 . 缓存大小通过cache.max.bytes.buffering参数指定,该参数是每个处理拓扑的全局设置:

根据文档,在没有缓存输出记录的情况下使用聚合时会产生增量结果 . (我们注意到,即使有缓存,有时也会发生这种情况) . 我们的问题是我们有其他应用程序作用于这些输出聚合并进行一些计算 . 因此,当输出具有中间聚合时,这些其他计算出错 . 例如,当我们有 <A (21,1)> 事件时,我们可能会开始计算其他东西(正确的计算应该在 <A (321, null)> 那个时间窗口完成 .

我们的要求是仅对该窗口的最终聚合进行其他计算 . 我们有关于kafka流聚合的以下问题

  • 当kakfa输出中间结果时,那些输出是否已经汇总了数据?例如,考虑输出 <A, (1, null)>, <A, (21, 1)>, <A, (321, 21)> . 第二个输出事件 <A, (21, 1)> 是第三个输出 <A, (321, 21)> 已经聚合了值 . 它是否正确 ?

  • 有没有办法识别窗口的中间结果?

1 回答

  • 2

    要记住的另一件事是提交时间间隔 and 缓存大小控制结果向下游转发的时间 .

    例如,如果您的提交间隔为10秒,则表示缓存中的结果将被转发(并且如果启用了日志记录,则会写入changelog主题),无论缓存是否已满 .

    因此,如果您可以将内存设置得足够高,以支持将提交间隔设置为所需的窗口时间,那么您可以近似单个最终结果 . 当然,这是一种粗粒度的方法并影响整个拓扑,因此您需要考虑并可能对示例应用程序进行原型设计,以确定此方法是否适合您 .

相关问题