Kafka的EOS主要体现在3个方面:
上面3种EOS语义有着不同的应用范围,幂等producr只能保证单分区上无重复消息;事务可以保证多分区写入消息的完整性;而流处理EOS保证的是端到端(E2E)消息处理的EOS。用户在使用过程中需要根据自己的需求选择不同的EOS。以下是启用方法:
幂等producer的设计与实现。
-----------------------------------------------------------------------
所谓幂等producer指producer.send的逻辑是幂等的,即发送相同的Kafka消息,broker端不会重复写入消息。同一条消息Kafka保证底层日志中只会持久化一次,既不会丢失也不会重复。幂等性可以极大地减轻下游consumer系统实现消息去重的工作负担,因此是非常实用的功能。值得注意的是,幂等producer提供的语义保证是有条件的:
虽然有上面两个限制,幂等producer依然是一个非常实用的新功能。下面我们来讨论下它的设计原理。如果要实现幂等性, 通常都需要花费额外的空间来保存状态以执行消息去重。Kafka的幂等producer整体上也是这样的思想。
首先,producer对象引入了一个新的字段:Producer ID(下称PID),它唯一标识一个producer,当producer启动时Kafka会为每个producer分配一个PID(64位整数),因此PID的生成和分配对用户来说是完全透明的,用户无需考虑PID的事情,甚至都感受不到PID的存在。其次,0.11 Kafka重构了消息格式,引入了序列号字段(sequence number,下称seq number)来标识某个PID producer发送的消息。和consumer端的offset类似,seq number从0开始计数并严格单调增加。同时在broker端会为每个PID(即每个producer)保存该producer发送过来的消息batch的某些元信息,比如PID信息、消息batch的起始seq number及结束seq number等。这样每当该PID发送新的消息batch时,Kafka broker就会对比这些信息,如果发生冲突(比如起始seq number和结束seq number与当前缓存的相同),那么broker就会拒绝这次写入请求。倘若没有冲突,那么broker端就会更新这部分缓存然后再开始写入消息。这就是Kafka实现幂等producer的设计思路:1. 为每个producer设置唯一的PID;2. 引入seq number以及broker端seq number缓存更新机制来去重。
PID
与Sequence Number
的引入实现了写操作的幂等性PID标记了Producer、topic、partition的唯一性,Seq标记了PID下每一个消息得唯一性。broker会记录已经收到得seq值,下一个seq一定是上一个seq+1,如果大于1,抛InvalidSequenceNumber异常(丢数据了),如果小于1,抛DuplicateSequenceNumber异常(数据重复了),生产端需要对这两种情况做处理
At Least Once
语义实现了单一 Session 内的Exactly Once
语义Transaction Marker(引入事务协调者)
与PID
提供了识别消息是否应该被读取的能力,从而实现了事务的隔离性Transaction Marker
)来实现事务中涉及的所有读写操作同时对外可见或同时对外不可见简单的说,其实就是把所有操作都那个小本本写下来,所有人都能看到,就避免了重复问题和丢数据问题。
当然,这只是说kafka内部得事务实现,至于kafka的上游生产者,下游消费者的事务,需要使用方自己实现
参考资料:
本文系转载,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文系转载,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。