我目前有一个服务,用于消费来自Kafka主题的消息,做一些计算,就是这样,我目前的设计是服务将分批进行计算(即每批1000条消息),并在该批处理完成后发出偏移量,因为延迟不是问题。然而,我意识到,如果我的服务要处理500条消息,崩溃然后重新启动,它可能会再次重新计算500条消息,因为它没有向Kafka主题发送偏移量,并且它不知道消费者在哪里。我应该如何设计一个过程,我可以保证一次计算,而不设置偏移每一个消息?再强调一次,延迟不是问题,但我不想每次都设置偏移量而牺牲太多。
Kafka可以支持事务处理,所以我将从它开始。
但是如果你不提交offset % 1000
记录,只处理batch[0..499]
,那么你需要一些下游逻辑,在Kafka的范围之外,以防止你再次处理这些记录。例如,使用Redis存储一些记录ID,并进行快速哈希查找,以查看记录是否已被处理。当然,这是一个故障点,但这是编写不具有幂等性的消费者代码的权衡。
重新启动的Kafka消费者将自动倒回到上一次提交的偏移量,并重新开始读取,就像什么都没有发生一样。
幂等记录的例子-(id, null)
是一个删除事件;处理相同的操作应该什么也不做,因为该ID已经在下游系统中消失了。但是,如果您倒带看到(id, data)
,它将尝试再次打乱该事件,直到再次看到(id, null)
。