[读书笔记] KafkaConsumer工作原理

Kafka消费者不是线程安全的。

Kafka消费者通过订阅主题(Topic)拉取消息。每个消费者对应一个消费组,消息发布到主题后,只会投递给订阅它的每个消费组中的一个消费者。

一个主题有多个分区(parition),每一个分区只能被一个消费组中的一个消费者所有消费。Kafka默认的分区分配策略会根据消费组中消费者的数量动态分配分区,提供横向伸缩性。消费组内的消费者数量应该小于或等于订阅主题的分区数,否则多于的消费者是无法消费到消息造成资源浪费。

消费者可以订阅一个或多个主题,或通过正则表达式订阅,当新的主题符合正则表达式,消费者就能消费到消息。

void subscribe(Collection<String> topics);

void subscribe(Collection<String> topics, ConsumerRebalanceListener callback);

void subscribe(Pattern pattern, ConsumerRebalanceListener callback);

void subscribe(Pattern pattern);

subscribe()方法支持再均衡,自动分配分区。

assign()方法之前订阅某主题的特定分区中的消息,但是它不具备自动再均衡的特性。

void assign(Collection<TopicPartition> partitions);

poll()方法阻塞式,timeout参数控制阻塞时间。poll()方法每次拉取的是一组消息ConsumerRecords,里面包含若干的ConsumerRecord。

自动消费位移提交,当系统异常时会比较容易造成消息重复消费和丢失消息情况。

手动同步位移提交,以分区粒度提交,可保证一定的性能和容错性。

消费者位移持久化在内部的__consumer_offsets主题中。

seek()方法指定消费分区位移。

void seek(TopicPartition partition, long offset);

void seek(TopicPartition partition, OffsetAndMetadata offsetAndMetadata);

void seekToBeginning(Collection<TopicPartition> partitions);

void seekToEnd(Collection<TopicPartition> partitions);

再均衡是指分区的所属权从一个消费者转移到另一个消费者,有利用高可用和伸缩性。但是再均衡时,消费组是不可用的,消费者的状态会丢失,这样可能会造成数据丢失。可以利用再均衡监听器ConsumerRebalanceListener对再均衡前后做处理,保证消息可靠性。

public interface ConsumerRebalanceListener {

    void onPartitionsRevoked(Collection<TopicPartition> partitions);


    void onPartitionsAssigned(Collection<TopicPartition> partitions);
}

ConsumerRebalanceListener源码中给出的使用建议

 public class SaveOffsetsOnRebalance implements ConsumerRebalanceListener {
        private Consumer<?,?> consumer;
 
        public SaveOffsetsOnRebalance(Consumer<?,?> consumer) {
            this.consumer = consumer;
        }
 
        public void onPartitionsRevoked(Collection<TopicPartition> partitions) {
            // save the offsets in an external store using some custom code not described here
            for(TopicPartition partition: partitions)
               saveOffsetInExternalStore(consumer.position(partition));
        }
 
        public void onPartitionsAssigned(Collection<TopicPartition> partitions) {
            // read the offsets from an external store using some custom code not described here
            for(TopicPartition partition: partitions)
               consumer.seek(partition, readOffsetFromExternalStore(partition));
        }
    }
  }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值