Apache Kafka源码分析 - autoLeaderRebalanceEnable
在broker的配置中,auto.leader.rebalance.enable (false)
那么这个leader是如何进行rebalance的?
首先在controller启动的时候会打开一个scheduler,
if (config.autoLeaderRebalanceEnable) { //如果打开outoLeaderRebalance,需要把partiton leader由于dead而发生迁徙的,重新迁徙回去
info("starting the partition rebalance scheduler")
autoRebalanceScheduler.startup()
autoRebalanceScheduler.schedule("partition-rebalance-thread", checkAndTriggerPartitionRebalance,
5, config.leaderImbalanceCheckIntervalSeconds, TimeUnit.SECONDS)
}
定期去做,
checkAndTriggerPartitionRebalance
这个函数逻辑,就是找出所有发生过迁移的replica,即
topicsNotInPreferredReplica
并且判断如果满足imbalance比率,即自动触发leader rebalance,将leader迁回perfer replica
关键要理解什么是preferred replicas?
preferredReplicasForTopicsByBrokers =
controllerContext.partitionReplicaAssignment.filterNot(p => deleteTopicManager.isTopicQueuedUpForDeletion(p._1.topic)).groupBy {
case(topicAndPartition, assignedReplicas) => assignedReplicas.head
}
partitionReplicaAssignment: mutable.Map[TopicAndPartition, Seq[Int]]
TopicAndPartition可以通过topic name和partition id来唯一标识一个partition,Seq[int],表示brokerids,表明这个partition的replicas在哪些brokers上面
从partition的ReplicaAssignment里面过滤掉delete的topic,然后按照assignedReplicas.head进行groupby,就是按照Seq中的第一个brokerid
意思就是说,默认每个partition的preferred replica就是第一个被assign的replica
groupby的结果就是,每个broker,和应该以该broker作为leader的所有partition,即
case(leaderBroker, topicAndPartitionsForBroker)
那么找出里面当前leader不是preferred的,即发生过迁移的,
很简单,直接和leaderAndIsr里面的leader进行比较,如果不相等就说明发生过迁徙
topicsNotInPreferredReplica =
topicAndPartitionsForBroker.filter {
case(topicPartition, replicas) => {
controllerContext.partitionLeadershipInfo.contains(topicPartition) &&
controllerContext.partitionLeadershipInfo(topicPartition).leaderAndIsr.leader != leaderBroker
}
}
并且只有当某个broker上的imbalanceRatio大于10%的时候,才会触发rebalance
imbalanceRatio = totalTopicPartitionsNotLedByBroker.toDouble / totalTopicPartitionsForBroker
对每个partition的迁移过程,
首先preferred的broker要是活着的,并且当前是没有partition正在进行reassign或replica election的,说明这个过程是不能并行的,同时做reassign很容易冲突
// do this check only if the broker is live and there are no partitions being reassigned currently
// and preferred replica election is not in progress
if (controllerContext.liveBrokerIds.contains(leaderBroker) &&
controllerContext.partitionsBeingReassigned.size == 0 &&
controllerContext.partitionsUndergoingPreferredReplicaElection.size == 0 &&
!deleteTopicManager.isTopicQueuedUpForDeletion(topicPartition.topic) &&
controllerContext.allTopics.contains(topicPartition.topic)) {
onPreferredReplicaElection(Set(topicPartition), true)
onPreferredReplicaElection
还是通过partitionStateMachine,来改变partition的状态
partitionStateMachine.handleStateChanges(partitions, OnlinePartition, preferredReplicaPartitionLeaderSelector)
partitionStateMachine会另外分析,这里只需要知道,当前partition的状态是,OnlinePartition –> OnlinePartition
并且是以preferredReplicaPartitionLeaderSelector,作为leaderSelector的策略
PreferredReplicaPartitionLeaderSelector
策略很简单,就是把leader换成preferred replica
def selectLeader(topicAndPartition: TopicAndPartition, currentLeaderAndIsr: LeaderAndIsr): (LeaderAndIsr, Seq[Int]) = {
val assignedReplicas = controllerContext.partitionReplicaAssignment(topicAndPartition)
val preferredReplica = assignedReplicas.head //取AR第一个replica作为preferred
// check if preferred replica is the current leader
val currentLeader = controllerContext.partitionLeadershipInfo(topicAndPartition).leaderAndIsr.leader
if (currentLeader == preferredReplica) { //如果当前leader就是preferred就不需要做了
throw new LeaderElectionNotNeededException("Preferred replica %d is already the current leader for partition %s" .format(preferredReplica, topicAndPartition))
} else {
info("Current leader %d for partition %s is not the preferred replica.".format(currentLeader, topicAndPartition) + " Trigerring preferred replica leader election")
// check if preferred replica is not the current leader and is alive and in the isr
if (controllerContext.liveBrokerIds.contains(preferredReplica) && currentLeaderAndIsr.isr.contains(preferredReplica)) { //判断当前preferred replica所在broker是否活,是否在isr中
(new LeaderAndIsr(preferredReplica, currentLeaderAndIsr.leaderEpoch + 1, currentLeaderAndIsr.isr, currentLeaderAndIsr.zkVersion + 1), assignedReplicas) //产生新的leaderAndIsr
} else {
throw new StateChangeFailedException("Preferred replica %d for partition ".format(preferredReplica) +
"%s is either not alive or not in the isr. Current leader and ISR: [%s]".format(topicAndPartition, currentLeaderAndIsr))
}
}
}
}
Apache Kafka源码分析 - autoLeaderRebalanceEnable的更多相关文章
- Apache Kafka源码分析 – Broker Server
1. Kafka.scala 在Kafka的main入口中startup KafkaServerStartable, 而KafkaServerStartable这是对KafkaServer的封装 1: ...
- apache kafka源码分析-Producer分析---转载
原文地址:http://www.aboutyun.com/thread-9938-1-1.html 问题导读1.Kafka提供了Producer类作为java producer的api,此类有几种发送 ...
- Apache Kafka源码分析 - kafka controller
前面已经分析过kafka server的启动过程,以及server所能处理的所有的request,即KafkaApis 剩下的,其实关键就是controller,以及partition和replica ...
- Apache Kafka源码分析 – Controller
https://cwiki.apache.org/confluence/display/KAFKA/Kafka+Controller+Internalshttps://cwiki.apache.org ...
- Apache Kafka源码分析 – Log Management
LogManager LogManager会管理broker上所有的logs(在一个log目录下),一个topic的一个partition对应于一个log(一个log子目录)首先loadLogs会加载 ...
- Apache Kafka源码分析 - KafkaApis
kafka apis反映出kafka broker server可以提供哪些服务,broker server主要和producer,consumer,controller有交互,搞清这些api就清楚了 ...
- Apache Kafka源码分析 – Replica and Partition
Replica 对于local replica, 需要记录highWatermarkValue,表示当前已经committed的数据对于remote replica,需要记录logEndOffsetV ...
- Apache Kafka源码分析 - ReplicaStateMachine
startup 在onControllerFailover中被调用, /** * Invoked on successful controller election. First registers ...
- Apache Kafka源码分析 - PartitionStateMachine
startup 在onControllerFailover中被调用, initializePartitionState private def initializePartitionState() { ...
随机推荐
- C++Premer Plus学习(五)——函数探幽
一.内联函数 1.优点: 内联函数就是比较省资源,然后一般就是将简短,使用频率高的函数作为内联函数会比较合适. 2.一个demo #include "stdafx.h" #incl ...
- 什么是超级立方体,HyperCube
我试试用我的方式说说如何构造n维空间吧. n维空间在n大于3后,说要画出来,有点难以想象.但从数学的角度看,高维空间这个概念还算比较普通.容易理解的. 与其解释,不如快快开始.我选择用图(Graph) ...
- DOM--1 遵循最佳实践
为重用命名空间而进行规划 (function() { function $(id) { return document.getElementById(id); } function alertNode ...
- 简单几何(线段覆盖) POJ 3347 Kadj Squares
题目传送门 题意:告诉每个矩形的边长,它们是紧贴着的,问从上往下看,有几个还能看到. 分析:用网上猥琐的方法,将边长看成左端点到中心的距离,这样可以避免精度问题.然后先求出每个矩形的左右端点,然后如果 ...
- 使用 IL 实现类型转换
在之前的文章中,我大致介绍过一些类型间的隐式和显式类型转换规则.但当时并未很仔细的研究过<CSharp Language Specification>,因此实现并不完整.而且只部分解决了类 ...
- eBay 消息发送(2)
1.简介 Call Index Doc: http://developer.ebay.com/DevZone/XML/docs/Reference/eBay/index.html 消息发送主要 ...
- Cat VS Dog
Cat VS Dog Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 125536/65536 K (Java/Others)Total ...
- Channel 笔记本项目 (门户客户端 和 wp7客户端(介绍1))
Channel 笔记本项目:(所包含 门户客户端 和 wp7客户端) 首先wp7客户端中,首页向右滑行,到了新闻(博文):(点触某篇新闻后,进入到新闻详细页面,在菜单栏所对应 ...
- java获取获得Timestamp类型的当前系统时间
java获取取得Timestamp类型的当前系统时间java获取取得Timestamp类型的当前系统时间 格式:2010-11-04 16:19:42 方法1: Timestamp d = new T ...
- Medical Image Processing Conference and Journal 医学图像处理会议与期刊
会议: Information Processing in Medical Imaging,IPMI IPMI2013 International Conference on Medical Imag ...