概述:
本文主要分享Kafka客户端的元数据如何创建,及其内部结构和对象
一、介绍MetaData
客户端元数据在初始化生产者客户端时被创建,以缓存的形式保存在客户端本地内存中;
元数据中保存有Kafka broker的节点信息如ip和端口,保存有topic与其partition的映射关系,以及每个partition的信息如主副分片以及ISR。
Metadata:org.apache.kafka.clients.Metadata
源码上的示意:
A class encapsulating some of the logic around metadata. --一个封装了元数据逻辑结构的类。 This class is shared by the client thread (for partitioning) and the background sender thread. Metadata is maintained for only a subset of topics, which can be added to over time. When we request metadata for a topic we don't have any metadata for it will trigger a metadata update. ---这个类由客户端主线程和后台发送线程sender共享。 元数据维护的是主题的一个[子集],kafka服务器上主题的变更会随时间同步到本地元数据中(即本地元数据与broker的信息并不是每时每刻100%同步的,所以老外把元数据叫做服务器上topic的叫子集)。 如果客户端从元数据中没有查询到一个topic的元数据,将会触发元数据更新(实际并不只是在这种情况下触发元数据更新) If topic expiry is enabled for the metadata, any topic that has not been used within the expiry interval is removed from the metadata refresh set after an update. Consumers disable topic expiry since they explicitly manage topics while producers rely on topic expiry to limit the refresh set. ---如果开启了元数据主题过期,在此段过期时间间隔内未使用的主题将会从元数据中删除。因为消费者显式管理主题,所以消费者禁用主题过期,而生产者则依赖主题过期来实现元数据刷新。
1.两个子类
ConsumerMetadata和ProducerMetadata,两个子类分别负责生产者生产消息和消费者消费消息时关于查询元数据方法的实现,以及维护各个topic信息的过期时间
2.各种xx时间
如刷新元数据的停顿时间,防止请求broker刷新元数据过于频繁;元数据过期时间,用于刷新元数据
3.MetadataCache
实际保存元数据缓存的类,缓存了集群ID,集群节点信息,以及各个topic及其对应partiton的信息。
其中还有一个非常重要的成员变量是Cluster,其保存了Kafka整个集群的完整信息,对比MetadataCache 和Cluster的成员变量发现很多类似的,不明白为什么要保存两份缓存,两个类的成员变量对于以及源码示意如下:
MetadataCache示意:
所属包:org.apache.kafka.clients
An internal mutable cache of nodes, topics, and partitions in the Kafka cluster. This keeps an up-to-date Cluster instance which is optimized for read access.
---Kafka集群中节点、主题和分区的内部可变缓存。这将保持最新的群集实例,该实例已针对读取访问进行了优化。
Cluster示意:
所属包:org.apache.kafka.common
An immutable representation of a subset of the nodes, topics, and partitions in the Kafka cluster.
---Kafka集群中节点、主题和分区的子集的不可变表示。在初始化MetadataCache时也会初始化Cluster:
在调用MetaDataCache进行初始化 if (clusterInstance == null) { // 初始化Cluster computeClusterView(); } else { this.clusterInstance = clusterInstance; } computeClusterView()方法: private void computeClusterView() { List<PartitionInfo> partitionInfos = metadataByPartition.values() .stream() .map(metadata -> MetadataResponse.toPartitionInfo(metadata, nodes)) .collect(Collectors.toList()); // 初始化并将clust对象引用到MetaData的成员变量中 this.clusterInstance = new Cluster(clusterId, nodes.values(), partitionInfos, unauthorizedTopics,invalidTopics, internalTopics, controller, topicIds); }
我目前的理解是Cluster和MeataDataCache是不同层级的缓存,提供给不同场景使用,Cluster也会提供给MeataDataCache访问元集群数据信息;
第二种理解是:MeataDataCache中的缓存数据是【元数据】,Cluster中缓存的数据是【集群信息】,虽然两者很多数据是一致的,但是概念不一样。。。
后面有新的理解再修改这段吧
二、MetaData中的保存的信息
汇总MeataDataCache和Cluster对象中的成员变量,主要的有如下这些:
1.节点---Node
保存有节点ID到节点的映射,以及节点IP,端口信息。
// Node成员变量 private static final Node NO_NODE = new Node(-1, "", -1); private final int id; private final String idString; private final String host; private final int port; private final String rack; // Cache hashCode as it is called in performance sensitive parts of the code (e.g. RecordAccumulator.ready) private Integer hash;
2.主题分区-TopicPartition
保存了一个topic到分区的映射关系,以及这个关系到分区详情的关系,但是MeataDataCache和Cluster使用的分区详情类不一样
MeataDataCache:Map<TopicPartition, PartitionMetadata>
Cluster:Map<TopicPartition, PartitionInfo>
TopicPartition主要成员变量:
// 从成员变量可以看出,一个TopicPartition代表的是 // 一个topic与其某一个partition的[映射关系] // 着重表示[映射关系] private int hash = 0; private final int partition; private final String topic;
3.分区详情-PartitionMetadata/PartitionInfo
这两者都保存了某一分区的主分片ID/节点,副本分片ID/节点,ISR列表
// MeataDataCache---PartitionMetadata成员变量 public final TopicPartition topicPartition; public final Errors error; public final Optional<Integer> leaderId; public final Optional<Integer> leaderEpoch; public final List<Integer> replicaIds; public final List<Integer> inSyncReplicaIds; public final List<Integer> offlineReplicaIds;
// Cluster---PartitionInfo成员变量 private final String topic; private final int partition; private final Node leader; private final Node[] replicas; private final Node[] inSyncReplicas; private final Node[] offlineReplicas;
总结:
本文介绍了Kafka客户端元数据保存了那些数据及其结构,分别为:节点---Node,主题分区-TopicPartition,分区详情-PartitionMetadata/PartitionInfo