Uber将Michelangelo ML平台从单体升级为云原生Kubernetes,通过CRD、联邦模式和Uniflow等技术,解决了扩展瓶颈、资源孤立和开发效率问题,实现了每秒3000万次预测,并规划自愈生态。
译自:From monolith to global mesh: How Uber standardized ML at scale
作者:Eric Wang, Ying Zheng
引言:扩展的瓶颈
2015年,Uber 的增长速度超过了其基础设施的承受能力。随着公司从豪华轿车服务发展成为全球物流巨头,每个工程团队都开始构建自己的机器学习“孤岛”。数据科学家将80%的时间花在手动“管道工程”上——管理服务器和数据管道——而不是构建模型。“冷启动”问题成为现实:将一个模型从笔记本电脑部署到生产环境需要数月时间。
“数据科学家将80%的时间花在手动‘管道工程’上——管理服务器和数据管道——而不是构建模型。”
Michelangelo 便诞生于这种混乱之中。它被设计为 Uber 的集中式“支柱”,通过为机器学习创建一个标准化的端到端传送带,实现人工智能的民主化。但当我们跨越每秒 3000 万次预测的门槛时,我们遇到了一个扩展瓶颈,这需要一次根本性的架构转变:从单体遗留堆栈转向云原生的 Kubernetes 基础。

架构:解决“平台现实”
现代平台工程不仅仅是运行容器;它关乎管理 Uber 训练的每个模型的分布式状态。我们利用 Kubernetes 作为分布式状态机来解决这些关键的扩展瓶颈。
扩展控制平面:高基数 CRD 和透明持久化
在 Uber 的运营规模下,一个普通的 Kubernetes 实现面临着巨大的压力。标准集群依赖于 ETCD,它针对小而扁平的键值对进行了优化。然而,Michelangelo 管理着数千个具有复杂高基数关系链接的项目和模型。
策略:通过自定义资源实现架构抽象。 我们没有强行将关系数据模型塞入非关系存储,而是采用了一种“两全其美”的方法,利用先进的 Kubernetes 模式:
- 100+ 个专用 CRD: 我们定义了一个包含 100 多个 自定义资源定义(CRD) 的广泛生态系统,代表了完整的机器学习生命周期。这使我们能够利用标准的 Kubernetes API 和 controller-runtime,同时保持丰富且领域特定的数据模型。
- 透明的关系持久化: 为了解决 etcd 的扩展限制,我们设计了一种对用户完全透明的存储抽象。虽然开发人员通过 kubectl 或我们的 API 与标准 Kubernetes 对象交互,但底层元数据与横向可扩展的 MySQL 后端同步。
- 高效调和: 通过将 CRD 映射到优化的关系模式,我们实现了复杂的连接和毫秒级延迟过滤,这在标准 Kubernetes 中是不可能实现的。
解决搁浅计算:联邦模式
Uber 运营着数十个区域集群。在联邦化之前,数据科学家和工程师必须手动选择集群。这导致了“搁浅计算”问题:集群 A 将以 100% 的容量和巨大的队列运行,而集群 B 则空闲 50%。
教训:抽象物理集群。我们使用 PropagationPolicy CRD 实现了统一批处理联邦层:
- 工程师现在将作业提交到**“虚拟区域集群”。一个联邦控制器**充当全球交通警察,检查所有物理区域的实时 GPU 可用性,并为作业“加盖”目标集群。
- 区域 Clusterlet 随后将工作负载规范拉取到本地硬件。这通过将工作负载转移到实际存在容量的地方,确保了 99.9% 的调度成功率。
使用 Uniflow 弥合“摩擦鸿沟”
即使拥有强大的 Kubernetes 核心,我们仍然面临“编排陷阱”。开发人员在用僵化的基础设施语言来串联诸如“处理数据 → 训练 → 安全检查 → 部署”等复杂任务时遇到困难。
为了解决这个问题,我们利用 Uniflow,一个专为 ML 生命周期设计的 Python 原生工作流服务。与通用 ETL 引擎不同,Uniflow 是一种“灵活”的工作流服务,它优先考虑模型开发的独特需求,而非传统的批量数据移动:
- Python 优先体验: 数据科学家使用标准 Python 编写整个工作流,无需 YAML 或复杂的领域特定语言。
- 资源感知调度: 通过智能跟踪“可消耗”资源和专业硬件 SKU 来防止争用,超越了基本的 CPU/GPU 请求。
- 一次编写,随处运行: 确保用于本地调试的代码在全球云中也能相同运行,消除了“在我的机器上可以运行”的不一致性。
- 零接触和代理自动化: 自动化从模型评估到人工参与治理的一切。
通用计算网格:多云批处理编排
2026年,单一云依赖是一种战略风险。对于 Michelangelo 来说,挑战是双重的:访问通常限于特定区域的专用硬件(如 NVIDIA H100s),以及利用跨提供商的 Spot Instances 来保持训练成本的可持续性。
- 云作为商品: 通过利用 Kubernetes 原生抽象,我们构建了一个云无关的批处理层,该层跨越单个控制平面和多个公共提供商(GCP、OCI、AWS 和 Azure)。
- 提供商无关调度: 我们的联邦层将 GCP 中的集群与 Uber 自有的数据中心相同对待。PropagationPolicy CRD 承担了繁重的工作,将高级要求转换为每个提供商特定的网络和存储原语。
- 统一数据访问: 我们实施了一个全球数据网格以确保透明性。无论是 RayJob 在本地区域还是远程云 VPC 中运行,云原生解决方案都能安全地挂载数据集和密钥,使云边界对 ML 模型不可见。
“2026年,单一云依赖是一种战略风险。”
影响:Uber 的生产现实
截至 2026年,该平台以前所未有的规模管理着关键任务工作负载:
- 每秒 3000 万次以上预测: 为全球的实时匹配、定价和安全服务提供支持。
- 每天 4000 万次总行程: 支持移动出行和配送服务的显著增长。
- 每秒 450 次行程: 无缝处理来自 70 多个国家和 15000 多个城市的高速数据。
未来方向:下一个运营前沿
随着我们规模的扩大,管理 100 多个 CRD 和数十个专用控制器的“维护成本”无法仅靠增加人手来解决。我们 2026 年的路线图侧重于将 Michelangelo 从一个托管平台转变为一个自治、自愈的生态系统,通过三个战略支柱:
-
自愈调试: AI 代理实时解析日志,为失败的作业提供即时根本原因分析和修复。
-
代理辅助治理: 智能 CI/CD 自动化复杂的集成测试,确保安全、高速的日常部署。
-
零费力升级: 自动化工作流预验证并将管道迁移到最新框架,使库更新透明化。