计算与调度层详细设计方案(L4 层)
计算与调度层详细设计方案(L4 层)
本章节在总体方案的基础上,专门针对 计算与调度层(L4) 给出详细设计,重点说明 CPU/GPU 混合集群架构、作业队列与统一调度、弹性伸缩与成本优化、可观测性与运维闭环,以说明和图示为主,尽量减少代码细节。
1. 角色定位与设计目标
层级定位:
- 上承:数据湖(L2)、元数据与治理层(L3)提供的数据与元信息。
- 下接:模型训练与服务层(L5)的训练作业与推理任务。
- 对外:为 Notebook、工作流编排、自动化系统等提供统一算力资源池和作业运行环境。
核心目标:
- 统一调度:CPU、GPU、Spot 等多种资源在同一调度平面下统一编排。
- 多工作负载并存:流式 ETL、批处理、特征工程、训练、推理离线评估等共存且互不干扰。
- 高利用率 & 低成本:通过智能队列、Spot 优先、自动扩缩容等手段提升利用率、降低 TCO。
- 可观测 & 可治理:作业级、队列级、团队级的可观测与配额治理能力。
2. 计算与调度层整体架构
2.1 逻辑架构视图
graph TB
subgraph Top["上层系统"]
U1[Notebook / IDE]
U2[工作流编排<br/>Airflow / 自研 Scheduler]
U3[自动化系统<br/>如数据引擎]
end
subgraph API["作业与资源 API 层"]
JAPI[Job 提交与管理 API]
RAPI[资源与队列配置 API]
end
subgraph SCHED["统一调度与队列"]
Q[多级作业队列<br/>交互 / 训练 / ETL / 批处理]
P[优先级 & 配额管理]
C[成本感知调度器<br/>Spot 优先 / OnDemand 回退]
T[拓扑感知调度器<br/>数据本地性 / GPU 类型]
end
subgraph POOLS["计算资源池"]
CPU[CPU Pool<br/>Spark / Flink 等]
GPU_STD[GPU Pool - 标准<br/>T4 / A10]
GPU_HI[GPU Pool - 高性能<br/>A100 集群]
SPOT[Spot Pool<br/>CPU + GPU Spot]
end
subgraph K8S["托管 Kubernetes 集群"]
OP1[Spark Operator]
OP2[Ray Operator]
OP3[Training Operator<br/>PyTorchJob / MPIJob]
OP4[Notebook Operator / JupyterHub]
end
Top --> JAPI
Top --> RAPI
JAPI --> Q
RAPI --> P
Q --> C
C --> T
T --> K8S
K8S --> CPU
K8S --> GPU_STD
K8S --> GPU_HI
K8S --> SPOT
说明:
- 所有作业统一通过
JAPI提交,调度逻辑对上层产品(Notebook、工作流)透明。 SCHED模块负责把“作业意图”翻译成“资源需求”,并结合队列策略、配额策略和成本策略做决策。- K8s 作为底层资源管理与编排平面,通过各类 Operator 将 Spark、Ray、分布式训练等映射为原生 K8s 工作负载。
2.2 工作负载类型与映射
flowchart LR
subgraph Workload["工作负载类型"]
W1[ETL 批处理<br/>Spark Job]
W2[流式处理<br/>Flink / Spark Streaming]
W3[特征工程<br/>Spark / Ray Data]
W4[模型训练<br/>PyTorch DDP]
W5[超参搜索<br/>Ray Tune / Optuna]
W6[Notebook Session]
end
subgraph Mapping["到 K8s 的映射"]
M1[SparkApplication CRD]
M2[FlinkDeployment / Job CRD]
M3[RayCluster CRD]
M4[PyTorchJob / MPIJob CRD]
M5[RayCluster + Trial Pod]
M6[Notebook Pod / JupyterHub]
end
W1 --> M1
W2 --> M2
W3 --> M1
W3 --> M3
W4 --> M4
W5 --> M5
W6 --> M6
设计要点:
- 统一的 CRD(自定义资源)体系使得所有作业都能通过 K8s 原语进行生命周期管理。
- 每类工作负载都有专门的 Operator 管理,调度器只需对“资源请求 + 约束条件”做决策。
3. 资源池与节点形态设计
3.1 多资源池架构
graph TB
subgraph POOL_CPU["CPU Pool - 通用计算"]
C1[c5/c6i 系列节点<br/>16-48 vCPU]
end
subgraph POOL_GPU_STD["GPU Pool - 标准"]
G1[g4dn/g5 节点<br/>1-4 张 T4/A10]
end
subgraph POOL_GPU_HI["GPU Pool - 高性能"]
GH1[p4d/p4de 节点<br/>8x A100 80GB]
end
subgraph POOL_SPOT["Spot Pool - 成本优化"]
S1[Spot CPU 实例]
S2[Spot GPU 实例]
end
各资源池职责:
- CPU Pool:ETL、数据清洗、特征工程前处理、统计分析等。
- GPU 标准 Pool:中小规模训练、图像/点云预处理、批量推理。
- GPU 高性能 Pool:大模型或超大 batch 的分布式训练。
- Spot Pool:对中断容忍的作业(如可重启 ETL、带 checkpoint 的长训)优先使用。
3.2 资源池与作业类型的绑定策略
flowchart TD
Job[作业提交] --> Analyze{分析作业类型<br/>和资源需求}
Analyze -->|ETL/统计| CPU_ONLY[绑定 CPU Pool]
Analyze -->|特征工程| HYBRID[CPU + GPU]
Analyze -->|训练/调参| GPU_JOB[绑定 GPU Pool]
HYBRID --> GPU_STD_OR_SPOT[优先 GPU 标准 Pool<br/>可选 Spot GPU]
GPU_JOB --> VRAM{显存需求?}
VRAM -->|≤ 24GB| GPU_STD[标准 GPU 节点]
VRAM -->|> 24GB| GPU_HI[A100 高性能节点]
策略要点:
- 以 作业类型 + 显存估算结果 为主,自动给出资源池推荐,用户可在 UI 中少量覆盖。
- 对轻量训练或调参任务优先使用标准 GPU / Spot GPU,重训或核心模型才上 A100。
4. 作业队列与统一调度
4.1 多级队列模型
flowchart TB
subgraph Users["用户与系统"]
U1[Notebook 用户]
U2[训练作业提交者]
U3[数据工程自动任务]
end
subgraph Queues["多级队列"]
Q1[交互队列<br/>Priority: 1000<br/>短时 GPU/CPU]
Q2[训练队列<br/>Priority: 500<br/>中长训]
Q3[ETL 队列<br/>Priority: 300]
Q4[批处理队列<br/>Priority: 100]
end
subgraph Scheduler["统一调度器"]
S1[优先级排序]
S2[配额与公平性]
S3[成本感知决策]
S4[拓扑/数据本地性]
end
Users --> Q1
Users --> Q2
Users --> Q3
Users --> Q4
Q1 --> S1
Q2 --> S1
Q3 --> S1
Q4 --> S1
S1 --> S2
S2 --> S3
S3 --> S4
说明:
- 交互队列:确保 Notebook/小实验低延迟,通常不可被抢占,资源上限较小。
- 训练队列:中高优先级,可抢占低优先级批处理作业。
- ETL 队列:以吞吐和成本为主,优先跑在 CPU Pool + Spot。
- 批处理队列:最低优先,适合夜间/闲时跑的长任务。
4.2 提交流程与调度路径
sequenceDiagram
participant User as 用户/上层系统
participant JAPI as Job API
participant Queue as 队列管理器
participant Sched as 统一调度器
participant K8s as Kubernetes
participant Operator as 对应 Operator
User->>JAPI: 提交作业请求<br/>(JobSpec + 资源需求)
JAPI->>Queue: 根据 JobSpec 选择队列
Queue->>Sched: 入队并等待调度
loop 调度周期
Sched->>Queue: 拉取可调度作业
Sched->>Sched: 检查配额 / 优先级 / 成本策略
Sched->>K8s: 创建对应 CRD(如 SparkApplication)
K8s->>Operator: Operator 监听并创建 Pod
end
要点:
- JobSpec 中包括:作业类型、资源请求、优先级 hint、是否可使用 Spot、是否可被抢占等。
- 队列与调度器之间采用拉取+批调度方式,以降低频繁调度开销。
5. 调度策略:优先级、配额、成本与拓扑
5.1 优先级与抢占
sequenceDiagram
participant High as 高优先级训练作业
participant Low as 低优先级批处理作业
participant Sched as 调度器
participant GPU as GPU 资源
Low->>GPU: 正在运行(占用 4x GPU)
High->>Sched: 需要 4x GPU 的训练作业
Sched->>Sched: 发现资源不足
Sched->>Low: 发送抢占通知
Low->>Low: 保存 Checkpoint
Low->>GPU: 释放资源
GPU->>Sched: 资源可用
Sched->>High: 分配 GPU
High->>GPU: 开始训练
Low->>Sched: 重新入队等待
策略说明:
- 仅允许抢占 可容错、允许中断 的低优先级作业(配置级区分)。
- 抢占前调度器会检查作业的最近 Checkpoint 时间和剩余预算,避免频繁中断浪费成本。
5.2 分层配额管理
graph TD
Org[组织总配额<br/>100 GPU / 500 vCPU]
Team1[感知团队<br/>40 GPU / 200 vCPU]
Team2[规划团队<br/>40 GPU / 200 vCPU]
Team3[控制团队<br/>20 GPU / 100 vCPU]
Proj1[自动驾驶项目<br/>25 GPU]
Proj2[目标检测项目<br/>15 GPU]
Proj3[路径规划项目<br/>30 GPU]
Org --> Team1
Org --> Team2
Org --> Team3
Team1 --> Proj1
Team1 --> Proj2
Team2 --> Proj3
配额要点:
- 支持 组织 → 团队 → 项目 → 用户 的多层配额,下层配额不可突破上层硬上限。
- 引入 软配额/借用机制:未使用配额可被其他团队暂用,但在突发需求时可被回收。
5.3 成本感知调度
flowchart TD
Job[作业提交] --> Check{可容错?<br/>可接受中断?}
Check -->|是| SpotCheck{当前 Spot 价格<br/>与可用性}
Check -->|否| OD[直接使用按需实例]
SpotCheck -->|便宜且充足| SpotAlloc[分配 Spot 资源]
SpotCheck -->|价格高或紧张| Wait{预计等待时间}
Wait -->|< 15 分钟| QueueWait[继续排队等 Spot]
Wait -->|≥ 15 分钟| Fallback[回退按需实例<br/>避免 SLA 超时]
策略说明:
- 为每类作业配置 成本上限/预算区间,调度时综合考虑单小时成本和总时长。
- 对 探索性训练 强调成本最优,对 关键生产训练 强调时效和可靠性。
5.4 拓扑感知与数据本地性
graph TB
subgraph AZ1["可用区 A"]
Cache1[Alluxio 缓存<br/>Dataset v1.2]
GPU1[GPU 节点组]
end
subgraph AZ2["可用区 B"]
Cache2[Alluxio 缓存<br/>Dataset v1.1]
GPU2[GPU 节点组]
end
Job[需要 Dataset v1.2 的训练作业]
Sched{拓扑感知调度}
Job --> Sched
Sched -->|优选| AZ1
Sched -.->|备选| AZ2
设计要点:
- 元数据中记录每个数据集版本在各可用区本地缓存命中情况及容量。
- 调度器优先将作业派发到 数据就近、有缓存 的节点组,减少跨区访问 S3 的成本与延迟。
5.5 调度算法设计细节
本节在前面策略描述的基础上,从算法视角给出更细粒度的调度逻辑说明,方便后续实现与优化。
5.5.1 调度周期与多阶段决策
flowchart TD
Tick[调度周期触发<br/>例如每 2 秒一次] --> Stage1[阶段1:候选作业筛选]
Stage1 --> Stage2[阶段2:排序与分组]
Stage2 --> Stage3[阶段3:资源匹配与放置]
Stage3 --> Stage4[阶段4:抢占与回退]
Stage4 --> End[输出调度结果<br/>生成 K8s 对象]
阶段 1:候选作业筛选
- 过滤掉:已被取消、已超时、Quota 不足、预算耗尽等作业。
- 基于队列优先级和限速策略选择每轮可参与排序的候选集合(例如最多 100 个)。
阶段 2:排序与分组
- 使用综合评分函数
Score(job)排序:
[ Score = w_p \cdot Priority + w_w \cdot f(\text{等待时间}) + w_f \cdot FairSharePenalty ]Priority:队列/作业的基础优先级。等待时间:等待越久,得分越高,避免“饿死”。FairSharePenalty:已过度使用资源的团队/项目会被打分惩罚。
- 对需要 Gang Scheduling 的作业(如分布式训练)进行分组,保证同一组要么整体成功调度,要么整体不调度。
- 使用综合评分函数
阶段 3:资源匹配与放置
- 对每个候选作业,按照以下顺序尝试放置:
- 首选资源池匹配:根据作业类型与显存需求,选择目标资源池(如标准 GPU Pool)。
- 节点过滤:只保留满足以下条件的节点:
- 有足够的 CPU/GPU/内存余量。
- Label/污点/容忍度(如 GPU 类型、可用区、机架)满足约束。
- 配额和成本预算允许。
- 放置算法:采用 分数打分 + Bin Packing 组合策略:
- 评分维度:节点当前负载、数据本地性、预估网络成本等。
- 目标:在确保数据本地性的前提下尽量把负载“打包”,避免大量小作业分散导致碎片。
- 对每个候选作业,按照以下顺序尝试放置:
阶段 4:抢占与回退
- 若高优先级作业无法找到可用资源,则调用抢占逻辑:
- 按“优先级从低到高 + 剩余运行时间从长到短”选择被抢占候选。
- 对支持 Checkpoint 的作业先发送 Checkpoint 信号,待确认后再回收资源。
- 若仍无法满足需求(例如没有可抢占目标或预算不足),则作业保持排队状态,并记录调度失败原因用于观测。
- 若高优先级作业无法找到可用资源,则调用抢占逻辑:
5.5.2 公平共享(Fair Share)与配额结合
flowchart TD
Usage[近一段时间资源使用统计<br/>按团队/项目] --> Calc[计算 FairShare 指标]
Calc --> Adjust[调整作业得分中的惩罚项]
Adjust --> Sched[影响下一轮调度排序]
- 对每个团队/项目,维护滚动时间窗口内的 GPU 小时 / CPU 小时 使用统计。
- 定义期望份额
ExpectedShare(由配额决定)与实际份额ActualShare:- 若某团队
ActualShare >> ExpectedShare,则对其新作业增加惩罚项。 - 若某团队长期低于期望,则在排序中给予适度倾斜(鼓励“补偿使用”)。
- 若某团队
- 这样在 配额硬上限 之上,再叠加一层 软公平性 控制,避免“抢占配额”导致体验极差。
5.5.3 Gang Scheduling(成组调度)
分布式训练等作业需要多 GPU 节点同时到位,否则无法启动,故采用成组调度:
- 在调度阶段为 Gang 作业预分配“资源申请集合”,只有当集合中所有 Pod 都找到合适节点时才真正下发到 K8s。
- 若只部分 Pod 找到位置,则全部撤销,等待下一轮调度,避免半启动状态浪费资源。
- 对大 Gang 作业(如 16 节点 128 GPU)引入:
- 优先预占窗口:允许在一小段时间内“积累”足够空闲资源再统一调度。
- 最大等待时长:超过则提示用户缩小规模或调整资源池。
5.5.4 Backfill(回填)策略
为避免因为等待大作业导致整体资源空转,引入回填策略:
- 调度器首先为高优先级、大 Job 预估未来一段时间内的资源需求。
- 对暂时无法满足的大 Job,“标记保留窗口”。
- 在保留窗口内,如果仍有短时空闲资源,可以调度 短作业或低优先任务 填档,但必须确保:
- 其预计运行时间不影响高优任务在保留窗口内启动。
- 或该短作业可被抢占且有 Checkpoint 支持。
5.5.5 成本感知的具体打分方式
在资源放置时,引入简单的成本打分模型:
[ NodeScore = w_l \cdot LocalityScore - w_c \cdot CostPerHour - w_f \cdot Fragmentation ]
LocalityScore:数据本地性评分,高缓存命中优先。CostPerHour:按 GPU/CPU 实例单价换算的小时成本;Spot 实例成本较低但要结合中断风险。Fragmentation:若在该节点放置后容易造成资源碎片,则增加惩罚。
调度器通过调整权重 w_l, w_c, w_f,在 性能优先 与 成本优先 模式之间灵活切换。
6. 弹性伸缩与容量管理
6.1 自动扩缩容状态机
stateDiagram-v2
[*] --> Monitoring: 持续监控指标
Monitoring --> ScaleUp: 满足扩容条件
Monitoring --> ScaleDown: 满足缩容条件
Monitoring --> Stable: 状态稳定
ScaleUp --> Provisioning: 创建新节点
Provisioning --> Monitoring: 节点就绪
ScaleDown --> Draining: 排空节点
Draining --> Terminating: 回收实例
Terminating --> Monitoring
扩容触发信号(示例):
- 队列等待时间(训练队列 P95 > 5 分钟)。
- GPU 利用率长时间 > 85%。
- Pending Pod 数量连续多个周期 > 阈值。
缩容触发信号(示例):
- 空闲 GPU/CPU 节点持续空闲 > 15 分钟。
- 当前队列无排队作业。
6.2 各资源池扩缩容差异策略
| 资源池 | 扩容触发 | 扩容速度 | 缩容策略 | 最小/最大节点数 |
|---|---|---|---|---|
| CPU Pool | ETL 队列等待 >3m | 快 | 空闲 10m 即缩容 | 10 / 100 |
| GPU 标准 Pool | 训练等待 >5m | 中 | 空闲 15m 后渐进缩容 | 5 / 50 |
| GPU 高性能 Pool | 审批后手动扩容 | 慢/人工 | 空闲 30m 后缩容 | 0 / 10 |
| Spot Pool | 队列等待 >2m | 快 | 空闲 5m 即缩容 | 0 / 200 |
设计考虑:
- 标准 GPU Pool 强调平衡训练体验与成本,避免频繁扩缩容导致训练启动极慢。
- 高性能 GPU Pool 价格昂贵,采用 半自动 + 人工审批 的模式防止滥用。
7. 可观测性与运维闭环
7.1 指标与日志采集
graph LR
subgraph Metrics["指标采集"]
M1[作业级指标<br/>状态/耗时/重试]
M2[资源级指标<br/>CPU/GPU 利用率]
M3[队列级指标<br/>等待时间/吞吐]
M4[成本指标<br/>实例费用/队列费用]
end
subgraph Logs["日志与事件"]
L1[调度决策日志]
L2[抢占事件记录]
L3[扩缩容事件]
end
Collector[采集与聚合层] --> M1
Collector --> M2
Collector --> M3
Collector --> M4
Collector --> L1
Collector --> L2
Collector --> L3
用途:
- 为平台运营方提供队列公平性、抢占频率、资源利用率的量化视图。
- 支持 回放调度决策,定位异常调度行为或成本异常。
7.2 调度与容量的优化闭环
flowchart TD
Obs[观测数据<br/>指标 + 日志] --> Analyze[分析与报表]
Analyze --> Insight[发现问题<br/>如队列长等待、GPU 利用不足]
Insight --> Plan[制定优化方案<br/>调整队列/配额/扩缩策略]
Plan --> Apply[通过配置中心下发变更]
Apply --> Obs
示例优化场景:
- 发现训练队列经常长时间排队 → 提高 GPU Pool 最小节点数或增加 Spot 使用比例。
- 发现某团队长期占用大量 GPU 但平均利用率低 → 通过配额与成本告警促使其优化作业。
8. 与其它层的协同与边界
与数据湖(L2)/元数据层(L3):
- 调度器通过元数据感知数据存放位置、缓存情况,从而进行拓扑感知调度。
- 作业生命周期与数据血缘打通,可追踪“某训练作业使用了哪些数据版本与特征版本”。
与模型训练与服务层(L5):
- 训练 Job 的资源申请、调度、Checkpoints 管理由本层负责。
- 训练完成的模型交由 L5 进行版本注册与上线发布,本层仅关心训练阶段资源使用。
与用户与工具层(L7):
- Notebook / Job UI / API 只与 Job API 交互,不直接操作底层资源。
- UI 侧展示队列状态、预估开始时间、预计费用等信息,增强用户对调度行为的理解。
9. 小结:计算与调度层的价值
- 统一算力平面:将分散的 CPU/GPU/Spot 资源统一成一个可被编排和观测的资源平面。
- 多队列 + 多资源池:通过队列、优先级、配额、成本策略实现对不同作业类型的差异化服务。
- 智能调度与弹性能力:结合拓扑感知、成本感知和自动扩缩容,使得平台既能保证性能,又能显著降低成本。
- 可观测与可治理:通过监控、日志和配额治理,为平台长期稳定运营和持续优化提供基础。
该层作为整个机器人训练数据处理平台的“算力中枢”,确保上层数据处理与训练工作负载在公有云环境中高效、可控、可持续地运行。
10. 技术栈与第三方组件选型建议
本节聚焦于实现计算与调度层时可选用的关键三方组件与库,重点考虑 成熟度、生态、云环境适配度。
10.1 调度与批作业框架
Kubernetes 原生调度扩展:
- Kueue:K8s 官方 SIG-scheduling 下的批作业队列与配额管理框架,适合训练/ETL 队列场景。
- Volcano / Yunikorn:适合大规模批作业与 GPU 调度,支持队列、Gang Scheduling、抢占等高级特性。
- 适用场景:
- 对 K8s 依赖重、期望统一资源平面的场景。
- 希望尽量复用社区已有的调度能力,减少自研工作量。
作业级编排:
- Apache Airflow:成熟的工作流引擎,用于“数据接入 → ETL → 特征工程 → 训练 → 评估”的 DAG 编排。
- Prefect / Argo Workflows:更云原生的选择,与 K8s 结合紧密,适合全容器化场景。
10.2 分布式计算与训练框架
Spark:
- 用于大规模 ETL、批量特征工程,配合 Spark on Kubernetes + Spark Operator 使用。
- 优势:生态成熟、对 Parquet/Delta 等数据湖格式支持好。
Flink / Spark Streaming:
- 用于实时数据接入与流式处理,构建实时特征与在线指标。
- 若实时性要求极高且复杂流计算,Flink 更合适;若希望与现有 Spark 生态复用,可优先 Spark Streaming。
Ray / Ray Data / Ray Tune:
- 用于分布式 Python 任务、特征工程与超参搜索。
- 与 Ray Operator 配合,可在 K8s 上动态创建 Ray 集群。
PyTorch / PyTorch Lightning / DeepSpeed:
- 核心训练框架,支持 DDP、模型并行与混合并行。
- PyTorch Lightning 简化训练逻辑,提升可维护性;DeepSpeed 适合大模型训练。
10.3 K8s Operator 与 CRD 选型
Spark Operator(Google / community):
- 通过
SparkApplicationCRD 管理 Spark 作业生命周期。 - 支持动态资源申请、失败重试、日志采集等。
- 通过
Kubeflow Training Operator:
- 提供
PyTorchJob、TFJob、MPIJob等 CRD,适合统一管理多框架训练。 - 与 Kueue、Volcano 等组合,可实现 Gang Scheduling 与队列调度。
- 提供
Ray Operator:
- 通过
RayClusterCRD 管理 Ray 集群,自动扩缩。 - 适合特征工程、在线服务与超参搜索等。
- 通过
JupyterHub / Kubeflow Notebook Controller:
- 为 Notebook 场景提供多用户会话管理与资源隔离,结合本方案的交互队列使用。
10.4 成本与监控相关组件
Prometheus + Grafana:
- 采集 K8s、节点、GPU、作业指标,并展示在统一 Dashboard 上。
- 可通过自定义 Exporter 采集队列延迟、调度事件、成本估算等。
Thanos / Cortex:
- 用于大规模时序指标的长周期存储,便于做长期成本与容量分析。
OpenTelemetry + Jaeger:
- 实现从 Job API → 调度器 → K8s → 训练容器的全链路追踪,辅助定位调度与性能问题。
10.5 数据本地性与缓存层组件
- Alluxio / JuiceFS / Nydus 等分布式缓存层:
- Alluxio:成熟的数据加速层,可将 S3 上的训练数据缓存到本地 SSD 或内存。
- JuiceFS:兼具文件系统接口与对象存储后端,适合训练数据与 Checkpoint 存取。
- 这些组件与拓扑感知调度器结合,可显著降低跨区/跨机架的数据访问成本。
10.6 技术选型建议小结
- 调度核心:优先基于 Kubernetes + Kueue/Volcano/Yunikorn,只在必要逻辑上做“插件式扩展”(如成本打分、Fair Share)。
- 计算引擎:ETL/特征工程用 Spark/Flink,训练用 PyTorch + Training Operator,超参与分布式 Python 用 Ray。
- 编排与体验:上层采用 Airflow/Argo 进行工作流编排,Notebook 采用 JupyterHub 或类 Databricks Notebook 服务。
- 缓存与本地性:Alluxio/分布式缓存 + 拓扑感知调度组合,实现“就近计算”。
整体技术栈在保持开源、云中立的前提下,尽量选择社区成熟组件,并通过统一的调度与 CRD 体系将其整合在一起,减少自研调度器的工作量,把精力投入到 策略与算法层的差异化能力 上。