十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Apache DolphinScheduler Worker 负载均衡算法深度解析:从随机分配到动态平滑加权轮询

Apache DolphinScheduler Worker 负载均衡算法深度解析:从随机分配到动态平滑加权轮询 Apache DolphinScheduler Worker 负载均衡算法深度解析从随机分配到动态平滑加权轮询【免费下载链接】dolphinschedulerApache DolphinScheduler is the modern data orchestration platform. Agile to create high performance workflow with low-code项目地址: https://gitcode.com/GitHub_Trending/dol/dolphinscheduler导读本文聚焦 Apache DolphinScheduler 中 Master 将任务分发给 Worker 的核心机制——Worker 负载均衡。你将完整掌握四种内置负载均衡算法随机、轮询、平滑加权轮询、动态平滑加权轮询的原理、适用场景与配置方式并借助仓库源码理解平滑加权轮询的选点过程与动态权重的计算公式从而在生产集群中依据 Worker 的 CPU、内存与线程池负载状况做出最合理的调度决策。为什么需要 Worker 负载均衡在 DolphinScheduler 的多 Worker 集群环境中Master 负责将流程实例中的任务下发给注册到集群中的 Worker 执行。当同一 Worker 分组下存在多台 Worker 节点时任务如何分配直接决定了集群的整体吞吐与单机压力。负载均衡Load Balancing正是通过合理的路由算法典型应用于集群环境将服务端压力进行合理分散从而最大限度地优化服务器性能。从源码结构看这一职责由dolphinscheduler-master模块下org.apache.dolphinscheduler.server.master.cluster.loadbalancer包中的一组类承担统一的IWorkerLoadBalancer接口定义了按 Worker 分组选择 Worker 地址的select(workerGroup)方法四种算法分别实现了该接口。四种负载均衡算法总览DolphinScheduler-Master 提供了四种用于将任务分发到 Worker 的负载均衡算法对应枚举 WorkerLoadBalancerType算法枚举值特点默认启用随机RANDOM从可用 Worker 中随机挑选一个执行任务否轮询ROUND_ROBIN按固定顺序循环选择 Worker保证各节点任务量均匀否平滑加权轮询FIXED_WEIGHTED_ROUND_ROBIN基于管理员配置的固定权重平滑调度兼顾权重与均匀性否动态平滑加权轮询DYNAMIC_WEIGHTED_ROUND_ROBIN依据 Worker 实时负载动态计算权重后平滑调度是其中DYNAMIC_WEIGHTED_ROUND_ROBIN为默认算法。默认值在 dolphinscheduler-master 的 application.yaml 中通过type: DYNAMIC_WEIGHTED_ROUND_ROBIN显式指定需要说明的是配置类WorkerLoadBalancerConfigurationProperties中字段的代码默认值为ROUND_ROBIN因此实际生效算法以配置文件中的显式配置为准。负载均衡算法配置负载均衡算法在 Master 节点的配置文件中进行设置。原文档给出的路径为master-server/conf/application.yaml在当前仓库中对应的真实文件为 dolphinscheduler-master/src/main/resources/application.yaml配置片段如下master: worker-load-balancer-configuration-properties: # types: RANDOM, ROUND_ROBIN, FIXED_WEIGHTED_ROUND_ROBIN, DYNAMIC_WEIGHTED_ROUND_ROBIN type: DYNAMIC_WEIGHTED_ROUND_ROBIN # dynamic-weight-config-properties only used in DYNAMIC_WEIGHTED_ROUND_ROBIN, # the weight of memory-usage, cpu-usage, task-thread-pool-usage should sum to 100. dynamic-weight-config-properties: memory-usage-weight: 30 cpu-usage-weight: 30 task-thread-pool-usage-weight: 40关键点说明type字段取值必须严格匹配枚举RANDOM、ROUND_ROBIN、FIXED_WEIGHTED_ROUND_ROBIN、DYNAMIC_WEIGHTED_ROUND_ROBIN大小写敏感dynamic-weight-config-properties仅在DYNAMIC_WEIGHTED_ROUND_ROBIN算法下生效该配置由 Spring Boot 绑定到MasterConfig中的WorkerLoadBalancerConfigurationProperties对象并在运行时读取。从实现上看WorkerLoadBalancerConfiguration 是一个 Spring 配置类它根据配置的type在启动时创建对应的负载均衡器 BeanRANDOM创建RandomWorkerLoadBalancerROUND_ROBIN创建RoundRobinWorkerLoadBalancerFIXED_WEIGHTED_ROUND_ROBIN创建FixedWeightedRoundRobinWorkerLoadBalancerDYNAMIC_WEIGHTED_ROUND_ROBIN则创建携带动态权重配置的DynamicWeightedRoundRobinWorkerLoadBalancer若配置了无法识别的类型会抛出IllegalArgumentException(unSupport worker load balancer type ...)。Worker 权重配置固定权重配置FIXED_WEIGHTED_ROUND_ROBIN使用FIXED_WEIGHTED_ROUND_ROBIN算法时管理员可以在每台 Worker 节点自己的配置文件中修改固定权重。原文档给出的路径为worker-server/conf/application.yaml仓库中的真实文件为 dolphinscheduler-worker/src/main/resources/application.yaml配置如下worker: host-weight: 100 # default value is 100该配置的含义与约束host-weight是当前 Worker 节点在固定加权轮询中对外宣告的权重值默认值为100权重越大被分配到的任务占比越高。例如三台 Worker 权重分别配置为 100、200、300则其任务分配比例约为 1:2:3权重值最终通过 Worker 心跳上报给 Master 集群。在 WorkerServerMetadata 中心跳数据workerHostWeight被解析为workerWeight字段源码注释明确标注该字段仅在FixedWeightedRoundRobinWorkerLoadBalancer中使用权重相等如都为默认 100时固定加权轮询退化为等权重的平滑轮询各节点任务量基本均匀。动态权重配置DYNAMIC_WEIGHTED_ROUND_ROBIN使用DYNAMIC_WEIGHTED_ROUND_ROBIN算法时无需也不能在 Worker 端配置权重而是在 Master 端配置三项指标各自的权重占比master: worker-load-balancer-configuration-properties: type: DYNAMIC_WEIGHTED_ROUND_ROBIN # Dynamic weight configuration, only used for DYNAMIC_WEIGHTED_ROUND_ROBIN algorithm # The sum of memory-usage, cpu-usage, task-thread-pool-usage weights must be 100 dynamic-weight-config-properties: memory-usage-weight: 30 # Memory usage weight cpu-usage-weight: 30 # CPU usage weight task-thread-pool-usage-weight: 40 # Task thread pool usage weight三个权重项的约束在 WorkerLoadBalancerConfigurationProperties 的校验逻辑中强制保证cpuUsageWeight、memoryUsageWeight、taskThreadPoolUsageWeight三者均必须 0三者之和必须恰好等于 100否则启动校验会报错cpuUsageWeight memoryUsageWeight threadUsageWeight must be 100代码默认值分别为 30、30、40与仓库配置文件中给出的示例一致。四种算法原理详解RandomRANDOM随机算法从当前 Worker 分组内所有正常可用的 Worker 节点中随机选择一个来执行任务。它的优点是实现简单、无状态适合对任务分布要求不高、各节点性能接近的场景缺点是任务分配比例完全随机无法按节点性能差异进行倾斜也无法感知节点负载变化。对应实现类为RandomWorkerLoadBalancer。Round RobinROUND_ROBIN轮询算法按照固定顺序在 Worker 节点间循环选择确保每个 Worker 获得大致相同的任务数量。对应实现类 RoundRobinWorkerLoadBalancer 的核心逻辑非常简洁持有一个原子自增索引robinIndex每次选择时执行workerServerAddresses.get(robinIndex.getAndIncrement() % workerServerAddresses.size())即按地址列表长度取模轮转。该算法的优点是各节点任务数量绝对均匀缺点是完全不考虑节点权重与实时负载一旦集群中节点性能存在差异或负载不均衡容易造成强节点空闲、弱节点过载的情况。Smooth Round RobinFIXED_WEIGHTED_ROUND_ROBIN平滑加权轮询平滑加权轮询在纯轮询的基础上引入了权重目标是既按权重比例分配任务又避免权重大的节点被连续命中导致的瞬时过载。其核心机制见 FixedWeightedRoundRobinWorkerLoadBalancer如下每台 Worker 拥有两个权重weight固定权重来源于host-weight配置注册进集群后保持不变和current_weight当前权重动态变化每次路由时遍历所有 Worker将每台的current_weight累加上其weight同时累加所有 Worker 的weight得到total_weight选出current_weight最大的 Worker 执行任务选中的 Worker 将其current_weight减去total_weight。原文档给出了一个经典示例3 台 WorkerA、B、C的权重分别为 1、2、3则选择顺序为C B C A B C C B C A B C C B C A B C C B C A B C C B C A B C ...在该 30 轮调度示例中各 Worker 获得的任务数为C:15、B:10、A:5恰好等于权重比例 3:2:1。这一结论在仓库测试 FixedWeightedRoundRobinWorkerLoadBalancerTest 中得到验证该测试循环选择 10000 次断言三台权重比为 1:2:3 的 Worker 被选中次数之比同样约为 1:2:3允许 10 次以内的误差且总次数恒等于 10000。需要注意两个实现细节当某个 Worker 分组下没有任何正常可用的 Worker时select返回Optional.empty()调用方会走无可用 Worker的处理分支该算法对集群节点的新增/移除事件做出响应onServerAdded时按权重登记、onServerRemove时移除但忽略更新事件因为固定权重不会随 Worker 运行状态变化。Dynamic Smooth Round RobinDYNAMIC_WEIGHTED_ROUND_ROBIN动态平滑加权轮询—— 默认算法动态平滑加权轮询是 DolphinScheduler 默认采用的负载均衡算法。与固定权重版本不同Worker 的权重不再由管理员静态指定而是由 Worker 自身定期向注册中心上报负载信息Master 依据这些信息动态计算权重。评价指标与默认权重如下Memory Usage内存使用率默认权重 30%CPU UsageCPU 使用率默认权重 30%Task Thread Pool Usage任务线程池使用率默认权重 40%。权重计算公式对应 DynamicWeightedRoundRobinWorkerLoadBalancer 中的calculateWeight实现Weight 100 - (CPU Weight × CPU Usage Memory Weight × Memory Usage Thread Pool Weight × Thread Pool Usage) ÷ 3从公式可以直观看出Worker 负载越低计算出的权重越高系统在选点时会优先选择负载较低的 Worker 节点执行任务从而实现真正的动态负载均衡。对应源码片段摘自DynamicWeightedRoundRobinWorkerLoadBalancer内部监听器private double calculateWeight(WorkerServerMetadata server) { return 100 - (dynamicWeightConfigProperties.getCpuUsageWeight() * server.getCpuUsage() dynamicWeightConfigProperties.getMemoryUsageWeight() * server.getMemoryUsage() dynamicWeightConfigProperties.getTaskThreadPoolUsageWeight() * server.getTaskThreadPoolUsage()) / 3; }动态权重的数据来源Worker 心跳中携带 CPU 使用率、内存使用率、线程池使用率等信息Master 侧通过 WorkerServerMetadata.parseFromHeartBeat 将心跳解析为集群元数据其中taskThreadPoolUsage即对应线程池使用率。Master 注册了集群变更监听器在 Worker 心跳更新onServerUpdate时用最新负载重新计算动态权重并写入权重表。最终选点过程动态平滑加权轮询在最终选点阶段与固定平滑加权轮询完全一致——遍历节点累加current_weight、比较total_weight、选中后扣减total_weight——唯一区别在于前者的weight随 Worker 负载实时变化对应select方法中的while循环选点逻辑。源码级选点流程小结综合源码可以梳理出 Master 分发任务时的完整链路Master 启动时WorkerLoadBalancerConfiguration 依据master.worker-load-balancer-configuration-properties.type装配对应的负载均衡器 Bean负载均衡器持有WorkerClustersWorker 集群状态并注册集群变更监听器维护各自的权重表固定权重或动态权重调度线程按 Worker 分组调用select(workerGroup)从该分组**正常可用Normal**的 Worker 地址中按算法选出一个返回地址或Optional.empty()若动态算法下某 Worker 心跳超时或节点移除监听器会将其从权重表中剔除后续不再参与选点。测试方面仓库为四种算法均提供了单元测试如 RandomWorkerLoadBalancerTest、RoundRobinWorkerLoadBalancerTest、FixedWeightedRoundRobinWorkerLoadBalancerTest与 DynamicWeightedRoundRobinWorkerLoadBalancerTest可作为理解各算法行为的参考。选型建议场景推荐算法集群各 Worker 配置均衡、任务类型简单追求实现最简单RANDOM或ROUND_ROBINWorker 节点性能存在差异希望通过静态配置控制任务倾斜比例FIXED_WEIGHTED_ROUND_ROBIN配合每台 Worker 的host-weightWorker 负载波动大希望系统依据 CPU、内存、线程池实时负载自动调度DYNAMIC_WEIGHTED_ROUND_ROBIN默认推荐总结DolphinScheduler 通过 Master 侧可插拔的负载均衡器架构为多 Worker 集群的任务分发提供了从简单随机到感知实时负载的动态平滑加权轮询的完整算法谱系。默认的DYNAMIC_WEIGHTED_ROUND_ROBIN算法以 CPU、内存、线程池使用率三项指标默认权重 30:30:40和必须为 100动态计算 Worker 权重并结合平滑加权轮询的选点机制在保证权重比正确的前提下避免了热点节点的连续过载是生产环境中最值得优先使用的配置。【免费下载链接】dolphinschedulerApache DolphinScheduler is the modern data orchestration platform. Agile to create high performance workflow with low-code项目地址: https://gitcode.com/GitHub_Trending/dol/dolphinscheduler创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表