[我有一个无状态的Kafka流,该流从某个主题使用,并发布到forEach
内的另一个队列(Cloud PubSub)中。拓扑结构不会在产生新的Kafka主题时结束。
我如何知道我可以保证的交付语义?知道这只是一个消息转发器,没有进行反序列化或任何其他转换或任何适用的方法:在任何情况下,我可能有重复或丢失的消息吗?
我正在考虑以下方案以及对如何提交偏移量的相关影响:
谢谢你们
[如果考虑Kafka Stream应用程序通常创建的kafka到kafka循环,请设置属性:
processing.guarantee=exactly_once
当然,具有exactly-once语义就足够了,当然在失败的情况下也是如此。
内幕,Kafka使用事务来保证消费-处理-生产-提交偏移量处理在全部或不保证的情况下执行。
一旦将语义kafka写到Google PubSub时,便要使用一个接收器连接器,这将意味着解决same issues Kafka已经解决了kafka至kafka的问题。
- producer.send()可能由于内部重试而导致消息B的重复写入。这由幂等的生产者解决,而不是本文其余部分的重点。
- 我们可能会重新处理输入消息A,导致重复的B消息被写入输出,这完全违反了一次处理语义。如果流处理应用程序在写入B之后但将A标记为已使用之前崩溃,则可能会发生重新处理。因此,当恢复时,它将再次消耗A并再次写入B,从而导致重复。
- 最后,在分布式环境中,应用程序将崩溃或—更糟!暂时失去与系统其余部分的连接。通常,新实例会自动启动以替换被认为丢失的实例。通过此过程,我们可能有多个实例处理相同的输入主题并写入相同的输出主题,从而导致输出重复,并且违反了一次处理语义的方式。我们称此为“僵尸实例”问题。
[假设您使用Cloud PubSub的生产者逻辑不会遇到问题1,就像使用enable.idempotence=true
的Kafka生产者一样,您仍然会遇到问题2和3。
如果不解决这些问题,您的处理语义将是您的消费者正在使用的传递语义,因此,如果您选择手动提交偏移量,则至少一次。