Fetcher解析
回顾
上一篇介绍了消费者KafkaConsumer两个主要方法,一个对外可以调用的poll方法和一个内部私有的pollForFetches方法。
我们知道pollForFetches方法主要是抓取数据的实现细节,里面多次出现Fetcher对象,其中最主要的两个方法是 fetcher.sendFetches() 和 fetcher.fetchedRecords()。接下来让我们揭开他们的面纱。
Fetcher概述
官方定义:该类使用代理管理获取过程,线程安全。
此类主要有三部分组成。
- 成员变量
- 静态内部类
- 方法
接下来我们依次介绍。
成员变量
private final Logger log; // 日志
private final LogContext logContext; // 日志信息
private final ConsumerNetworkClient client; // 消费者网络客户端
private final Time time; // 时间
private final int minBytes; // 最小字节大小
private final int maxBytes; // 最大字节大小
private final int maxWaitMs; // 最大等待时长
private final int fetchSize; // 抓取数据的大小
private final long retryBackoffMs;
private final long requestTimeoutMs;
private final int maxPollRecords; // 每一次获取的最大记录条数
private final boolean checkCrcs;
private final Metadata metadata; // 元数据
private final FetchManagerMetrics sensors; // 度量管理类
private final SubscriptionState subscriptions;
private final ConcurrentLinkedQueue<CompletedFetch> completedFetches; // 已完成的获取类的一个基于链接节点的无界线程安全队列
private final BufferSupplier decompressionBufferSupplier = BufferSupplier.create();
private final Deserializer<K> keyDeserializer; // 反序列化后的key
private final Deserializer<V> valueDeserializer;
private final IsolationLevel isolationLevel;
private final Map<Integer, FetchSessionHandler> sessionHandlers;
private final AtomicReference<RuntimeException> cachedListOffsetsException = new AtomicReference<>();
有些成员一眼看不出来职业,伪装的很好,我们先放着,待后续补充。
静态内部类
之所以先介绍静态内部类,因为方法中会频频用到。这里只介绍几个简单和常用的。
复杂的我也看不懂阿,嘻嘻。
OffsetData
偏移量类,表示关于代理返回的偏移量的数据。
private static class OffsetData {
final long offset; // 偏移量
final Long timestamp; // null if the broker does not support returning timestamps
final Optional<Integer> leaderEpoch; // empty if the leader epoch is not known
OffsetData(long offset, Long timestamp, Optional<Integer> leaderEpoch) {
this.offset = offset;
this.timestamp = timestamp;
this.leaderEpoch = leaderEpoch;
}
}
此类比较简单,点到为止。
ListOffsetResult
偏移量结果列表类,顾名思义是记录偏移量结果的集合。
private static class ListOffsetResult {
private final Map<TopicPartition, OffsetData> fetchedOffsets; // 主题分区和偏移量结果的map集合
private final Set<TopicPartition> partitionsToRetry; // 主题分区的set集合
public ListOffsetResult(Map<TopicPartition, OffsetData> fetchedOffsets, Set<TopicPartition> partitionsNeedingRetry) {
this.fetchedOffsets = fetchedOffsets;
this.partitionsToRetry = partitionsNeedingRetry;
}
public ListOffsetResult() {
this.fetchedOffsets = new HashMap<>();
this.partitionsToRetry = new HashSet</