💯 作者:谢先生。 2014年入行的程序猿。多年开发和架构经验。专注于Java、云原生、大数据等技术。从CRUD入行,负责过亿级流量架构的设计和落地,解决了千万级数据治理问题。
📖 微信公众号、B站:搜索「谢先生说技术」不定时更新 ~
📂 清单: goku-framework、【定期开源】享阅读II
真的是好久都没有更新了,失业难过中😫
前言
在最开始我们就说过,Kafka中存储消息数据看似在向Topic写入,但其实Topic只是逻辑上的概念,实际上数据最终都以Partition为落点。随后Broker会对Partition中的存储数据做进一步操作。与此同时Producer和Consumer都是跟Partition的Leader角色进行数据发送与消费。
顾名思义,这都是我们之前了解过的
本章我们针对Broker中的副本信息作细致介绍。本节内容包括:
- 副本基本信息
- 副本间Leader选举与故障处理
- Leader Partition自平衡处理
- 人为干预Partition分布策略
把我们零碎的知识汇总起来~
副本
副本信息
我们在创建Topic的时候,会设置对应的分区数与副本因子,为了保证整个集群的健康,默认情况下Kafka集群会将分区与副本均匀的每一个Broker节点上。
而一般情况下,Broker会将同一分区的Leader和Follower节点进行分离,这样主要为了保证:
- 为了防止当某个Broker节点出现宕机等问题,其余Follower能够快速升级。保证整个集群的高可用
- 为了提高数据的可靠性,避免由于单点故障而导致数据丢失等情况
这里需要注意的是:副本并不是说越多越好,如果副本数设置过多,会增加磁盘的存储空间,而且主从节点间的数据同步还会增加网络数据传输 这里建议:
- 建议副本数配置2,不要过多设置
故障处理
前面其实我们也提到过: 分区Leader角色承担与Producer和Consumer的读写交互,而Follower会从Leader分区中进行数据同步。 但是我们必须能够想到:
- 如果由于出现网络或者Broker节点本身出现故障,导致分区无法正常交互,进而影响到整个集群健康
为了能够尽快对外提供服务,Kafka也提供了故障处理机制。我们先从Leader故障处理来看:
Leader故障处理
当Leader发生故障之后,首先Controller控制器会从ZK中查询该分区下的所有副本的LEO,某个最大LEO所在的Broker将会被选举为Leader角色
选举原则一: 副本数据保存最全
如果存在多个副本的LEO相同,则Controller将会从ISR列表中选择一个副本所在Broker为Leader。
ISR: 同步副本队列,当前集合表示其它副本及时于Leader进行数据同步,同步数据基本赶上了Leader的数据
如果ISR中不存在集合数据,那么将选择所有副本中第一个在线的Broker作为Leader。
为了保证副本数据间的一致性,此时其它Follower需要与新的Leader进行数据同步:
- 其它Follower会先将各自的log文件中高于HW的部分截取,然后开始从新的Leader同步
Follower故障处理
接下来我们看看当Follower出现故障之后会出现的问题:
首先,Follower无法正常与Leader进行心跳且无法正常拉取数据,那么当等待replica.lag.time.max.ms
时间之后将会被提出ISR列表
等待该Follower正常恢复之后,由于Leader还在正常处理消息中,必然会出现消息同步不及时的问题。
- 此时当前Follower节点会读取本地磁盘记录的HW,并将log记录中高于HW的部分进行截取,然后从HW的位置开始从Leader进行同步
- 等待当前Follower的LEO与该Partition的HW持平,那么表示当前Follower可以重新加入到ISR集合中
Leader分区自平衡机制
自平衡是Kafka在处理分区均匀分散的一种非常重要的机制。Kafka本身会通过该机制将Partition均匀分散在每个Broker节点上。这样能够保证每个Broker节点的读写吞吐量都是平均的。
但是如果某些Broker节点故障出现宕机等问题,Controller会快速对Leader和Follwer进行故障恢复处理,此时Partition容易集中在部分Broker节点上。
- 这样就会导致部分Broker节点的读写请求压力过高
- 而当Broker节点重启恢复之后,大概率都是Follower分区,这些节点上读写请求非常低。 这样就很大程度上会造成集群负载不均衡。 现在我们来看看Kafka是如何解决这种问题的~
核心参数
为了防止出现上述问题,kafka提供三个配置项:
auto.leader.rebalance.enable
当前参数默认为true
,也就是说默认自动开启LeaderPartition平衡检测机制。
其实在生产环境我们一般推荐将参数设置为
false
如果出现频繁自平衡调整,将会导致整个集群性能严重下降
leader.imbalance.per.broker.percentage
每个Broker允许的不平衡的比率。如果broker超过了设置的值,那么Controller就会触发自动平衡进行调整
默认10% , 如果非要开启
auto.leader.rebalance.enable
, 建议将该值设置的略大一些
leader.imbalance.check.interval.seconds
一般情况下比率与间隔时间都是相辅出现的: 如果迟迟没有达到
leader.imbalance.per.broker.percentage
设置的值,那么Broker将在等待leader.imbalance.check.interval.seconds
之后检查集群是否平衡
检查每个Broker节点下Leader Partition是否平衡的间隔时间。默认为300秒
人为干预副本分配
手动调衡副本的方式其实非常简单,我们在上一节《Broker节点负载》中也介绍过执行命令,回忆回忆:
kafka-reassign-partitions.sh
操作流程如下
- 编写副本存储计划
json
{
"version": 1,
"partitions": [
{
"topic": "", // topic名称
"partition": 0/1/2/3, // 分区号
"replicas": [0,1] // 想要放的broker节点
}
]
}
- 执行当前计划
shell
kafka-reassign-partitions.sh --bootstrap-server master:9092 --reassignment-json-file jsonfile.json --execute
- 对当前执行计划进行校验
json
kafka-reassign-partitions.sh --bootstrap-server master:9092 --reassignment-json-file b.json --verify
如此这般,就能实现手动管理副本的功能。
最后
到此本节内容结束,基于概念性内容居多,希望大家多看多理解。 后面为大家介绍关于Broker中消息数据的存储与过期等内容。 期待~