Kafka深入学习(3)

消费者和消费组

拥有相同group.id的消费者线程为同一组消费组
消费者数量和分区数量一致时为p2p模式;消费者数量少于分区数量为发布订阅模式

订阅主题与分

subscribe()方法为订阅主题,有4个重载的方法

public void subscribe(Collection<String> topics, ConsumerRelanceListener listener)
public void subscribe(Collection<String> topics)
public void subscribe(Pattern pattern, ConsumerRelanceListener listener)
public void subscribe(Pattern pattern)
Pattern.compile("topic-*")

指定分区来消费

public void assign(Collection<TopicPartition> partitions)

使用KafkaConsumer的partitionsFor()方法来获取主题的元数据

public List<PartitionInfo> partitionsFor(String topic)

PartitionInfo的实例属性

String topic
int partiiton
Node leader
Node[] replicas
Node[] inSyncReplicas
Node[] offlineReplicas

消息消费

Kafka是基于拉模式的,一般来说是拉一片处理一批在拉下一批
拉取的方法为

public ConsumerRecords<K,V> poll(final Duration timeout)
public ConsumerRecords<K,V> poll(final long timeout)
//在没有数据的时候,poll方法将处于阻塞状态,而timeout则是决定会阻塞多长时间

ConsumerRecords实例属性

String topic
int partition
long offset
long timestamp
TimestampType timestampType
int serializedKeySize
int serializedValueSize
Headers headers
K key
V value
Long checksum

ConsumerRecords实现了Iterable接口,可以直接使用for each循环来获取,同时iterator()方法也返回一个Iterable<ConsumerRecord<K,V>>

获取指定topic和partition下的数据

public List<ConsumerRecord<K,V>> records(TopicPartition partition)
public Iterable<ConsumerRecord<K,V>> records(String topic)

这里是两个方法的源码,可以看下

/**
     * Get just the records for the given partition
     * 
     * @param partition The partition to get records for
     */
    public List<ConsumerRecord<K, V>> records(TopicPartition partition) {
        List<ConsumerRecord<K, V>> recs = this.records.get(partition);
        if (recs == null)
            return Collections.emptyList();
        else
            return Collections.unmodifiableList(recs);
    }

    /**
     * Get just the records for the given topic
     */
    public Iterable<ConsumerRecord<K, V>> records(String topic) {
        if (topic == null)
            throw new IllegalArgumentException("Topic must be non-null.");
        List<List<ConsumerRecord<K, V>>> recs = new ArrayList<>();
        for (Map.Entry<TopicPartition, List<ConsumerRecord<K, V>>> entry : records.entrySet()) {
            if (entry.getKey().topic().equals(topic))
                recs.add(entry.getValue());
        }
        return new ConcatenatedIterable<>(recs);
    }

//从源码中可以看到其实就是讲ConsumerRecords类中的records属性中的具体的partition中的数据list拿出来了

获取这个ConsumerRecords下的topic和parition列表

public List<TopicPartition> partitions()

KafkaConsumer提供了postition(TopicPartition)和committed(TopicPartition)来获取postion和comittedoffset的位置

提交

如果不使用自动提交,需要设置参数
enable.auto.commit=false
同步提交(手动)

public void commitSync()
public void commitSync(final Map<TopicPartition,OffsetAndMetadata> offset)

异步提交(手动)

public void commitAsync(final Map<TopicPartition,OffsetAndMetadata> offset, OffsetCommitCallback callback)
// OffsetCommitCallback接口有一个onComplete的方法
public void onComplete(Map<TopicPartition, OffsetAndMetadata> offsets, Exception exception)
// 两个参数互斥

控制和关闭消费

pasuse和resume两个方法

指定位移消费

auto.offset.reset来控制消费的起始点:earliest,latest和none
默认为earliest,从头开始消费

以上是自动,下面是手动

public void seek(TopicPartition partition, long offset)
//在seek方法执行前要先执行一次poll

在执行seek前还可以先获取这批数据的topic和partition情况

public Set<TopicPartition> assignment()

一般offset存储在外部db当中,可能要先去查一下offset

while(assignment == 0) {
	consumer.poll(10000)
	assignment = consumer.assignment()
}

获取指定分区的最后offset

public Map<TopicPartiion,Long> endOffsets(Collection<TopicPartition> partitions)

根据时间来获取offset

//该方法用于查询需要的offset
public Map<TopicPartition, OffsetAndTimestamp> offsetForTimes(Map<TopicPartition,Long> timestampToSearch)

再平衡

主要是subscribe中的ConsumerRelanceListener接口的重写

//这个方法在停止读数据之后和再平衡之前执行
public void onPartitionRevoked(Collection<TopicPartition> partitions)
//这个方法在再平衡之后和开始读数据之前执行
public void onPartitionAssigned(Collection<TopicPartition> partitions)

拦截器

实现一个拦截器接口后,重写onConsume和onCommit方法
前者在poll返回前执行,后者在提交offset后执行

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值