提交offset原理
消费者提交偏移量是往一个叫作 _consumer_offset 的特殊主题发送消息,消息里包含每个分区的偏移量。
提交的类型(5)
自动 properties.put("enable.auto.commit",true); true为自动 false手动
同步 consumer.commitSync();
异步 consumer.commitSync();
同步和异步配合使用 consumer.commitSync(); consumer.commitSync();
特定
Map
currentOffsets.put(new TopicPartition(record.topic(), record.partition()),
new OffsetAndMetadata(record.offset() + 1, "no metadata"));
if (count % 1000 == 0) {
consumer.commitAsync(currentOffsets, null);
}
再均衡
当机器出现故障或者增加broker时发生Partition 重新分配consumer。
处理再均衡后保证消息正常消费不丢失也不重复
核心的逻辑是从特定的偏移量开始读。
过程:
1.业务逻辑过程是在customer中消费数据的同并将数据和offset同时入库
2.当发生再均衡的时候还有一些事务没有提交应该提交事务,然后再执行再均衡之后的逻辑
3.模拟分区再均衡:前:3个Partition 对应3个consumer 后 3个Partition 对应2个consumer
4.从数据库中找到Partition和offset
5.调用seek()方法 kafka从特定的偏移量开始读
核心代码:
public class HandlerRebalance implements ConsumerRebalanceListener {
/*模拟一个保存分区偏移量的数据库表*/
public final static ConcurrentHashMap
partitionOffsetMap = new ConcurrentHashMap
private final Map
private final KafkaConsumer
public HandlerRebalance(Map
KafkaConsumer
this.currOffsets = currOffsets;
this.consumer = consumer;
}
public void onPartitionsRevoked(
Collection
final String id = Thread.currentThread().getId()+"";
System.out.println(id+"-onPartitionsRevoked参数值为:"+partitions);
System.out.println(id+"-服务器准备分区再均衡,提交偏移量。当前偏移量为:"
+currOffsets);
//TODO 给生产者提交offset
consumer.commitSync(currOffsets);
//TODO 提交事务
System.out.println("分区偏移量表中:"+partitionOffsetMap);
for(TopicPartition topicPartition:partitions)
{
partitionOffsetMap.put(topicPartition,currOffsets.get(topicPartition).offset());
}
}
public void onPartitionsAssigned(
Collection
final String id = Thread.currentThread().getId()+"";
System.out.println(id+"-再均衡完成,onPartitionsAssigned参数值为:"+partitions);
System.out.println("分区偏移量表中:"+partitionOffsetMap);
//TODO 再均衡之后 取数据再从特定偏移量取读
for(TopicPartition topicPartition:partitions)
{
consumer.seek(topicPartition,partitionOffsetMap.get(topicPartition));
}
}
}
总结:
1.consumer消费数据后通过一个特殊的topic来提交偏移量。
2.当发生再均衡前,首先保存每一个partition最后一个消费了的offset
然后再均衡之后提交每一个partition最后一个消费了的offset,并且通过seek方法
指定消费每一个partition中的offset既:保存的offset+1
深入解析Kafka消费者——提交和偏移量 -