我目前正在将 Kafka Streams 用于有状态应用程序。不过,状态不存储在 Kafka 状态存储中,而只是暂时存储在内存中。这意味着每当我重新启动应用程序时,所有状态都会丢失,并且必须通过从头开始处理所有记录来重建它。
在对 Kafka 状态存储进行了一些研究之后,这似乎正是我正在寻找的在应用程序重启之间保持状态(在内存中或磁盘上)的解决方案。但是,我发现网上的资源缺少一些非常重要的细节,所以我仍然有几个关于它究竟如何工作的问题:
- 如果流设置为从偏移量
latest
开始,是否仍会根据所有以前的记录(重新)计算状态? - 如果之前已经处理过的记录需要重新处理以重建状态,这是否会通过其余的 Streams 拓扑传播记录(例如 InputTopic -> stateful processor -> OutputTopic,这会导致 OutputTopic 中的重复记录吗因为重建状态)?
最佳答案
国有商店使用自己的changelog
主题和 kafka-streams 状态存储负责从中加载。如果您的状态存储未初始化,您的 kafka-streams 应用程序将使用 EARLIEST
从变更日志主题中重新水合其本地状态存储。 ,因为它必须读取每条记录。
这意味着全新实例的启动顺序大致是:
- 观察没有本地状态存储缓存
- 通过使用状态存储的变更日志主题加载本地状态存储(状态存储的主题名称为
<state-store-name>-changelog
) - 读取每条记录并相应地更新本地 rocksDB 实例
- 不要发出任何东西,因为这是一个应用程序服务,而不是您的实际拓扑结构
- 使用
EARLIEST
读取您的消费者群体偏移量或LATEST
根据您配置拓扑的方式。如果您的消费者群体还没有任何抵消,这不仅仅是一个问题 - Process stuff,根据拓扑发出记录
您是否设置实际拓扑的 auto.offset.reset
至 LATEST
或 EARLIEST
你决定。如果它们丢失了,或者您创建了一个新组,它会在可能跳过记录 (LATEST
) 与处理旧记录和重复数据删除的重新处理 (EARLIEST
) 之间取得平衡,
长话短说:状态恢复不同于处理,由 kafka-streams 自行处理。
关于apache-kafka - 在 Kafka Streams 中重建状态存储是否会将重复记录传播到下游主题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59716187/