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() { ...
随机推荐
- 开源的DevOps开发工具箱
DevOps是一组过程.方法与系统的统称,用于促进开发(应用程序/软件工程).技术运营和质量保障(QA)部门之间的沟通.协作与整合.在DevOps的整个流程中,使用一些开源工具可以促进开发与运维之间的 ...
- android自动更新程序,安装完以后就什么都没有了,没有出现安装成功的界面的问题
转载自: http://blog.csdn.net/lovexieyuan520/article/details/9250099 在android软件开发中,总是需要更新版本,所以当有新版本开发的时候 ...
- .net 日期格式转换
DateTime dt = DateTime.Now; dt.ToString();//2005-11-5 13:21:25dt.ToFileTime().ToString();//127756416 ...
- jQuery对表单、表格的操作及更多应用(中:表格应用)
内容摘录自锋利的JQuery一书 二.表格应用 1 表格隔行变色(:odd和:even选择器 P157) $(function(){ $("tr:odd").addClass(&q ...
- office2010永久的密钥
1.Office Professional Plus 2010: 6QFDX-PYH2G-PPYFD-C7RJM-BBKQ8 BDD3G-XM7FB-BD2HM-YK63V-VQFDK 2.O ...
- POJ 2342 Label:树形dp
Anniversary party Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 6955 Accepted: 4003 ...
- 用Java通过串口发送手机短信
用Java通过串口发短信其实很简单,因为有现成的类库供我们使用.有底层的类库,也有封装好一点的类库,下面我介绍一下在 Win32 平台下发送短信的方法. 如果你想用更底层的类库开发功能更强大的应用程序 ...
- 关于UIWebView的总结
关于UIWebView的总结 前言 今天参加了 Adobe 和 CSDN 组织的一个关于 PhoneGap 的开发讲座 ,而 PhoneGap 在 iOS 设备上的实现就是通过 UIWebView 控 ...
- thinkphp模型没继承model报的错
Call to undefined method RoleModel::query() 错误位置 FILE: H:\www\tpsmarty\shop\Lib\Model\RoleModel.clas ...
- 数据库SQL及相关
//1.生成随机数 ROUND(((89 - 71 -1) * RAND() + 71), 0) DECLARE @Result INT DECLARE @Upper INT DECLARE @Low ...