|NO.Z.00074|——————————|BigDataEnd|——|Hadoop&kafka.V59|——|kafka.v59|稳定性|控制器|

一、控制器
### --- 控制器

~~~     Kafka集群包含若干个broker,broker.id指定broker的编号,编号不要重复。
~~~     Kafka集群上创建的主题,包含若干个分区。
~~~     每个分区包含若干个副本,副本因子包括了Follower副本和Leader副本。
~~~     副本又分为ISR(同步副本分区)和OSR(非同步副本分区)。
~~~     控制器就是一个broker。
~~~     控制器除了一般broker的功能,还负责Leader分区的选举。
二、broker选举
### --- broker选举

~~~     集群里第一个启动的broker在Zookeeper中创建临时节点<KafkaZkChroot>/controller 。
~~~     其他broker在该控制器节点创建Zookeeper watch对象,使用Zookeeper的监听机制接收该节点的变更。
~~~     即:Kafka通过Zookeeper的分布式锁特性选举集群控制器。
~~~     下图中,节点/myKafka/controller 是一个zookeeper临时节点,其中"brokerid":0 ,
~~~     表示当前控制器是broker.id为0的broker。
[zk: localhost:2181(CONNECTED) 0] get /myKafka/controller
{"version":1,"brokerid":0,"timestamp":"1632434689604"}
cZxid = 0x432
ctime = Fri Sep 24 06:04:49 CST 2021
mZxid = 0x432
mtime = Fri Sep 24 06:04:49 CST 2021
pZxid = 0x432
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x100001417d10001
dataLength = 54
numChildren = 0
### --- 每个新选出的控制器通过 Zookeeper 的条件递增操作获得一个全新的、数值更大的 controllerepoch。

~~~     其他 broker 在知道当前 controller epoch 后,
~~~     如果收到由控制器发出的包含较旧epoch 的消息,就会忽略它们,以防止“脑裂”。
~~~     比如当一个Leader副本分区所在的broker宕机,需要选举新的Leader副本分区,
~~~     有可能两个具有不同纪元数字的控制器都选举了新的Leader副本分区,
~~~     如果选举出来的Leader副本分区不一样,听谁的?脑裂了。有了纪元数字,
~~~     直接使用纪元数字最新的控制器结果。
[zk: localhost:2181(CONNECTED) 1] get /myKafka/controller_epoch
4
cZxid = 0x1b
ctime = Thu Sep 23 22:48:42 CST 2021
mZxid = 0x433
mtime = Fri Sep 24 06:04:49 CST 2021
pZxid = 0x1b
cversion = 0
dataVersion = 3
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 1
numChildren = 0
~~~     # 当控制器发现一个 broker 已经离开集群,
~~~     # 那些失去Leader副本分区的Follower分区需要一个新Leader(这些分区的首领刚好是在这个 broker 上)。
~~~     1. 控制器需要知道哪个broker宕机了?
~~~     2. 控制器需要知道宕机的broker上负责的时候哪些分区的Leader副本分区?
~~~     # 下图中, <KafkaChroot>/brokers/ids/0 保存该broker的信息,
~~~     # 此节点为临时节点,如果broker节点宕机,该节点丢失。
~~~     # 集群控制器负责监听ids 节点,一旦节点子节点发送变化,集群控制器得到通知。
[zk: localhost:2181(CONNECTED) 2] get /myKafka/brokers/ids/0   
{"listener_security_protocol_map":{"PLAINTEXT":"PLAINTEXT"},"endpoints":["PLAINTEXT://hadoop01:9092"],"jmx_port":-1,"host":"hadoop01","timestamp":"1632434690085","port":9092,"version":4}
cZxid = 0x437
ctime = Fri Sep 24 06:04:50 CST 2021
mZxid = 0x437
mtime = Fri Sep 24 06:04:50 CST 2021
pZxid = 0x437
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x100001417d10001
dataLength = 186
numChildren = 0
### --- 控制器遍历这些Follower副本分区,并确定谁应该成为新Leader分区,

~~~     然后向所有包含新Leader分区和现有Follower的 broker 发送请求。
~~~     该请求消息包含了谁是新Leader副本分区以及谁是Follower副本分区的信息。
~~~     随后,新Leader分区开始处理来自生产者和消费者的请求,
~~~     而跟随者开始从新Leader副本分区消费消息。
~~~     当控制器发现一个 broker 加入集群时,
~~~     它会使用 broker ID 来检查新加入的 broker 是否包含现有分区的副本。
~~~     如果有,控制器就把变更通知发送给新加入的 broker 和其他 broker,
~~~     新 broker上的副本分区开始从Leader分区那里消费消息,与Leader分区保持同步。
### --- 结论:

~~~     Kafka 使用 Zookeeper 的分布式锁选举控制器,并在节点加入集群或退出集群时通知控制器。
~~~     控制器负责在节点加入或离开集群时进行分区Leader选举。
~~~     控制器使用epoch 来避免“脑裂”。“脑裂”是指两个节点同时认为自己是当前的控制器。

 
 
 
 
 
 
 
 
 

Walter Savage Landor:strove with none,for none was worth my strife.Nature I loved and, next to Nature, Art:I warm'd both hands before the fire of life.It sinks, and I am ready to depart
                                                                                                                                                   ——W.S.Landor

 

 

posted on   yanqi_vip  阅读(3)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

导航

统计

点击右上角即可分享
微信分享提示