文章目录
cruise-control介绍
什么是cruise control
资源的动态负载均衡
- CPU
- 磁盘使用率
- 入流量
- 出流量
失败检测与自修复
- 重新分配副本到死亡broker上
- 减少副本不足的窗口
添加/撤销一个broker
特性
- 持续平衡Kafka集群的磁盘、网络和CPU利用率;
- 当broker崩溃时,自动将这台broker上的副本重新分配到其他broker上,并还原原始复制因子;
- 确定消耗集群资源最多的主题分区;
- 支持一键式集群扩展和broker下线;
- 支持异构Kafka集群和单机多broker;
为什么是cruise control——动态负载均衡的复杂性
考虑下面情况
2000 Topics 16000 partitions 32000 replicas(RF=2)
每个副本有一个清晰的负载资料
CPU (Leader > Follower) Disk utilization (Leader = Follower) Network Inbound (Leader = Follower) Network Outbound (Follower = 0)
每个指标都有多个值进行分析:流量模式各不相同;足够长的观察期
更多需要考虑的事情所有分区在不同broker之间的分布 考虑机架 一台机器挂掉之后其他机器的负载情况
进行分区的重新分配很困难
不能影响正常流量 可能需要中断
大量副本
多资源负载均衡
附加限制条件
两种均衡方法Leadership movement(cheap) Replica movement(expensive)
- 总结
使用负载均衡前,单个资源组(1000个分区)均衡计划的生成需要300+min
使用负载均衡后,单个资源组(1000个分区)均衡计划的生成需要1~2min
基本设计
负载均衡目标
机架目标(Hard Goal)
RackAwareGoal: 相同分区的副本必须在不同机架上
RackAwareDistributionGoal: 保证副本均衡分散在机架上
资源使用阈值目标CapacityGoal(Hard Goal)
一台broker的每一个资源(CPU、Disk、NetWorkIn、NetWorkOut)利用率都应该在预定义的阈值之下
**CpuCapacityGoal **
**DiskCapacityGoal **
**NetworkInboundCapacityGoal **
**NetworkOutboundCapacityGoal **
资源利用率均衡目标ResourceDistributionGoal(Soft Goal)
一台broker的每个资源的利用率与每个资源的平均利用率之间不能相差x%
Topic分区分布目标(Soft Goal)
每个topic的分区应该尽可能分布在不同broker上
CpuUsageDistributionGoal
DiskUsageDistributionGoal
NetworkInboundUsageDistributionGoal
NetworkOutboundUsageDistributionGoal
全局分区分布目标(Soft Goal)
?
每一个目标都有优先级
用一个唯一整数来代替
确定令人满意的顺序
单个目标副本列表的生成与过滤
每个目标在计算均衡计划之前会对每个broker的副本列表按照目标维度(比如cpu、disk、netIn等)进行排序/其他处理(比如过滤topic等)
CapacityGoal:
CpuCapacityGoal-REVERSE-LEADER、CpuCapacityGoal-REVERSE
DiskCapacityGoal-REVERSE-LEADER、DiskCapacityGoal-REVERSE
NetworkInboundCapacityGoal-REVERSE-LEADER、NetworkInboundCapacityGoal-REVERSE
NetworkOutboundCapacityGoal-REVERSE-LEADER、NetworkOutboundCapacityGoal-REVERSE
GroupAwareGoal: GroupAwareGoal
RackAwareGoal: RackAwareGoal
ReplicaCapacityGoal: ReplicaCapacityGoal
各个目标对应的副本迁移类型
CapacityGoal:
LEADERSHIP_MOVEMENT、INTER_BROKER_REPLICA_MOVEMENT
GroupAwareGoal:
INTER_BROKER_REPLICA_MOVEMENT
RackAwareGoal:
INTER_BROKER_REPLICA_MOVEMENT
ReplicaCapacityGoal:
INTER_BROKER_REPLICA_MOVEMENT
系统设计和架构
Cruise control架构示意图
副本负载模型
CPU利用率:从总的CPU利用率派生而来((Partition_Bytes_in / Total_Bytes_In) * CPU_UTIL)
Disk利用率:分区大小(最近的)
网络入流量:Kafka metrics
网络出流量:Kafka metrics
负载快照
代表一个定义窗口的平均负载;
对于每一个分区保存最近N个快照;
对于每个负载快照进行多次负载取样;
不可用的取样导致非法的负载快照;
根据配置可以决定指标取样的窗口的大小以及训练时所需合法取样窗口的
只采取可信的执行计划
没有足够合法的负载快照的分区 排除在外;
有分区被排除了的topic 排除在外;
停止分析如果太多的topic 被排除在外;
cruise-control源码解析
客户端-CruiseControlMetricsReporter
服务端-Monitor
// LoadMonitorTaskRunner.java
// NOT_STARTED -> RUNNING
// SamplingTask(采样任务)
// RUNNING -> SAMPLING
// SAMPLING -> RUNNING
public enum LoadMonitorTaskRunnerState {
NOT_STARTED, RUNNING, PAUSED, SAMPLING, BOOTSTRAPPING, TRAINING, LOADING
}
负载指标的生成&加载过程
源码分析示意图
cruise-control服务端对于负载指标的处理分为两部分:
- 负载指标的生成——SamplingTask任务负责(定时任务)
SamplingTask从__CruiseControlMetrics topic中获取原生负载指标(topic/cpu/disk);
通过相应的计算加工为每个partition/broker生成sample指标对象,并将其集合封装仅MetricsSampler.Samples中;
对封装好的MetricsSampler.Samples做聚合处理并写入目标topic __KafkaCruiseControlModelTrainingSamples|__KafkaCruiseControlPartitionMetricSamples
- 负载指标的获取——SampleLoadingTask任务负责
根据配置创建对应topic的消费者,并消费已经处理好的指标数据
Cruise Control使用Kafka存储和检索其指标,该指标由Metric Fetcher读取。
在负载监视器中,Metric Fetcher Manager负责协调所有采样任务:Metric采样任务,Bootstrap任务和线性模型训练任务。
每个采样任务都由配置数量的Metric Fetcher线程执行。每个Metric Fetcher线程使用一个可插入的Metric Sampler来获取样本。每个Metric Fetcher都在集群中分配了几个分区以获取样本。指标标准样本由指标标准样本聚合器组织,该指标标准聚合器根据指标标准样本的时间戳将每个指标标准样本放入工作负载快照中。
集群工作负载模型是负载监视器的主要输出。集群工作负载模型反映了集群的当前副本分配,并提供了移动分区或副本的接口。分析器使用这些接口来生成优化解决方案。
样本存储区存储指标标准和训练样本以供将来使用。
借助指标标准采样器,您可以将Cruise Control部署到各种环境并与现有的指标标准系统一起使用。
在Cloudera环境中使用Cruise Control时,将 HttpMetricsReporter 指标报告给Cloudera Manager时间序列数据库。结果,可以使用Cloudera Manager读取Kafka指标。
负载均衡过程
源码分析示意图
cruise-control服务端对于负载均衡过程的处理分为三部分:
- 指标模型加载——KafkaCruiseControl先通过LoadMonitor加载cluster model
LoadMonitor首先会分别对partition和broker指标进行聚合操作;
LoadMonitor调用MonitorUtils工具类结合指标聚合结果生成最终cluster model并返回;
- 目标优化分析——KafkaCruiseControl将得到的cluster model传递给GoalOptimizer进行优化分析
GoalOptimizer按照goals -> brokers -> replicas的层级结构逐层下探,最终在replica层面上计算当前目标下的replica均衡计划并更改clusterModel中对应分区的分布(将违背目标的replica移动到最空闲的broker上)。经历过所有goals -> brokers -> replicas的分析、clusterModel更新后,结合分析、clusterModel更新之前就保存下来的副本、leader分布,最终得到均衡计划,比如下面这样:
{
"proposal": {
"oldReplicas": [
1000005,
1000006
],
"topicPartition": {
"hash": -2051444043,
"partition": 37,
"topic": "cruise-control-test3"
},
"newReplicas": [
1000003,
1000002
],
"oldLeader": 1000005
}
}
- 目标均衡计划执行——KafkaCruiseControl将得到的均衡计划提交给线程,最终由Executor执行均衡计划
指标聚合
源码分析示意图
指标聚合简介
- 从__KafkaCruiseControlPartitionMetricSamples获取到指标,对每个窗口的若干个采样做聚合操作(累加/均值、最大值、最新值)
- 按照指标类型对聚合的指标分类,每个指标类型会有多个窗口,每个窗口的值就是上面聚合操作得来的
最终效果示意图:
附录
- 参考文章