kafka 请求 UpdateMetadata 处理

文章详细阐述了Kafka集群中Controller如何发送元数据更新请求,其他Broker如何处理这些更新,以及元数据在本地缓存的管理和获取。元数据更新涉及到创建主题、副本主从切换等操作,而MetadataCache则存储集群的元数据信息,提供不同方法获取主题、分区等信息。

1.Controller 发送集群元数据更新请求

集群 Controller 负责元数据的管理,保存有一个 event 事件队列,如果 event 事件是通知其他节点更新集群元数据的话就会广播元数据更新请求出去。在创建主题、副本主从切换等等都会触发这个过程。


ControllerEventManager.doWork() 从事件队列queue中获取到事件:QueuedEvent(event=LeaderAndIsrResponseReceived()
ControllerChannelManager.RequestSendThread.doWork() 轮训到队列中待发送请求 ApiKeys=UPDATE_METADATA
NetworkClient.doSend() 发送集群内部请求 ApiKey=UPDATE_METADATA (org.apache.kafka.clients.NetworkClient)

2.其他Broker处理元数据更新


KafkaApis.handle()     =>    处理客户端请求:UPDATE_METADATA
KafkaApis.handleUpdateMetadataRequest()     =>    更新元数据
Kafkaapis.isBrokerEpochStale()     =>    校验epoch
ReplicaManager.maybeUpdateMetadataCache()    =>    更新元数据
MetadataCache.updateMetadata()    =>    更新元数据
MetaCache.addOrUpdatePartitionInfo    =>    更新元数据

最终元数据保存在每个 boker 的缓存 metadataSnapshot 属性中。


def updateMetadata(correlationId: Int, updateMetadataRequest: UpdateMetadataRequest): Seq[TopicPartition] = {
  inWriteLock(partitionMetadataLock) {
    updateMetadataRequest.liveBrokers.forEach { broker =>
      // ..
      // 这里替换内存中的缓存
      metadataSnapshot = MetadataSnapshot(partitionStates, topicIds.toMap, controllerIdOpt, aliveBrokers, aliveNodes)
    }
  }
}


3.元数据本地缓存获取

每个节点都会创建一个  ZkMetadataCache 缓存对象如果是 Raft协议的话就是使用的 RaftMetadataCache 缓存,里面有个 metadataSnapshot 属性就缓存了集群所有元数据,并提供各个 get() 方法来获取主题、分区等等信息。

class ZkMetadataCache(brokerId: Int) extends MetadataCache with Logging {
        // 集群元数据缓存结构
        private var metadataSnapshot: MetadataSnapshot;
        getPartitionMetadata();
        getTopicMetadata();
        getAllTopics();
        getAllPartitions();
        getPartitionInfo();
        getPartitionLeaderEndpoint();
        getControllerId();
        getClusterMetadata();
}

其中分区信息定义:
public static class UpdateMetadataPartitionState implements Message {
    String topicName;   // 主题
    int partitionIndex; // 分区编号
    int controllerEpoch;    // Controller 的 epoch 任期
    int leader; // 主副本所在 brokerId
    int leaderEpoch;    // 主副本所在 broker 的 epoch 任期
    List<Integer> isr;  // ISR列表,也就是保持 FETCH 同步的所有 broker 节点
    int zkVersion;
    List<Integer> replicas; // 副本列表
    List<Integer> offlineReplicas;  // 离线副本列表
    private List<RawTaggedField> _unknownTaggedFields;
}


4.处理 METADATA 请求


获取集群元数据,客户端发送 METADATA 请求获取结果:
KafkaApis.handle()     =>    处理客户端请求:METADATA
KafkaApis.handleTopicMetadataRequest()    =>    获取集群元数据

响应结果:

MetadataResponseData(
        throttleTimeMs=0,
        brokers=[
                MetadataResponseBroker(nodeId=2, host='localhost', port=29092, rack=null),
                MetadataResponseBroker(nodeId=1, host='localhost', port=19092, rack=null)],
        clusterId='ZNcsoJSfQQSMHXX92InNhA',
        controllerId=1,
        topics=[
                MetadataResponseTopic(
                        errorCode=0,
                        name='flinkin-01',
                        topicId=4I1Ms6FqSBWRkJMPI6BdcA,
                        isInternal=false,
                        partitions=[
                                MetadataResponsePartition(errorCode=0, partitionIndex=0, leaderId=2, leaderEpoch=7, replicaNodes=[1, 2], isrNodes=[2, 1], offlineReplicas=[])
                        ],
                        topicAuthorizedOperations=-2147483648
               )
        ],
        clusterAuthorizedOperations=-2147483648
)


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

0x13

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值