PartitionStateMachine 记录了集群所有TopicPartition的状态信息,它记录着每个分区的状态流转。Kafka 中的分区状态共有以下4种类型:
1、NonExistentPartition:表示该分区没有被创建过或创建之后又被删除了,有效前置状态是 OfflinePartition;
2、NewPartition:分区创建后,将处于这个状态。此时分区还没有 leader 和 isr,有效前置状态是 NonExistentPartition;
3、OnlinePartition:一旦这个分区的 leader 被选举出来,将处于这个状态。有效前置状态是 NewPartition、OnlinePartition、OfflinePartition;
4、OfflinePartition:当分区的 leader 宕机,分区会被转移到这个状态。有效前置状态是 NewPartition、OnlinePartition、OfflinePartition。
PartitionStateMachine 初始化
PartitionStateMachine先调用initializePartitionState()初始化集群中所有分区的状态:
1)如果分区有LeaderAndIsr,当分区leader所在的Broker是存活的,那么将其状态设置为OnlinePartition,否则设置为OfflinePartition;
2)如果分区没有LeaderAndIsr,那么将其状态设置为NewPartition。
initializePartitionState()方法中,只是将分区的状态更新到分区状态机的partitionState中,并没有真正的进行状态转移。
后面会调用triggerOnlinePartitionStateChange(),为所有的状态为NewPartition/OnlinePartition的分区进行leader选举。选举成功后,状态会被设置为OnlinePartition。
以上的目的是为了将所有状态为NewPartition/OnlinePartition的分区转移到OnlinePartition,它做了2件事:
1)状态转移;
2)发送相应的请求。
分区状态转移
状态转换为 NewPartition
NewPartition是分区刚创建时的状态,处理逻辑如下:
1)校验前置状态,有效的前置状态为NonExistentPartition;
2)将该分区设置为NewPartition状态。
状态转换为 OnlinePartition
OnlinePartition是分区正常工作时的状态,此时分区已经成功选举出了leader,实现逻辑如下:
1)将分区集合切分为:NewPartition和(OfflinePartition|OnlinePartition);
2)如果前置状态是NewPartition,那么为该分区选举leader,更新到ZK和控制器上下文中,如果没有副本存活,则抛出异常;
3)如果前置状态是OnlinePartition|OfflinePartition,需要传入leader选举的策略,触发分区的leader选举;
4)更新分区状态为OnlinePartition。
对于上面几种情况,无论前置状态是什么,最后都会触发分区的leader选举。成功后,会向这个分区的所有副本发送LeaderAndIsr请求。
状态转换为 OfflinePartition
OfflinePartition是分区leader宕机后,转移到的状态。如果分区转移到这个状态,那么就意味着这个分区没有可用leader。
1)校验前置状态,有效的前置状态为 NewPartition、OnlinePartition或OfflinePartition;
2)将分区的状态设置为OfflinePartition。
状态转换为 NonExistentPartition
NonExistentPartition表示已经处于OfflinePartition状态的分区,已经从metadata和ZK中删除。
1)校验前置状态,有效前置状态为OfflinePartition;
2)将该分区的状态转移为NonExistentPartition。
参考:《Kafka技术内幕》、《Apache Kafka 源码剖析》、Kafka源码