Kafka流窗口批处理

时间:2018-05-22 18:07:12

标签: apache-kafka-streams

来自Spark Streaming背景 - 掌握Kafka流。

我有一个简单的Spark Streaming应用程序,可以从Kafka中读取,

并返回该分钟内每位用户的最新事件

示例事件看起来像{"user": 1, "timestamp": "2018-05-18T16:56:30.754Z", "count": 3}, {"user": 1, "timestamp": "2018-05-22T16:56:39.754Z", "count": 4}

我对Kafka Streams的工作原理感兴趣,因为似乎每个事件都有一个输出 - 当我的用例是减少流量时。

从我的阅读到目前为止,似乎这不是直接的,你必须使用处理器API。

理想情况下,我想使用DSL而不是处理器API,因为我刚刚开始查看Kafka流,但似乎我必须使用处理器API的punctuate方法来读取每隔n秒进行一次状态存储?

我正在使用kafka 0.11.0

2 个答案:

答案 0 :(得分:2)

在DSL级别,Kafka Streams允许配置减少下游负载的KTable缓存(默认启用)。缓存是一个定期刷新的LRU缓存。因此,虽然缓存减少了下游负载,但它并不能保证每个窗口有多少输出。 (参见https://docs.confluent.io/current/streams/developer-guide/memory-mgmt.html

如果每个窗口严格需要单个输出,则使用Processor API是正确的方法。

答案 1 :(得分:0)

我自己还没有尝试过,但是 Kafka Streams 现在支持 suppress 操作。看看here

<块引用>

您可以使用 Suppress 来有效地限制仅一个 KTable 输出的速率 或回调。或者,对于不可收回的输出特别有价值,例如 警报,您可以使用它来仅获取窗口化的最终结果 聚合。目前 Suppress 最清晰的用例是 得到最终结果

根据文章,代码可以如下所示:

events
  .groupByKey()
  .windowedBy(
    TimeWindows.of(Duration.ofMinutes(2).withGrace(Duration.ofMinutes(2))
  )
  .count(Materialized.as("count-metric"))
  .suppress(Suppressed.untilWindowClose(BufferConfig.unbounded()))
  .filter( _ < 4 )
  .toStream()
  .foreach( /* Send that email! */)

我使用的是 Kafka Streams 2.6.0,我能够重用相同的方法来构建流。