来自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
答案 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,我能够重用相同的方法来构建流。