Kafka源码之KafkaConsumer分析之Fetcher

本文深入探讨了KafkaConsumer中的Fetcher组件,其主要任务是通过发送FetchRequest获取消息。Fetcher涉及的关键参数包括minBytes、maxWaitMs、fetchSize和maxPollRecords。创建FetchRequest的流程包括查找fetchable分区、定位Leader副本、封装请求对象。消息解析过程最多处理maxPollRecords个数据。当服务端未记录消费位置时,Fetcher会依据用户设定或默认策略调整消费起始点。
摘要由CSDN通过智能技术生成

对于KafkaConsumer,我们最后来看一下消费者是符合从服务端获取消息的,它是用Fetcher来实现此功能。Fetcher的主要工作就是发送FetchRequest请求,获取指定的消息集合,处理FetchResponse,更新消费位置。
我们先来看一下它的核心字段:
client:负责网络通信
minBytes:在服务端收到FetchRequest之后并不是立即响应,而是当可返回的消息数据积累到至少minBytes个字节时才进行响应。
maxWaitMs:等待FetchResponse的最长时间,服务端根据此时间决定何时进行响应
fetchSize:每次fetch操作的最大字节数
maxPollRecords:每次获取Record的最大数量
metadata:记录了Kafka集群的元数据
subscriptions:记录每个TopicPartition的消费情况
completedFetches:每个FetchResponse首先会转换成CompletedFetch对象进入此队列缓存,此时并未解析消息。
nextInLineRecords:保存了FetchResponse解析之后的结果集
下面我们先来看创建FetchRequest请求的方法

private Map<Node, FetchRequest> createFetchRequests() {
        // 获取集群元数据
        Cluster cluster = metadata.fetch();
        Map<Node, Map<TopicPartition, FetchRequest.PartitionData>> fetchable = new HashMap<>();
        for (TopicPartition partition : fetchablePartitions()) {
        	//查找当前分区所在的节点
            Node node = cluster.leaderFor(partition);
            //如果节点为空,需要更i性能元数据
            if (node == null) {
                metadata.requestUpdate();
                //如果没有pend的请求
            } else if (this.client.pendingRequestCount(node) == 0) {
                Map<TopicPartition, FetchRequest.PartitionData> fetch = fetchable.get(node);
                if (fetch == null) {
                    fetch = new HashMap<>();
                    fetchable.put(node, fetch);
                }
				//记录需要fetch的消息的offset
                long position = this.subscriptions.position(partition);
                fetch.put(partition, new FetchRequest.PartitionData(position, this.fetchSize));
                log.trace("Added fetch request for partition {} at offset {}", partition, position);
            }
        }

        Map<Node, FetchRequest> requests = new HashMap<>();
        for (Map.Entry<Node, Map<TopicPartition, FetchRequest.PartitionData>> entry : fetchable.entrySet()) {
        	//创建Request
            Node node = entry.getKey();
            FetchRequest fetch = new FetchRequest(this.maxWaitMs, this.minBytes, entry.getValue());
            requests.put(node, fetch);
        }
        return requests;
    }

总结一下上面这个方法的流程:
1、首先按条件查找fetchable分区
(1)首先是分配个当前消费者的分区

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值