Kakaf02-Kafka拉取元数据的时机

目录

1.Kafka集群元数据信息

2.生产者创建 KafkaProducer 实例时更新元数据

3.生产者调用 doSend() 方法发送消息时更新元数据 

4.消费者更新元数据的时机


1.Kafka集群元数据信息

// 集群元数据信息
public final class Cluster {

    private final boolean isBootstrapConfigured;
    // kafka集群的Broker节点列表
    private final List<Node> nodes;
    // 未授权的topic集合
    private final Set<String> unauthorizedTopics;
    // 无效的topic集合
    private final Set<String> invalidTopics;
    // 内部主题集合
    private final Set<String> internalTopics;
    // Kafka集群的控制节点
    private final Node controller;
    // partition 的详细信息
    private final Map<TopicPartition, PartitionInfo> partitionsByTopicPartition;
    // 一个topic下面有多少个partition
    private final Map<String, List<PartitionInfo>> partitionsByTopic;
    // 一个topic下面有多少个可用的partition
    private final Map<String, List<PartitionInfo>> availablePartitionsByTopic;
    // 一个Node节点上面的partition列表
    private final Map<Integer, List<PartitionInfo>> partitionsByNode;
    // node 与 id 的对应关系
    private final Map<Integer, Node> nodesById;
    private final ClusterResource clusterResource;
}

// TopicPartition: 包含 topic、partition、leader、replicas、isr
public class PartitionInfo {
    // 主题
    private final String topic;
    // 分区编号
    private final int partition;
    // leader副本,每个分区有且只有一个leader副本
    private final Node leader;
    // 单个分区的全部副本集合
    private final Node[] replicas;
    // 单个分区的ISR列表
    private final Node[] inSyncReplicas;
    // 单个分区的OSR列表
    private final Node[] offlineReplicas;
}

2.生产者创建 KafkaProducer 实例时更新元数据

  1. 初始化 KafkaProducer 对象:当使用 new KafkaProducer<String, String>(props) 创建 KafkaProducer 实例时,构造方法中会调用 this.metadata.bootstrap(addresses) 来从 Broker 端拉取元数据到本地。

  2. 设置核心参数:构造函数中会设置以下参数:

    • refreshBackoffMs:更新失败时的重试间隔,默认为 100 毫秒。
    • metadataExpireMs:本地元数据的过期时间,默认为 5 分钟(300000 毫秒)。
    • metadataIdleMs:闲置主题的元数据过期时间,默认也为 5 分钟。
    • ClusterResourceListeners:注册监听器,用于在集群元数据变更时通知客户端。
  3. 集群元数据信息Cluster 类中保存了 Kafka 集群的详细信息,包括 Broker 节点列表、未授权和无效的主题集合、控制节点、分区信息等。

  4. PartitionInfo 类:包含主题、分区编号、Leader 副本、所有副本集合、ISR 列表和 OSR 列表。

  5. MetadataCache 更新:在 KafkaProducer 对象创建时,会强制更新元数据信息,将目标主题的元数据信息拉取到本地缓存。

3.生产者调用 doSend() 方法发送消息时更新元数据 

  1. 调用 doSend() 方法:在 KafkaProducer 调用 send() 方法后,最终会执行 doSend()

  2. 检查元数据可用性:通过 waitOnMetadata() 方法判断目标主题的元数据是否可用。如果本地缓存包含且未过期,则直接返回。

  3. 更新元数据:如果元数据不可用或过期,将进行更新。如果是首次启动或元数据过期,将全量更新;否则,只更新部分需要的 TopicPartition 元数据。

  4. 阻塞等待:主线程将同步阻塞等待拉取最新元数据,最大等待时间为 60 秒(由 max.block.ms 控制)。

  5. 唤醒 Sender 子线程:调用 sender.wakeup() 唤醒 Sender 子线程,进而唤醒 NetworkClient 线程。

  6. 拉取最新元数据:通过 NetworkClient 从 Broker 端拉取最新元数据。

  7. 更新 MetadataCache:Broker 返回最新元数据后,更新本地缓存,包括版本号、最后刷新时间等,并根据需要更新全量或部分元数据信息。

  8. 通知主线程:拉取成功后,通知主线程,主线程根据最新元数据信息发送数据。

这个过程确保了 KafkaProducer 在发送消息时始终使用最新的元数据,从而保证了消息的正确路由和集群的高可用性。

4.消费者更新元数据的时机

  1. 初始化时拉取元数据:当 KafkaConsumer 被实例化时,它会在构造方法中调用 this.metadata.bootstrap(addresses),向 Broker 端发送请求以拉取当前的元数据信息到本地。

  2. 订阅主题匹配新主题时:使用正则表达式订阅主题时(例如 consumer.subscribe(Pattern.compile("test-.*"))),如果新创建的主题与正则表达式匹配,KafkaConsumer 会触发元数据的更新,以包含新主题的相关信息。

  3. 拉取数据前检查元数据:在 ConsumerCoordinator 调用 poll() 方法进行数据拉取之前,需要检查是否需要刷新最新的元数据。这是因为 TopicPartition 的分区副本可能会经历重新选举 Leader 的过程,新的 Leader 可能位于不同的 Broker 节点上。

  4. 元数据过期时更新:当订阅的 Topic 的元数据达到过期时间(由 metadataExpireMs 参数控制),KafkaConsumer 会自动拉取最新的元数据信息,以确保消费者能够获取到最新的分区和副本信息。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值