Apache kafka 避免写入Kafka Streams中的中间聚合存储

Apache kafka 避免写入Kafka Streams中的中间聚合存储,apache-kafka,apache-kafka-streams,Apache Kafka,Apache Kafka Streams,在我的情况下,我正在执行跳跃窗口,例如(100秒,1秒) KTable WinMinMax=Records.groupByKey().aggregate(新的aggt初始化器(), 新的minMaxCalculator() ,TimeWindows.of(TimeUnit.SECONDS.toMillis(100)).advanceBy(TimeUnit.SECONDS.toMillis(1)),aggrMessageSerde); 但在这里,100秒窗口中的消息数量非常大,这导致窗口执行需要

在我的情况下,我正在执行
跳跃窗口
,例如
(100秒,1秒)

KTable WinMinMax=Records.groupByKey().aggregate(新的aggt初始化器(),
新的minMaxCalculator()
,TimeWindows.of(TimeUnit.SECONDS.toMillis(100)).advanceBy(TimeUnit.SECONDS.toMillis(1)),aggrMessageSerde);
但在这里,100秒窗口中的消息数量非常大,这导致窗口执行需要花费大量时间。所以,为了提高这个窗口的执行时间

  • 我希望避免将数据写入中间聚合状态存储(卡夫卡流在默认情况下写入)
  • 另外,如果(1)不可能,那么我们可以将窗口生成的中间聚合状态存储在RAM中而不是磁盘中吗?(相同的设置是什么?)
  • 是否有进一步的建议来改进窗口执行时间

  • 不确定您是如何实现
    MinMaxCalculator()
    的,但我假设它只是将当前的最小值/最大值与新值进行比较。因此,存储区仅包含当前聚合。-因此,窗口大小根本不重要,因为与窗口大小无关,您只存储键和当前聚合结果

    要回答您的问题:

  • 根据设计,聚合需要一个存储来保持当前的聚合结果——因此,您无法摆脱存储
  • 是的,您可以使用内存存储。
    aggregate()。查看文档(顺便说一下:这些API在Kafka 1.0中简化了很多,因此如果您还没有使用1.0,我建议您升级):
  • 如上所述,窗口的大小不会影响计算“速度”
  • 旁注:

    • 如果使用内存状态而不是RocksDB,则会将存储大小限制为RAM大小——如果保留时间太长,这可能会成为一个问题,因为状态可能会变得相当大
    • 如果您进行滚动反弹,这将需要更多的时间,因为需要通过读取完整的changelog主题重新创建状态——RocksDB存储可以从本地磁盘恢复速度更快的状态
    • 您可以尝试使用RocksDB并增加KTable缓存大小以提高性能:

    附录:即使您使用内存中的状态存储,您的状态存储仍然是容错的(除非您明确禁用此功能)。也就是说,内存存储在设计上有一个限制,即其数据必须适合应用程序的可用主内存,但它仍然是容错的,以防止在机器崩溃时丢失数据。@MichaelG.Noll我已禁用与窗口聚合相关联的内存状态存储的日志记录,但它仍然在磁盘的changelog上写聚合,为什么会发生这种情况?
    KTable<Windowed<String>, aggrTest> WinMinMax = Records.groupByKey().aggregate(new aggrTestInitilizer(), 
            new minMaxCalculator()
            , TimeWindows.of(TimeUnit.SECONDS.toMillis(100)).advanceBy(TimeUnit.SECONDS.toMillis(1)),aggrMessageSerde);