kafka关于Consumer提交offset及再均衡

提交offset原理

消费者提交偏移量是往一个叫作 _consumer_offset 的特殊主题发送消息,消息里包含每个分区的偏移量。 

提交的类型(5)


kafka关于Consumer提交offset及再均衡_第1张图片
提交的类型5种

自动                             properties.put("enable.auto.commit",true); true为自动 false手动

同步                                 consumer.commitSync();

异步                                 consumer.commitSync();

同步和异步配合使用        consumer.commitSync();  consumer.commitSync();

特定           

Map currentOffsets = new HashMap();

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 currOffsets;

    private final KafkaConsumer consumer;

    public HandlerRebalance(Map currOffsets,

                            KafkaConsumer consumer) {

        this.currOffsets = currOffsets;

        this.consumer = consumer;

    }

    public void onPartitionsRevoked(

            Collection partitions) {

        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 partitions) {

        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消费者——提交和偏移量 -

你可能感兴趣的:(kafka关于Consumer提交offset及再均衡)