Kafka科普系列 | 原来Kafka中的选举有这么多?

面试官在考查你Kafka知识的时候极可能会故弄玄虚的问你一下:Kafka中的选举时怎么回事?除非问你具体的哪一种选举,不然问这种问题的面试官多半也是对Kafka只知其一;不知其二,这个时候就是“弄死”他的时候。固然若是你没有必定的知识储备,那么就是你被“弄死”的时候。面试

通常问这个问题,那么他确定知道其中的一种,好比分区leader的选举。所谓分区leader的选举就是当ISR中的leader副本歇菜了,再从新选举一个的过程。对于这个问题就是你反客为主的机会,由于Kafka中的选举有多处,可不止分区leader的选举这一处,就算指明问分区leader的选举,那么也须要分4种状况具体分析。而这里面的细节是大多数人不甚明了的。算法

Kafka中的选举大体能够分为三大类:控制器的选举、分区leader的选举以及消费者相关的选举,这里还能够具体细分为7个小类。咱们一一来过一下,本文只是简单罗列下大体的内容,至于内部具体的细节逻辑就须要靠读者本身去探索啦。虐人仍是被虐就靠你的自驱力了。bash

控制器的选举

在Kafka集群中会有一个或多个broker,其中有一个broker会被选举为控制器(Kafka Controller),它负责管理整个集群中全部分区和副本的状态等工做。好比当某个分区的leader副本出现故障时,由控制器负责为该分区选举新的leader副本。再好比当检测到某个分区的ISR集合发生变化时,由控制器负责通知全部broker更新其元数据信息。微信

Kafka Controller的选举是依赖Zookeeper来实现的,在Kafka集群中哪一个broker可以成功建立/controller这个临时(EPHEMERAL)节点他就能够成为Kafka Controller。网站

这里须要说明一下的是Kafka Controller的实现仍是至关复杂的,涉及到各个方面的内容,若是你掌握了Kafka Controller,你就掌握了Kafka的“半壁江山”。篇幅所限,这里就不一一展开了,有兴趣的读者能够查阅一下《深刻理解Kafka》中第6章的相关内容。spa

分区leader的选举

这里不说什么一致性协议(PacificA)相关的内容,只讲述具体的选举内容。scala

分区leader副本的选举由Kafka Controller 负责具体实施。当建立分区(建立主题或增长分区都有建立分区的动做)或分区上线(好比分区中原先的leader副本下线,此时分区须要选举一个新的leader上线来对外提供服务)的时候都须要执行leader的选举动做。设计

基本思路是按照AR集合中副本的顺序查找第一个存活的副本,而且这个副本在ISR集合中。一个分区的AR集合在分配的时候就被指定,而且只要不发生重分配的状况,集合内部副本的顺序是保持不变的,而分区的ISR集合中副本的顺序可能会改变。注意这里是根据AR的顺序而不是ISR的顺序进行选举的。这个提及来比较抽象,有兴趣的读者能够手动关闭/开启某个集群中的broker来观察一下具体的变化。code

还有一些状况也会发生分区leader的选举,好比当分区进行重分配(reassign)的时候也须要执行leader的选举动做。这个思路比较简单:从重分配的AR列表中找到第一个存活的副本,且这个副本在目前的ISR列表中。cdn

再好比当发生优先副本(preferred replica partition leader election)的选举时,直接将优先副本设置为leader便可,AR集合中的第一个副本即为优先副本。

Kafka中有不少XX副本的称呼,若是不是很了解,能够关注本系列的下一篇《Kafka科普系列 | Kafka中到底有多少种副本?》

还有一种状况就是当某节点被优雅地关闭(也就是执行ControlledShutdown)时,位于这个节点上的leader副本都会下线,因此与此对应的分区须要执行leader的选举。这里的具体思路为:从AR列表中找到第一个存活的副本,且这个副本在目前的ISR列表中,与此同时还要确保这个副本不处于正在被关闭的节点上。

消费者相关的选举

对于这部份内容的理解,额。。若是你对消费者、消费组、消费者协调器以及组协调器不甚理解的话,那么。。。职能毛遂自荐《深刻理解Kafka》一书了,嘿嘿。

组协调器GroupCoordinator须要为消费组内的消费者选举出一个消费组的leader,这个选举的算法也很简单,分两种状况分析。若是消费组内尚未leader,那么第一个加入消费组的消费者即为消费组的leader。若是某一时刻leader消费者因为某些缘由退出了消费组,那么会从新选举一个新的leader,这个从新选举leader的过程又更“随意”了,相关代码以下:

//scala code.
private val members = new mutable.HashMap[String, MemberMetadata]
var leaderId = members.keys.head
复制代码

解释一下这2行代码:在GroupCoordinator中消费者的信息是以HashMap的形式存储的,其中key为消费者的member_id,而value是消费者相关的元数据信息。leaderId表示leader消费者的member_id,它的取值为HashMap中的第一个键值对的key,这种选举的方式基本上和随机无异。整体上来讲,消费组的leader选举过程是很随意的。

插播:近日发现文章被盗的厉害,发文几个小时文章就在各大门户网站上出现,全都是标的原创。虽然没有能力制止,可是我发现大多不仔细看直接抄的(有连我下面的公众号二维码也抄了去的,固然也有用PS来P掉我图片水印的鸡贼操做),因此机智的我。。不如在文章中插播一下个人书,让他们盗了去也好替我宣传宣传。我是皮的很~~

到这里就结束了吗?还有分区分配策略的选举呢。

许你对此有点陌生,可是用过Kafka的同窗或许对partition.assignment.strategy(取值为RangeAssignor、RoundRobinAssignor、StickyAssignor等)这个参数并不陌生。每一个消费者均可以设置本身的分区分配策略,对消费组而言须要从各个消费者呈报上来的各个分配策略中选举一个彼此都“信服”的策略来进行总体上的分区分配。这个分区分配的选举并不是由leader消费者决定,而是根据消费组内的各个消费者投票来决定的。至于具体的细节么。。。嘿嘿。


欢迎支持笔者小册:《图解Kafka之实战指南》和《图解Kafka之核心原理


欢迎支持笔者新做:《深刻理解Kafka:核心设计与实践原理》和《RabbitMQ实战指南》,同时欢迎关注笔者的微信公众号:朱小厮的博客。

相关文章
相关标签/搜索