Volcano 无 Selector 多调度器部署:基于 StatefulSet 与一致性哈希的吞吐量扩展方案

发布时间:2026/9/17 12:24:51

Volcano 无 Selector 多调度器部署:基于 StatefulSet 与一致性哈希的吞吐量扩展方案 Volcano 无 Selector 多调度器部署基于 StatefulSet 与一致性哈希的吞吐量扩展方案【免费下载链接】volcanoA Cloud Native Batch System (Project under CNCF)项目地址: https://gitcode.com/GitHub_Trending/vol/volcano本文档对应的设计原文位于 docs/design/deploy-multi-volcano-schedulers-without-using-selector.md全文围绕如何在不使用 Node Selector 的前提下部署多个 Volcano Scheduler 实例展开。通过 StatefulSet 编排调度器副本、利用环境变量开启多调度器模式并由一致性哈希算法自动为每个调度器分配 Job 与 Node是大型集群吞吐量扩展的轻量级实践方案。读完本文你将掌握无 Selector 多调度器的完整部署 YAML、三个关键环境变量的语义以及调度器缓存层哈希过滤的底层实现原理。背景单调度器吞吐量瓶颈与多调度器扩展在部分高吞吐场景下单个 Volcano Scheduler 实例无法满足调度吞吐需求。除了对单调度器做性能优化如 如何调优 Volcano 性能之外另一种更直接的选择是部署多个 Volcano Scheduler 副本将调度负载水平拆分从而提升整体调度吞吐量。多调度器方案的核心价值在于调度压力被多个调度器实例分担突破单实例吞吐上限各调度器实例拥有完整的调度能力gang scheduling、queue、插件体系等可以在不改造业务工作负载的前提下透明地扩展。传统方案回顾基于 Selector 的节点分区及其痛点在引入本文方案之前Volcano 支持通过selector将集群节点划分为多个分区每个 Volcano Scheduler 负责一个分区。完整的用法记录在 docs/design/multi-volcano-schedulers.md 中大致思路如下为每个调度器命名并通过--scheduler-name参数区分使用--node-selectorlabel query支持:语法如--node-selector zone:gpu,zone:cpu过滤其负责的节点分区控制器侧controller-manager需要重复声明多个--scheduler-name业务 Job 需要在spec.schedulerName中显式指定调度器名称。这种做法的优点是可以按用途隔离节点例如 GPU 区、CPU 区但缺点也很明显需要为节点打标签并维护分区关系在大规模集群下运维成本高工作负载需要显式指定schedulerName改动面大与已有业务耦合分区是静态划分的负载在分区之间无法动态均衡。下图展示了多调度器按节点分区的基本架构该图来自 multi-volcano-schedulers.md 的配套图可用于理解多调度器各管一段的整体思想新方案StatefulSet 一致性哈希无需 Selector本文的设计文档提供了一种对工作负载和节点改动更少的部署选项使用 StatefulSet 部署 Volcano SchedulerJob 与 Node 依据哈希算法自动分配给对应的调度器实例整个过程无需节点标签、无需在 Pod 中额外指定调度器分区。其核心思路是调度器以 StatefulSet 方式部署Pod 名天然形如volcano-scheduler-0、volcano-scheduler-1、volcano-scheduler-2具备稳定有序的身份通过环境变量MULTI_SCHEDULER_ENABLEtrue开启多调度器模式SCHEDULER_NUM声明调度器总数每个调度器 Pod 通过SCHEDULER_POD_NAME取自metadata.name知道我是谁各实例基于调度器总数构建一张一致性哈希环consistent hash ring对 Job或其 PodGroup 的 OwnerReference 名称和 Node 名称做哈希取模命中哪个实例就由哪个实例负责调度。这样业务工作负载只需按默认方式提交调度器之间自动完成负载切分。完整部署步骤1. 准备 Volcano Scheduler 的 StatefulSet YAML下面是设计文档给出的可直接参考的部署示例kind: StatefulSet apiVersion: apps/v1 metadata: name: volcano-scheduler namespace: volcano-system labels: app: volcano-scheduler spec: replicas: 3 selector: matchLabels: app: volcano-scheduler serviceName: volcano-scheduler template: metadata: labels: app: volcano-scheduler spec: serviceAccount: volcano-scheduler containers: - name: volcano-scheduler image: volcanosh/vc-scheduler:ae78900d21dce8522eb04b6817aac66c9abd01e2 args: - --logtostderr - --scheduler-conf/volcano.scheduler/volcano-scheduler.conf - -v3 - 21 imagePullPolicy: IfNotPresent env: - name: MULTI_SCHEDULER_ENABLE value: true - name: SCHEDULER_NUM value: 3 - name: SCHEDULER_POD_NAME valueFrom: fieldRef: fieldPath: metadata.name volumeMounts: - name: scheduler-config mountPath: /volcano.scheduler volumes: - name: scheduler-config configMap: name: volcano-scheduler-configmap --- apiVersion: v1 kind: Service metadata: name: volcano-scheduler labels: app: volcano-scheduler spec: ports: - port: 80 name: volcano-scheduler clusterIP: None selector: app: volcano-scheduler要点说明StatefulSet 而非 DeploymentStatefulSet 保证每个副本拥有稳定的网络标识与稳定有序的 Pod 名称volcano-scheduler-0/1/2...这是哈希分配得以成立的前提headless ServiceclusterIP: None的 Service 配合serviceName: volcano-scheduler为每个 Pod 提供稳定的 DNS 名称环境变量注入三个环境变量详见下文共同驱动多调度器模式其中image为示例镜像 tag实际部署时应替换为当前发行版本的 vc-scheduler 镜像。2. 应用 StatefulSetkubectl apply -f volcano-statefulset.yaml其中volcano-statefulset.yaml为第 1 步准备好的清单文件路径。应用后即会启动replicas个调度器副本并各自进入多调度器模式工作。3. 三个关键环境变量环境变量取值作用MULTI_SCHEDULER_ENABLEtrue/ 其他是否开启多调度器模式。设为true时调度器才会读取SCHEDULER_NUM并构建哈希环未开启时行为与单调度器一致SCHEDULER_NUM正整数如3计划启动的 Volcano Scheduler 总数必须与实际 StatefulSetreplicas保持一致SCHEDULER_POD_NAME通过fieldRef: metadata.name自动注入当前调度器 Pod 的名称用于哈希环上确定我负责哪些 key源码级原理哈希环与责任过滤无 Selector 多调度器的实现落在调度器缓存层相关代码集中在 pkg/scheduler/cache/util.go 与 pkg/scheduler/cache/cache.go使用了stathat.com/c/consistent一致性哈希库。构建哈希环getMultiSchedulerInfo在 cache.go 中调度器初始化时调用getMultiSchedulerInfo()获取自己的 Pod 名与哈希环sc.schedulerPodName, sc.c getMultiSchedulerInfo()其实现util.go逻辑为读取MULTI_SCHEDULER_ENABLE非true时直接返回不启用哈希环c nil读取SCHEDULER_NUM并转成整数解析失败时回退为1由SCHEDULER_POD_NAME截取最后一个-之前的部分得到baseName例如volcano-scheduler-2→volcano-scheduler依次生成baseName-0至baseName-(N-1)共 N 个名称加入一致性哈希环consistent.New()。也就是说每个调度器 Pod 都会构建一张包含全部调度器名称的哈希环只是各自在环上的位置不同。责任判定responsibleForPod / responsibleForNode / responsibleForPodGrouputil.go 定义了三个责任判定函数语义如下responsibleForPod(pod, schedulerNames, mySchedulerPodName, c)先判断 Pod 的spec.schedulerName是否在当前调度器维护的schedulerNames集合中不在则直接返回false哈希环启用时取 Pod 的OwnerReferences[0].Name即所属工作负载名通常为 Job 名作为 key若无 OwnerReference 则退回使用pod.Name通过c.Get(key)得到负责的调度器名与mySchedulerPodName不一致则返回falseresponsibleForNode(nodeName, mySchedulerPodName, c)以节点名作为 key 哈希判断当前调度器是否负责该节点responsibleForPodGroup(pg, mySchedulerPodName, c)以 PodGroup 的 OwnerReference 名称无则用 PodGroup 名作为 key 哈希判断当前调度器是否负责该 PodGroup。接入点Informer 的 FilteringResourceEventHandler在 cache.go 中Pod informer 使用cache.FilteringResourceEventHandler作为过滤入口FilterFunc: func(obj interface{}) bool { switch v : obj.(type) { case *v1.Pod: if !responsibleForPod(v, sc.schedulerNames, sc.schedulerPodName, sc.c) { if len(v.Spec.NodeName) 0 { return false } if !responsibleForNode(v.Spec.NodeName, sc.schedulerPodName, sc.c) { return false } } return true ...即未绑定节点的 Pod 必须通过responsibleForPod才进入本地缓存已绑定节点的 Pod如已调度 Pod 的状态更新则再经responsibleForNode过滤。PodGroup informer 的 FilterFunc 同样调用了responsibleForPodGroupcache.go。由此可以总结出该方案的关键机制每个调度器只在自己的 informer 缓存中保留属于自己的 Pod / PodGroup / Node从而天然实现调度域的水平切分互不干扰归属关系由一致性哈希决定新增或下线调度器副本时只有少量 key 需要迁移优于简单取模无需节点标签、无需业务侧指定调度器这是与 Selector 方案的本质区别。使用注意与适用边界基于设计文档与源码实现使用该方案时需注意SCHEDULER_NUM必须与 StatefulSetreplicas一致否则哈希环上的实例数与实际副本数不匹配会导致部分负载无人认领或重复认领Pod 名称的稳定有序是前提因此必须使用 StatefulSet而非 Deployment且SCHEDULER_POD_NAME需通过fieldRef: metadata.name注入该方案面向水平扩展吞吐量的诉求若业务诉求是按用途物理隔离节点分区如 GPU 专用区则应参考 docs/design/multi-volcano-schedulers.md 的 Selector 方案涉及多个调度器共享同一集群时请确认控制器侧--scheduler-name配置能覆盖这些调度器名称确保 Job 的 PodGroup 能正确生成并被对应调度器认领镜像 tag 为示例值生产环境请以当前仓库发行版为准调度器配置--scheduler-conf由volcano-scheduler-configmap挂载可按需调整插件与 action 配置。综上StatefulSet 一致性哈希的无 Selector 多调度器方案为大型集群的调度吞吐扩展提供了一条改动小、自动化程度高的路径其哈希环自动分配、informer 过滤隔离的实现思路也值得在调度类系统设计中借鉴。【免费下载链接】volcanoA Cloud Native Batch System (Project under CNCF)项目地址: https://gitcode.com/GitHub_Trending/vol/volcano创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/9/17 12:24:51

Jetpack - Paging

一、概念 相对于传统的下拉刷新上拉加载,只需要告诉Paging如何加载数据,不用再监听滑动事件操作何时加载下一页。PagingSource用于定义数据的来源和加载方式。开发者需要实现 PagingSource 抽象类,并在其中指定如何从数据源中加载特定页的数据…

2026/9/17 14:30:00

LangChain4j 0.31.0 Java 8 兼容实践与 Spring Boot 2.3 集成指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/17 14:30:00

用 Rerun 的 3D 原语构建实时模拟时钟:Rust 示例逐行拆解

用 Rerun 的 3D 原语构建实时模拟时钟:Rust 示例逐行拆解 【免费下载链接】rerun Visualize, query, and stream to train on multimodal robotics data. 项目地址: https://gitcode.com/GitHub_Trending/re/rerun 本篇技术指南以 examples/rust/clock 示例为…

2026/9/17 14:30:00

MySQL 8.0备份实战:XtraBackup 8.0安装与恢复全指南

我见过很多DBA和运维朋友,一备份MySQL就下意识敲mysqldump,等数据量上了500GB,备份时间从半小时变成五六个小时,恢复更是遥遥无期,这时候才开始着急找方案。其实在MySQL 8.0时代,最该优先考虑的备份工具就是…

2026/9/17 14:30:00

通信交换技术本质:电路、报文与分组的工程抉择

1. 这不是教科书里的概念图,而是我亲手画了7版才搞懂的通信底层逻辑“图解数据交换技术——电路交换、报文交换、分组交换”,光看标题,很多人第一反应是:又来背网络层协议了?课本上那三张并排的示意图,箭头…

2026/9/17 14:30:00

球体导热理论与工程实践:从控制方程到数值求解

1. 球体导热问题概述球体导热是工程传热学中的经典问题,在核反应堆燃料球、相变储热材料、化工催化剂颗粒等领域具有广泛应用。与平板和圆柱体导热不同,球体导热具有独特的几何特性——温度场仅沿径向变化,这使得三维问题可以简化为仅与半径相…

2026/9/16 12:52:37

拯救者Y7000黑屏故障排查与维修实战指南

1. 项目概述:一台黑屏的拯救者Y7000,到底卡在哪一步? 联想拯救者Y7000系列笔记本,从2018年第一代搭载i5-8300H开始,到后来的i7-9750H、i7-10750H、i5-11400H,再到2023年款的R7-7840HS,它始终是学…

2026/9/17 0:03:13

WiFi密码安全测试:从原理到实战的字典暴力破解指南

1. 写在前面:我为什么要研究WiFi密码这件事先交代一下背景。我身边有不少朋友,家里的WiFi密码常年是"12345678"或者"88888888",问就是"好记"。直到有一次,隔壁邻居蹭网蹭到我家路由器后台都进不去&…

2026/9/17 0:03:13

redis-py服务控制与监控函数实战:从ping到slowlog的巡检指南

我用 redis-py 写了快五年的业务代码,坦白说,真正让我觉得这个客户端“像一个成熟工具箱”的,不是 get/set 那套基本操作,而是它那批专门做服务控制与状态监控的辅助函数。日常开发里,大家把redis.Redis(host..., deco…

2026/9/17 0:03:13

SpringBoot+Vue3实现中小企业设备管理系统开发实践

1. 项目概述与核心价值中小企业设备管理系统是制造业、服务业等领域的基础信息化工具。传统设备管理往往依赖Excel表格或纸质记录,存在数据孤岛、流程混乱、维护成本高等痛点。这套基于Java SpringBootVue3MyBatis的技术方案,通过前后端分离架构实现了设…

2026/9/16 22:55:57

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/16 22:56:09

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/16 22:56:16

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码