Kafka源码阅读 —— KafkaController(2)

Controller与broker之间的消息通道

当Controller做出动作时,需要向集群中的broker发送控制消息。发送的消息三种:LeaderAndIsrRequest、UpdateMetadataRequest和StopReplicaRequest, broker收到消息后,通过KafkaApis.handle进行处理————事实上,KafkaApis.handle是broker上的业务线程执行的主要工作,根据不同的消息类型分发给不同的函数处理。
ControllerChannelManager类负责向broker发送消息,其中包含一个map,存放brokerId -> ControllerBrokerStateInfo的映射。
ControllerBrokerStateInfo的定义如下:

case class ControllerBrokerStateInfo(channel: BlockingChannel,
                                     broker: Broker,
                                     messageQueue: BlockingQueue[(RequestOrResponse, (RequestOrResponse) => Unit)],
                                     requestSendThread: RequestSendThread)

其中channel是连接broker的阻塞通道,broker参数是broker的IP,端口等信息,messageQueue是消息队列,存放的是需要发送的request,requestSendThread是发送线程。其实就是简单地生产者——消费者模式,KafkaController向对应broker的messageQueue中放入消息,requestSendThread负责发送消息,收到相应后通过callback函数——就是messageQueue中的第二个参数进行处理。
ControllerBrokerRequestBatch类中包含三个Map,即leaderAndIsrRequestMap,stopReplicaRequestMapupdateMetadataRequestMap,因为KafkaController一个操作一般会需要向多个broker发送消息,通过新建ControllerBrokerRequestBatch实例,并组装向各个broker的消息,可以简化代码。需要说明的是,在向ControllerBrokerRequestBatch中添加LeaderAndIsrRequest消息时,同时会添加一条给所有broker的UpdateMetadataReuqest消息,因为Metadata存在于所有broker上,其中包含集群中所有TopicAndPartition的信息,在leader变化时需要更新所有broker的metadata。

LeaderAndIsrRequest消息

LeaderAndIsrRequest消息中包含关键信息的两个字段:

//(topic,partitionId) -> partitionStateInfo,即partition和对应的Leader,ISR,AR,leader_epoch信息
partitionStateInfos: Map[(String, Int), PartitionStateInfo],
//本条消息中可能包含多个partition -> partitionStateInfo;leaders变量是这些partition的leader所在broker的集合
leaders: Set[Broker]

收到LeaderAndIsr请求后的操作
收到LeaderAndIsr消息后,由ReplicaManager.becomeLeaderOrFollower进行处理,对于某个partition,如果当前Broker上的副本将成为Leader,则在ReplicaManager.makeLeaders函数中,执行成为Leader的必要操作,包括更新相应Partition实例的ISR, leaderEpoch,leaderReplicaId(当前broker),hw等。对于其他成为Follower的副本,则需要添加到相应Partition的Fecher,用于同步Leader上的log,此外,同样通过makeFollowers函数更新Partition实例ISR(清空),AR,leaderEpoch信息。
makeLeaders和makeFollowers中对topic == "__consumer_offsets"的情况都作了特殊处理,成为Leader时,需要从log中把属于当前分区的Offset项恢复到OffsetCache中,而成为Follower时,在之前为Leader的情况下,需要把属于当前Partition的Offset项清除。

UpdateMetadataRequest消息

UpdateMetadataRequest消息中包含的重要字段有:

//和LeaderAndIsrRequest中一样,就是partition的状态信息,Leader,ISR,AR,leader_epoch
partitionStateInfos: Map[TopicAndPartition, PartitionStateInfo],
//所有还活着的broker列表
aliveBrokers: Set[Broker]

KafkaApis类中存在一个MetadataCache类的实例,MetadataCache类中有两个重要字段:

//topic->(partitionId, partitionStateInfo),即集群中所有partition的状态信息
val cache: mutable.Map[String, mutable.Map[Int, PartitionStateInfo]],
//brokerId -> Broker,即活着的Broker
var aliveBrokers: Map[Int, Broker]

收到UpdatemetadataRequest消息后,KafkaApis类更新MetadataCache实例中的chace字段和aliveBroker字段,当consumer请求metadata时直接从cache中获取。MetadataCache实例在所有broker上都是一致的,也就是说,无论consumer向哪个broker发起请求,都能获取所有topicAndPartition的metadata信息。

StopReplicaRequest消息

StopReplicaRequest消息中的字段包含:

//是否是删除partition场景
deletePartitions: Boolean,
//须执行stop操作的partitions,同一broker上只有partition的一个replica
partitions: Set[TopicAndPartition]

收到stopReplica的消息后,ReplicaManager会移除replica所在的partition的Fetcher,即不再向该partition的leader拉取新的数据,如果不是删除partition(参数deletePartition=false)场景,这是唯一需要做的一件事。如果是删除partition场景,则还需要去删除partition(参数deletePartition=true)在本地的log。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值