我正在使用带有Windowed RocksDB状态存储的KafkaStreams 0.10.2.1,我在状态存储初始化期间看到了一个非常奇怪的行为。 在每个任务的状态存储文件夹中,KafkaStreams正在创建和删除包含RocksDB文件的文件夹30分钟。
如果状态存储名为XXX,那么我会在名为
的文件夹中看到正在创建的文件夹State Folder/Task ID/XXX
名称如
XXX-201710211345
包含RocksDB文件。创建这些文件夹,然后将其删除,并创建具有不同时间戳的新文件夹。这持续30分钟,直到消息处理为止。 我猜测RocksDB正在从状态存储的所有历史状态的更改日志主题重建,但我不明白为什么目的,因为它最终删除除最后一个之外的所有。
KafkaStreams创建和删除这些文件夹的原因是什么?
如何让KafkaStreams仅重新创建最新状态?
这是我拓扑的精简版本:
stream
.map((key, value) -> KeyValue.pair(key, value))
.through(Serdes.String(), serde, MY_TOPIC)
.groupByKey(Serdes.String(), serde)
.count(TimeWindows.of(TimeUnit.SECONDS.toMillis(windowDurationSec)).until(TimeUnit.SECONDS.toMillis(windowDurationSec) + TimeUnit.SECONDS.toMillis(lateEventGraceTimeSec)), "Hourly_Agg")
.foreach((k, v) -> System.out.println(""));
这是来自strace的一小部分:
6552 stat("/path/Prod/kafka-streams/Counter-V13/3_131/Hourly_Agg/Hourly_Agg-201710211230/000006.sst", {st_mode=S_IFREG|0644, st_size=3158, ...}) = 0
6552 unlink("/path/Prod/kafka-streams/Counter-V13/3_131/Hourly_Agg/Hourly_Agg-201710211230/000006.sst") = 0
6552 unlink("/path/Prod/kafka-streams/Counter-V13/3_131/Hourly_Agg/Hourly_Agg-201710211230") = -1 EISDIR (Is a directory)
6552 rmdir("/path/Prod/kafka-streams/Counter-V13/3_131/Hourly_Agg/Hourly_Agg-201710211230") = 0
6552 stat("/path/Prod/kafka-streams/Counter-V13/3_131/Hourly_Agg", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
6552 mkdir("/path/Prod/kafka-streams/Counter-V13/3_131/Hourly_Agg/Hourly_Agg-201710211500", 0755) = 0
6552 rename("/path/Prod/kafka-streams/Counter-V13/3_131/Hourly_Agg/Hourly_Agg-201710211500/LOG", "/path/Prod/kafka-streams/Counter-V13/3_131/Hourly_Agg/Hourly_Agg-201710211500/LOG.old.1508746634575191") = -1 ENOENT (No such file or directory)
答案 0 :(得分:3)
Kafka Streams会重新创建最新的状态,您看到的行为是设计的。
对于窗口存储,窗口保留时间段分为所谓的段,Streams每段使用一个RocksDB来存储相应的数据。这允许" roll"基于时间进度的段并删除比保留时间更长的数据(即,删除一个空洞段/ RocksDB)。
重新创建状态时,我们只需阅读整个更改日志主题并将所有这些更新应用于商店。因此,您会看到与处理期间相同的段滚动行为(仅在更小的时间范围内)。它不容易实现,跳跃"到最后一个状态,因为前期没有足够的信息 - 因此,盲目地重播更改日志是最好的选择。