Kafka如何保证消费者一条信息不会读两遍?或者上述情况是否可能?同一条信息能被一个或多个消费者阅读两次吗?
r1zhe5dt1#
如果不使消费过程幂等,这是绝对可能的。例如;您至少要实现一个传递语义,首先处理消息,然后提交偏移量。由于服务器故障或重新平衡,可能无法提交偏移量(也许你的消费者在那个时候被撤销了),所以当你投票的时候,你会得到同样的消息两次。
eufgjt7s2#
准确地说,Kafka保证:kafka提供了分区中消息的顺序保证当生成的消息被写入其所有同步副本上的分区时,它们被视为“已提交”只要至少有一个复制副本保持活动状态,提交的消息就不会丢失使用者只能读取已提交的邮件关于消费消息,消费者通过保存内部压缩的kafka主题中读取的最后一个偏移量来跟踪他们在分区中的进度。Kafka消费者可以自动提交补偿,如果 enable.auto.commit 已启用。然而,这将给出“最多一次”的语义。因此,通常标志被禁用,开发人员在处理完成后显式提交偏移量。
enable.auto.commit
ljo96ir53#
有许多情况会导致使用者使用重复的消息生产者已成功发布消息,但无法确认重试同一消息的原因生产者发布了一批消息,但部分发布的消息失败。在这种情况下,它将重试并再次重新发送同一批,这将导致重复消费者从kafka接收一批消息并手动提交其偏移量(enable.auto.commit=false)。如果消费者在承诺Kafka之前失败了,下次消费者将再次消费相同的记录,这些记录会在消费者端复制。为了保证不使用重复的消息,作业的执行和提交偏移量必须是原子的,以保证在使用者端准确地传递一次语义。您可以使用下面的参数来实现一个语义。但请你明白,这是一个妥协与性能。在producer端启用幂等性,保证不会两次发布同一消息enable.idempotence=true定义的事务(isolation.level)为read\u committed isolation.level=read\u committed在kafka流中,可以通过将语义设置为true使其成为单元事务来实现上述设置幂等的幂等传递使生产者能够在单个生产者的生命周期内将消息准确地一次写入kafka主题的特定分区,而不会丢失每个分区的数据和顺序。事务(隔离级别)事务使我们能够原子地更新多个主题分区中的数据。事务中包含的所有记录都将成功保存,或者都不会保存。它允许您在同一事务中提交消费偏移量以及已处理的数据,从而允许端到端只使用一次语义。生产者不等待向kafka写入消息,而生产者使用begintransaction、committransaction和aborttransaction(如果失败),消费者使用隔离。级别“已提交”或“未提交”read\u committed:使用者总是只读取提交的数据。read\u uncommitted:在不等待事务提交的情况下,按偏移顺序读取所有消息请参阅更详细的参考资料
3条答案
按热度按时间r1zhe5dt1#
如果不使消费过程幂等,这是绝对可能的。
例如;您至少要实现一个传递语义,首先处理消息,然后提交偏移量。由于服务器故障或重新平衡,可能无法提交偏移量(也许你的消费者在那个时候被撤销了),所以当你投票的时候,你会得到同样的消息两次。
eufgjt7s2#
准确地说,Kafka保证:
kafka提供了分区中消息的顺序保证
当生成的消息被写入其所有同步副本上的分区时,它们被视为“已提交”
只要至少有一个复制副本保持活动状态,提交的消息就不会丢失
使用者只能读取已提交的邮件
关于消费消息,消费者通过保存内部压缩的kafka主题中读取的最后一个偏移量来跟踪他们在分区中的进度。
Kafka消费者可以自动提交补偿,如果
enable.auto.commit
已启用。然而,这将给出“最多一次”的语义。因此,通常标志被禁用,开发人员在处理完成后显式提交偏移量。ljo96ir53#
有许多情况会导致使用者使用重复的消息
生产者已成功发布消息,但无法确认重试同一消息的原因
生产者发布了一批消息,但部分发布的消息失败。在这种情况下,它将重试并再次重新发送同一批,这将导致重复
消费者从kafka接收一批消息并手动提交其偏移量(enable.auto.commit=false)。如果消费者在承诺Kafka之前失败了,下次消费者将再次消费相同的记录,这些记录会在消费者端复制。
为了保证不使用重复的消息,作业的执行和提交偏移量必须是原子的,以保证在使用者端准确地传递一次语义。您可以使用下面的参数来实现一个语义。但请你明白,这是一个妥协与性能。
在producer端启用幂等性,保证不会两次发布同一消息enable.idempotence=true
定义的事务(isolation.level)为read\u committed isolation.level=read\u committed
在kafka流中,可以通过将语义设置为true使其成为单元事务来实现上述设置
幂等的
幂等传递使生产者能够在单个生产者的生命周期内将消息准确地一次写入kafka主题的特定分区,而不会丢失每个分区的数据和顺序。
事务(隔离级别)
事务使我们能够原子地更新多个主题分区中的数据。事务中包含的所有记录都将成功保存,或者都不会保存。它允许您在同一事务中提交消费偏移量以及已处理的数据,从而允许端到端只使用一次语义。
生产者不等待向kafka写入消息,而生产者使用begintransaction、committransaction和aborttransaction(如果失败),消费者使用隔离。级别“已提交”或“未提交”
read\u committed:使用者总是只读取提交的数据。
read\u uncommitted:在不等待事务提交的情况下,按偏移顺序读取所有消息
请参阅更详细的参考资料