大数据-65 Kafka 高级特性 Broker ISR 宕机重平衡 实测详解

90 阅读7分钟

点一下关注吧!!!非常感谢!!持续更新!!!

🚀 AI篇持续更新中!(长期更新)

AI炼丹日志-31- 千呼万唤始出来 GPT-5 发布!“快的模型 + 深度思考模型 + 实时路由”,持续打造实用AI工具指南!📐🤖

💻 Java篇正式开启!(300篇)

目前2025年08月11日更新到: Java-94 深入浅出 MySQL EXPLAIN详解:索引分析与查询优化详解 MyBatis 已完结,Spring 已完结,Nginx已完结,Tomcat已完结,分布式服务正在更新!深入浅出助你打牢基础!

📊 大数据板块已完成多项干货更新(300篇):

包括 Hadoop、Hive、Kafka、Flink、ClickHouse、Elasticsearch 等二十余项核心组件,覆盖离线+实时数仓全栈! 大数据-278 Spark MLib - 基础介绍 机器学习算法 梯度提升树 GBDT案例 详解

请添加图片描述

章节内容

上节我们完成了如下的内容: 我们模拟了让分区重新分配的过程,在业务上实际发生的情况。比如:当几台Kafka节点不够用后,我们将对Kafka进行扩容,但是此时遇到的问题是,之前的分区不会分配到新的Kafka节点上,那此时我们需要借助Kafka提供的脚本来实现这一过程:

  • Kafka分区重分配
  • 包含启动服务、创建主题、新增服务等操作
  • 查看集群、生成JSON、执行计划
  • 最终确认完成了新加Kafka节点后,分区进行了重分配。

在这里插入图片描述

Kafka启动再平衡机制详解

初始分区分配策略

在Kafka集群中创建新主题时,管理员可以手动指定分区副本的分配方案,这包括:

  1. 明确设置每个分区的Leader副本位于哪个Broker节点
  2. 配置每个分区的Follower副本分布在哪些Broker节点

例如,对于一个3副本的主题,管理员可以这样规划:

  • 分区0:Leader在Broker1,Follower在Broker2和Broker3
  • 分区1:Leader在Broker2,Follower在Broker3和Broker1
  • 分区2:Leader在Broker3,Follower在Broker1和Broker2

这种初始分配保证了Leader副本在集群中的均衡分布。

角色转换导致的不均衡问题

在系统运行过程中,以下几种情况会导致Leader分布失衡:

  1. Broker故障恢复

    • 当某Broker宕机时,其上的Leader分区会自动转移到其他Broker的Follower副本
    • 该Broker恢复后,并不会自动恢复原来的Leader角色
  2. 自动Leader选举

    • Kafka的Controller会监控Broker可用性
    • 当检测到Leader不可用时,会从ISR(In-Sync Replicas)中选择新的Leader
  3. 滚动重启影响

    • 在集群维护期间,如果逐个重启Broker
    • 每次重启都会触发Leader转移,可能导致Leader最终集中在少数节点

不均衡带来的性能问题

Leader分区过度集中会导致:

  1. 网络I/O瓶颈

    • 所有生产者和消费者的读写请求都集中在少数Broker
    • 这些节点的网络带宽可能成为瓶颈
  2. CPU资源竞争

    • Leader需要处理更多的请求编解码和磁盘I/O
    • 集中导致CPU使用率不均衡
  3. 磁盘I/O压力

    • 虽然所有副本都要写入数据
    • 但Leader需要处理更多的客户端请求

再平衡解决方案

Kafka提供了以下机制来重新均衡Leader分布:

  1. 自动再平衡

    • 通过auto.leader.rebalance.enable=true启用
    • Controller会定期检查Leader分布均衡性
    • 当检测到不均衡时自动触发Leader切换
  2. 手动触发

    kafka-leader-election --bootstrap-server <broker_list> \
    --election-type PREFERRED --topic <topic_name> --all-topic-partitions
    
  3. 再平衡算法

    • 计算当前集群中每个Broker的Leader比例
    • 将超出平均值的Broker上的Leader转移到其他Broker
    • 确保转移后各Broker的Leader数量差异在阈值内
  4. 最佳实践

    • 建议在业务低峰期执行再平衡
    • 监控Leader切换对客户端的影响
    • 可以设置leader.imbalance.check.interval.seconds调整检查频率

启动服务

目前我们需要启动两台Kafka进行测试: 分别在h121 和 h122节点上启动服务

kafka-server-start.sh /opt/servers/kafka_2.12-2.7.2/config/server.properties

h121

在这里插入图片描述

h122

在这里插入图片描述

新建主题

kafka-topics.sh --zookeeper h121.wzk.icu:2181 --create --topic topic_test_01 --replica-assignment "0:1,1:0,0:1"

该命令的解释:

  • 创建了主题 topic_test_01
  • 有三个分区,每个分区两个副本

创建的结果如下图: 在这里插入图片描述

查看主题

我们可以通过如下的命令进行查看:

kafka-topics.sh --zookeeper h121.wzk.icu:2181 --describe --topic topic_test_01 

执行结果如下图: 在这里插入图片描述

主题信息

  • 主题名称 topic_test_01
  • 分区数 3
  • 复制因子 2

分区详情

分区0:

  • Leader 0
  • 副本 0,1
  • ISR(同步副本集合)0,1

分区1:

  • Leader 1
  • 副本:1,0
  • ISR(同步副本集合)1,0

分区2:

  • Leader 0
  • 副本 0,1
  • ISR(同步副本集合)0,1

模拟宕机

停止节点

我们结束掉 h122 的机器的Kafka

此时查看我们的主题信息:

kafka-topics.sh --zookeeper h121.wzk.icu:2181 --describe --topic topic_test_01

运行结果如下图所示: 在这里插入图片描述

分析解释

  • 通过详细的状态对比分析可以清楚地看到,当前集群中所有分区的Leader信息已经全部变为0,并且ISR(In-Sync Replicas)列表也仅包含0。这表明Broker0已成为整个集群中唯一活跃且可用的节点。

  • 具体来看各个分区的情况:

    • 分区0:Leader从原来的不确定状态变为Broker0
    • 分区1:Leader同样被Broker0接管
    • 分区2:Leader也切换到了Broker0 这意味着Broker0目前承担了所有3个分区的Leader职责,负责处理这些分区的所有读写请求。
  • 关于ISR同步状态的重要变化:

    • 所有分区的ISR列表现在都只包含Broker0
    • 原先可能包含Broker1的ISR条目已被完全移除
    • 这表明只有Broker0保持着与所有分区的最新数据同步
    • 这种状态通常发生在Broker1节点完全停止服务或网络连接完全中断的情况下
  • 副本状态的实际情况:

    • 虽然副本配置(Replicas)仍显示为0,1或1,0的组合
    • 但由于Broker1已经停止运行
    • 实际上只有Broker0上的副本是真正活跃可用的
    • 这种状态可能会导致:
      • 系统丧失了副本冗余能力
      • 如果Broker0也发生故障,将导致数据不可用
      • 需要尽快恢复Broker1或添加新的节点来保证高可用性

重启节点

我们在刚才停掉的 h122 节点上,重新启动Kafka服务:

kafka-server-start.sh /opt/servers/kafka_2.12-2.7.2/config/server.properties

重新启动后,h122是Broker1,继续查看主题的分区:

kafka-topics.sh --zookeeper h121.wzk.icu:2181 --describe --topic topic_test_01

观察结果如下: 在这里插入图片描述

  • 根据对比,我们发现,Broker恢复了,但是Leader的分配并没有改变,还是出于Leader切换后的状态。
  • 分区还是3个,副本也正常,ISR也正常,但是唯独Leader这一项,会发现都是Broker0,而没有Broker1。

这种问题我们需要让Kafka自动平衡一下。

自动再平衡

脚本介绍

此时,我们需要使用Kafka自动再平衡的脚本:kafka-preferred-replica-election.sh 我们直接运行,可以看到脚本的介绍:

kafka-preferred-replica-election.sh

脚本的介绍如下图: 在这里插入图片描述

编写JSON

我们编写JSON,这样编写是因为我们开始配置的时候是: 在逗号分割的每个数值对儿中: ● 排在前面的是Leader分区 ● 后面的是副本的分区

# 这是我们希望的分区状况
--replica-assignment "0:1,1:0,0:1"

所以我们编写的JSON内容如下:

vim topic_test_01_preferred-replica.json


{
  "partitions": [
    {
      "topic": "topic_test_01",
      "partition": 0
    },
    {
      "topic": "topic_test_01",
      "partition": 1
    },
    {
      "topic": "topic_test_01",
      "partition": 2
    }
  ]
}

写入的内容如下图所示: 在这里插入图片描述

运行测试

执行如下的脚本:

kafka-preferred-replica-election.sh --zookeeper h121.wzk.icu:2181 --path-to-json-file topic_test_01_preferred-replica.json

运行后返回的结果如下: 在这里插入图片描述

查看分区

我们再次查看分区:

kafka-topics.sh --zookeeper h121.wzk.icu:2181 --describe --topic topic_test_01

执行的结果如下图所示: 在这里插入图片描述 我们可以观察到,此时的Leader中,已经重新平衡了:Leader0、Leader1、Leader0。