Controller设计--Kafka从入门到精通(十五)

2022-12-14 17:51:44 浏览数 (2)

上篇文章说到,当leader宕机,这时候follower可以参与竞争leader,但不是所有follower都有资格,只有在ISR里面的follower副本才有资格,在0.9.0.0之前有两个参数,后面版本就一个超时时间,默认10s。Highwatermark 和 log end offset,在hw和leo之间的是未提交的消息在,这些消息是不会被消费,在hw之前的消息是已经同步到副本的消息,这些会被消费。

副本与ISR设计--Kafka从入门到精通(十四)

一个kafka集群中,某个broker被选举出来,即用controller来管理协调kafka集群。

每个kafka集群任意时刻都只能有一个controller。当集群启动时候,所有broker都会参与controller竞选,一旦controller崩溃,其他的broker会重新竞选。

Controller管理状态

一类是每台broker上的分区副本,一类是每个分区的leader副本信息。分为副本状态和分区状态。Controller为了管理这两个分别引入了管理副本状态 和 分区状态。

1)副本状态机(replica state machine)

Kafka为副本定义了7个状态以及每个状态流转规则。

NewReplica:controller创建副本时最初状态。当在这个状态时候,副本只能成为follower副本。

OnlineReplica:启动副本后变为该状态。在该状态下,副本既可以成为follower副本也可以成为leader副本。

OfflineReplica:一旦副本的broler崩溃,则副本变为该状态。

ReplicatDeletionStarted:若开启了topic删除操作,topic所有分区的所有副本都被删除。则进入该状态。

ReplicaDeletionSuccessful:副本成功响应了删除副本请求,则进入该状态。

ReplicaDeletionIneligible:若副本删除失败,则进入该状态。

NonExistentReplica:若副本成功删除,则进入改状态。

当创建某个topic后,该topic分区下所有副本都是NonExistent状态的,此时controller加载zookeeper中该topic每个分区的所有副本信息存到内存中,同时把状态改为new,之后controller选择该分区副本列表中第一个副本作为分区leader副本并设置所有副本进入ISR,然后在zookeeper中持久化该决定。

一旦确定ISR和leader后,controller会将所有副本状态设置为online,正常工作。

当开启了topic删除操作时,controller会尝试停止所有副本,此时副本停止向leader获取数据,若停止的副本是leader,则controller会设置分区leader为no_leader,之后副本为offline状态。一旦都进入到offline时,controller会将副本进一步变为replicaDeleteTionStarted表示删除开始。删除成功则successful,删除失败则Ineligible。

2)分区状态机(partition state machine)

除了副本状态,controller还引入了分区状态机来负责集群下所有分区管理状态。

NonExistent:表示不存在的分区或已删除的分区。

NewPartition:一旦被创建,分区便处于该状态。此时,kafka已经为分区确定了副本列表,但尚未选举出leader和ISR.

onlinePatition:一旦该分区的leader被选出,则进入该状态。这也是分区正常工作时候的状态。

OfflinePartition:在成功选举出leader后,若leader所在broker宕机,则分区将进入该状态,表明无法正常工作。

当创建topic时,controller负责创建分区对象,他首先会短暂将所有分区状态设置为nonExitent,之后马上读取zookeeper中的副本分配方案。然后令分区状态进入newPartition。处于newPartition状态分区尚未有leader和ISR,因此controller会初始化leader和ISR信息并设置分区状态为onlinePartition。

若用户发起删除topic操作或者关闭broker操作,那么controller会令受影响的分区进入offline状态,如果是删除操作,controller会开启分区下面副本操作,并设置状态为nonExistent,如果是关闭broker操作,则controller会判断是否是分区leader。

Controler职责

1、更新集群元数据信息。

2、创建topic。

3、删除topic。

4、分区重分配。

5、Preferred leader 副本选举。

6、Topic 分区扩展。

7、Broker加入集群。

8、Broker崩溃。

9、受控关闭。

10、Controller leader选举。

1)更新集群元数据信息

当分区信息发生变更,controller将变更后的信息封装进updateMetadataRequests请求,然后发送给集群中的每个broker,这样clients在请求数据时总会获取最新、最及时的分区信息。

2)创建topic

Controller启动时候会创建一个zookeeper的监听器,该监听器的任务就是监听topic节点变化。

A. 通过kafka-topics脚本--create创建。

B. 构造createTopicsRequest请求创建。

C. 配置broker端参数auto.create.topics.enable为true,然后发送metadataRequest请求。

无论上面哪种方式创建,都是在/brokers/topics下创建对应的znode,然后把topic的分区以及对应副本对应列表都写入znode中。

3)删除topic

A、通过kafka-topics脚本删除--delete。

B、构造deleteTopicsRequest。

这两种方式都是在/brokers/delete_topics下新建znode。

4)分区重分配

分区重分配操作通常是由kafka集群的管理员发起的,旨在对topic所有分区重新分配副本所在broker的位置,以期望实现更均匀分配效果。

5)preferred leader 选举

为了避免分区副本分配不均匀,kafka引入了preferred副本概念,解决分区不均匀问题。

A、设置broker端参数auto.leader.rebalance.enable为true,这样controller定时自动调整preferred leader。

B、通过kafka-preferred-repica-election脚本手动触发。

6)topic分区扩展

在kafka集群运行过程中,用户可能会发现某些topic的现有分区不足以支持业务量,因此需要考虑增加分区。

7)broker加入集群

每个broker成功启动都会在/broker/ids下创建一个znode,并写入broker信息。如果让kafka动态维护broker列表,就必须注册一个zookeeper监听器时刻监控目录下的变化。

8)broker崩溃

由于当前broker在zookeeper中注册znode是临时节点,因此一旦broker崩溃,broker与zookeeper的会话失效并导致临时节点被删除,上面监听broker加入的那些监听器同样用来监视那些推出群聊的broker列表。

9)受控关闭

通过kafka-service-stop是通过脚本、kill -9 、kill -15正常关闭,而broker崩溃或强制推出通常是以“掉电”或者“kill -9”的方式实现的。前者被称为受控关闭。

10)controller leader选举

作为重要组件,controller必定支持故障转移,宕机时候必须保证及时选出新的controller。

1、关闭controller所在broker。

2、当前controller所在broker宕机或者崩溃。

3、手动删除zookeeper下面的/controller节点。

4、说动向/controller下写入新的broker id。

0 人点赞