点一下关注吧!!!非常感谢!!持续更新!!!
🚀 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集群中创建新主题时,管理员可以手动指定分区副本的分配方案,这包括:
- 明确设置每个分区的Leader副本位于哪个Broker节点
- 配置每个分区的Follower副本分布在哪些Broker节点
例如,对于一个3副本的主题,管理员可以这样规划:
- 分区0:Leader在Broker1,Follower在Broker2和Broker3
- 分区1:Leader在Broker2,Follower在Broker3和Broker1
- 分区2:Leader在Broker3,Follower在Broker1和Broker2
这种初始分配保证了Leader副本在集群中的均衡分布。
角色转换导致的不均衡问题
在系统运行过程中,以下几种情况会导致Leader分布失衡:
-
Broker故障恢复:
- 当某Broker宕机时,其上的Leader分区会自动转移到其他Broker的Follower副本
- 该Broker恢复后,并不会自动恢复原来的Leader角色
-
自动Leader选举:
- Kafka的Controller会监控Broker可用性
- 当检测到Leader不可用时,会从ISR(In-Sync Replicas)中选择新的Leader
-
滚动重启影响:
- 在集群维护期间,如果逐个重启Broker
- 每次重启都会触发Leader转移,可能导致Leader最终集中在少数节点
不均衡带来的性能问题
Leader分区过度集中会导致:
-
网络I/O瓶颈:
- 所有生产者和消费者的读写请求都集中在少数Broker
- 这些节点的网络带宽可能成为瓶颈
-
CPU资源竞争:
- Leader需要处理更多的请求编解码和磁盘I/O
- 集中导致CPU使用率不均衡
-
磁盘I/O压力:
- 虽然所有副本都要写入数据
- 但Leader需要处理更多的客户端请求
再平衡解决方案
Kafka提供了以下机制来重新均衡Leader分布:
-
自动再平衡:
- 通过
auto.leader.rebalance.enable=true启用 - Controller会定期检查Leader分布均衡性
- 当检测到不均衡时自动触发Leader切换
- 通过
-
手动触发:
kafka-leader-election --bootstrap-server <broker_list> \ --election-type PREFERRED --topic <topic_name> --all-topic-partitions -
再平衡算法:
- 计算当前集群中每个Broker的Leader比例
- 将超出平均值的Broker上的Leader转移到其他Broker
- 确保转移后各Broker的Leader数量差异在阈值内
-
最佳实践:
- 建议在业务低峰期执行再平衡
- 监控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。