Kafka消费端采用pull模式,为消费端提供了更多的控制权。
如果broker采用push模式,能更快的将消息推送给消费端,但无法适应消费端的消费能力,使消费端崩溃。
采用pull模式,可自主控制消费速率及消费的方式(批量、单条),并且可以表述不同的传输语义。
Kafka中包含了三种传输语义:
At Most Once
消息可能会丢,但不会重复。
在这种模式下,先Commit
Offset,再去处理
消息。
如果Commit成功
了,此时消费端宕机
了,那么下次恢复的时候,消息不会再下发,也就丢了
。
At Least Once
消息不会丢,但可能会重复(默认模式)。
在这种模式下,先处理
消息,再Commit
Offset。
如果Commit失败
了,那么这条消息还会继续下发,直到Offset Commit成功
,也就重了
。
Exactly Once
消息不会丢且不会重复。
以At Least Once
为基础,让下游保证幂等
,并且保存消息处理状态、Offset提交状态,间接实现Exactly Once
。而要真正实现Exactly Once
,需要引入两阶段
事务处理,对于消息乱序、消息重复,采用类似TCP三次握手的ACK
机制,对于单Session的,可以这么简单处理,对于多Session的,需要基于事务来实现类似分布式锁、分布式Session,记录所有事务状态、事务进度、判断是否合法,要么全部成功,要么全部失败。