Apache kafka 重建卡夫卡流中的状态存储是否会将重复记录传播到下游主题?
我目前正在为一个有状态的应用程序使用Kafka Streams。不过,该状态不是存储在卡夫卡状态存储中,而是暂时存储在内存中。这意味着每当我重新启动应用程序时,所有状态都将丢失,必须通过从一开始就处理所有记录来重建它 在对Kafka状态存储进行了一些研究之后,这似乎正是我所寻找的在应用程序重启之间(在内存或磁盘上)保持状态的解决方案。但是,我发现在线资源缺少一些非常重要的细节,因此我仍然有几个问题要问,这到底是如何工作的:Apache kafka 重建卡夫卡流中的状态存储是否会将重复记录传播到下游主题?,apache-kafka,apache-kafka-streams,restore,stateful,Apache Kafka,Apache Kafka Streams,Restore,Stateful,我目前正在为一个有状态的应用程序使用Kafka Streams。不过,该状态不是存储在卡夫卡状态存储中,而是暂时存储在内存中。这意味着每当我重新启动应用程序时,所有状态都将丢失,必须通过从一开始就处理所有记录来重建它 在对Kafka状态存储进行了一些研究之后,这似乎正是我所寻找的在应用程序重启之间(在内存或磁盘上)保持状态的解决方案。但是,我发现在线资源缺少一些非常重要的细节,因此我仍然有几个问题要问,这到底是如何工作的: 如果流被设置为从偏移量最新的开始,状态是否仍会根据所有以前的记录(重新
- 如果流被设置为从偏移量
最新的
开始,状态是否仍会根据所有以前的记录(重新)计算
- 如果需要重新处理以前已经处理过的记录以重建状态,这是否会通过流拓扑的其余部分传播记录(例如,InputTopic->stateful processor->OutputTopic,这是否会因为重建状态而导致OutputTopic中的重复记录)
changelog
主题,卡夫卡流州立商店负责从中加载。如果您的状态存储未初始化,您的kafka streams应用程序将使用最早的
,从changelog主题重新水化其本地状态存储,因为它必须读取每条记录
这意味着全新实例的启动顺序大致如下:
- 请注意,没有本地状态存储缓存
- 通过使用statestore的changelog主题加载本地状态存储(状态存储的主题名称为
)-changelog
- 读取每条记录并相应地更新本地rocksDB实例
- 不要发射任何东西,因为这是一个应用程序服务,而不是您的实际拓扑
- 根据您配置拓扑的方式,使用
或最早的
读取消费群体偏移量。不,这只是一个问题,如果你的消费群体还没有任何补偿最新的
- 处理内容,根据拓扑发送记录
auto.offset.reset
设置为LATEST
或earlime
取决于您。如果这些记录丢失,或者您创建了一个新的组,则可能会跳过记录(最新的
)与处理旧记录的重新处理和重复数据消除(最早的
)之间需要平衡
长话短说:状态恢复不同于处理,由卡夫卡自己处理
如果流被设置为从偏移量最新的开始,状态是否仍会根据所有以前的记录(重新)计算
如果您正在重新启动同一应用程序(例如,在之前停止它之后),则不会通过重新处理原始输入数据来重新计算状态。相反,状态将从其“备份”中恢复(每个状态存储或KTable都持久地存储在Kafka主题中,即该表/状态存储的所谓“changelog主题”,用于此目的),以便其数据与应用程序停止时的数据完全相同。此行为使您能够无缝地停止并重新启动应用程序,而不会跳过在“停止”和“重新启动”之间到达的记录
但您需要注意一个不同的警告:设置偏移起始点的配置(最新
或最早
)仅在首次运行Kafka Streams应用程序时使用。之后,无论何时停止并重新启动应用程序,它都会在以前停止的位置继续运行。这是因为,如果应用程序至少运行过一次,它会将其消费者偏移量信息存储在Kafka中,这使它能够知道在重新启动后从何处自动恢复操作
如果您需要始终(重新)从偏移量开始的不同行为,例如最新的
偏移量(因此可能会跳过在停止应用程序和重新启动应用程序之间到达的记录),则必须。重置工具执行的步骤之一是从Kafka中删除应用程序的使用者偏移信息,这使应用程序认为它以前从未启动过
如果需要重新处理以前已经处理过的记录以重建状态,这是否会通过流拓扑的其余部分传播记录(例如,InputTopic->stateful processor->OutputTopic,这是否会因为重建状态而导致OutputTopic中的重复记录)
如上所述,默认情况下不会进行此重新处理。在应用程序停止时,状态将自动重建为其先前的状态(双关语)
只有手动重置应用程序(见上文)并将应用程序配置为重新读取历史数据(如设置auto.offset.reset
至重置后最早的时间),才能进行重新处理。您指的是KTables吗?@cricket\u 007否,而是一个我认为不同的persistentKeyValueStore
?您应该能够执行类似于builder.addStateStore(storeBuilder)
的操作,关于auto.offset.reset
的点不正确--auto.offset.reset
仅在没有提交的偏移量时才适用。如果找到提交的偏移量,则从该偏移量开始处理。-例如,auto.offset.reset
通常仅在应用程序第一次启动时相关,在这种情况下,没有要恢复的状态,因为在初始启动时它将为空。Hmm。我的观点不是很清楚-我试图让读者思考在偏移丢失的情况下会发生什么,因为设置被提出,但我将