目录
3.3 消费-生产并存(consume-transform-produce)
4.2.2 tranaction id 、productid 和 epoch
4.4 Consume-transform-Produce 的流程
4.4.2 ControlMessage和Transaction markers
4.4.3 Transaction Coordinator 和 Transaction Log
4.5.3 Absorted Transaction Index
本文概览:在Kafka 0.11.0.0引入了EOS(exactly once semantics,精确一次处理语义)的特性,这个特性包括kafka幂等性和kafka事务两个属性。本小节对这个属性进行介绍。
1 生产者幂等性
1.1 引入
幂等性引入目的:
- 生产者重复生产消息。生产者进行retry会产生重试时,会重复产生消息。有了幂等性之后,在进行retry重试时,只会生成一个消息。
1.2 幂等性实现
1.2.1 PID 和 Sequence Number
为了实现Producer的幂等性,Kafka引入了Producer ID(即PID)和Sequence Number。
- PID。每个新的Producer在初始化的时候会被分配一个唯一的PID,这个PID对用户是不可见的。
- Sequence Numbler。(对于每个PID,该Producer发送数据的每个<Topic, Partition>都对应一个从0开始单调递增的Sequence Number。
Broker端在缓存中保存了这seq number,对于接收的每条消息,如果其序号比Broker缓存中序号大于1则接受它,否则将其丢弃。这样就可以实现了消息重复提交了。但是,只能保证单个Producer对于同一个<Topic, Partition>的Exactly Once语义。不能保证同一个Producer一个topic不同的partion幂等。
实现幂等之后
1.2.2 生成PID的流程
在执行创建事务时,如下
1 |
Producer<String, String> producer = new KafkaProducer<String, String>(props); |
会创建一个Sender,并启动线程,执行如下run方法,在maybeWaitForProducerId()中生成一个producerId,如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
==================================== 类名:Sender ====================================
void run(long now) { if (transactionManager != null) { try { ........ if (!transactionManager.isTransactional()) { // 为idempotent producer生成一个producer id maybeWaitForProducerId(); } else if (transactionManager.hasUnresolvedSequences() && !transactionManager.hasFatalError()) { ........ |
1.3 幂等性的应用实例
1、配置属性
需要设置:
- enable.idempotence,需要设置为ture,此时就会默认把acks设置为all,所以不需要再设置acks属性了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
private Producer buildIdempotProducer(){
// create instance for properties to access producer configs Properties props = new Properties();
// bootstrap.servers是Kafka集群的IP地址。多个时,使用逗号隔开 props.put("bootstrap.servers", "localhost:9092");
props.put(" |