假设我使用Kafka Streams处理器API编写了一个非常基本的处理器,用于对传入消息进行重复数据删除。处理器使用容错存储区来保留给定密钥的最新版本。
基本上,当处理器收到一条消息时,它会执行以下操作:
public void process(String key, Message value) {
Long lastVersion = store.get(key);
if (lastVersion == null || value.getVersion() > lastVersion) {
context.forward(key, message);
store.put(key, message.version);
}
}
context.forward()和store.put()都将向不同主题(分别是接收器主题和商店changelog主题,因为激活了容错功能)产生一条消息。 由于消息生产是异步的,并且可能针对不同的代理,因此,如果在process()完成后立即停止应用程序,则第一个生产可能无法完成(仍为批处理,尚未发送),而第二个生产成功。
由于没有因应用程序崩溃而导致使用者提交,因此传入消息的version = 1将由另一个使用者处理(重新平衡),但是商店(从changelog构建)实际上包含lastVersion = 1。因此,应用程序将忽略此消息->消息丢失。
问题:在像本示例中那样使用商店时,是否还有至少一项保证(这是Kafka Streams提供的默认值)?
例如,通过在context.forward()和store.put()之间添加一种手动刷新? 还是唯一可行的方法,可以一路实现并完全启用一次语义?