机器学习平台技术栈之 Ceph:筑牢 AI 时代的统一数据底座
机器学习平台技术栈之 Ceph:筑牢 AI 时代的统一数据底座
在构建企业级机器学习平台(Machine Learning Platform)的宏大工程中,我们谈论了计算调度(Volcano)、网络网关(Envoy)、以及 GPU 管理(Device Plugin 等)。然而,在 AI 的世界里,如果没有“数据”,再强悍的算力也只是无源之水。
无论是拥有数十亿张图片的自动驾驶视觉训练集,还是需要频繁保存重启的大语言模型(LLM)几百 GB 的 Checkpoint,亦或是算法端到端流水线(Pipeline)中不同步骤之间需要共享的临时特征文件,存储系统面临着吞吐量、并发度、持久性和云原生兼容性极其苛刻的挑战。
传统的 NAS 或单机文件系统早已无法支撑。在这个背景下,开源分布式存储的无冕之王——Ceph,凭借其“一套系统,三种接口(块、文件、对象)”的高度统一架构,以及无需中心元数据节点的去中心化高可用设计,成为了当今算力中心和 Kubernetes 机器学习平台最为主流的基础数据底座。
本文将极其硬核地深入解构 Ceph。从核心底层组件,到神级路由算法 CRUSH,再到它在 Kubernetes 中如何通过 Rook 与 AI 训练任务完美结合。通过这篇“万字级”深度的深度干货,带你穿透数据的汪洋大海。
1. 痛点:AI 训练到底撞上了什么样的“存储墙”?
在理解 Ceph 为什么称霸集群之前,我们必须看看 AI 训练任务对存储系统提出了哪些“变态”的要求:
- **海量小文件并发读取 (I/O 梦魇)**:计算机视觉(CV)训练往往需要每个 Epoch 随机打乱并读取数千万张几十 KB 的小图片(通过 PyTorch DataLoader)。传统的集中式存储在面对这种高并发元数据(Metadata)检索时,响应极易拥塞崩溃。
- **大文件极速写入 (Checkpoint 风暴)**:千亿参数的大模型训练往往采用 3D 并行,需要每隔几小时将当前的权重状态同时转储。几百个 GPU 并发写入几百 GB 数据,网络吞吐压力瞬间爆表。
- **多节点数据强一致共享 (RWX 支持)**:分布式训练中,通常需要多台物理机(多个 Pod)同时挂载同一份数据目录进行并行读取。这需要存储系统支持
ReadWriteMany(RWX)语义。 - 结构化与非结构化杂糅:既需要极其快速的文件系统(如挂载训练集),又需要廉价且海量的对象存储(用来做数据集归档和 MLflow 模型无版本管理)。
为了解决同时想要“文件、块、对象”的痛点,Ceph 走上了全能王的王座。
2. 核心架构设计与三种存储形态
Ceph 的架构设计是一首优雅的冰与火之歌。它的基本哲学是:底层构建一个无限可扩展的、强一致的、去中心化的对象存储底座(RADOS),然后再并在其上套不同的马甲(接口)向外界提供服务。
1 | graph TD |
Ceph 向上方提供的三大引擎:
- **RBD (块存储)**:向 K8s 暴露为一个纯底层的裸盘。速度极快,用于挂载给数据库(如 AI 平台底层的 MySQL 或 Redis),一般仅支持单节点读写(
ReadWriteOnce, RWO)。 - **CephFS (文件存储)**:符合 POSIX 语义标准。可以像普通硬盘一样在多台机器配置中被
mount,并支持群组并发读写(ReadWriteMany, RWX)。在 AI 领域,这是挂载训练源码、日志、数据集最高频的存储方式。 - **RGW (对象存储 Gateway)**:兼容 AWS S3 协议。应用通过 HTTP 通信,使用 Bucket 与 Object。非常适合大模型平台用来构建统一的模型制品仓库(Model Registry),抛弃本地文件依赖。
3. Ceph 核心底层概念大解析
我们要真正掌握 Ceph,必须要将其下方的 RADOS 底座抽丝剥茧。这里有四个最重要的实体概念:OSD、MON、PG 以及 Pool。
3.1 实体组件概念
- OSD (Object Storage Daemon):真正的“搬砖工”。集群里的每一块物理硬盘(HDD 或 NVMe SSD)都会对应运行一个起管理作用的 OSD 进程(Daemon)。OSD 负责实际保存数据块,并与其它 OSD 进行心跳检测和数据副本的复制/恢复。
- MON (Monitor):监控者 / 维系视角的首脑。MON 维护着集群状态的映射图(Cluster Map 的权威副本,包含 OSD Map 等)。值得注意的是,用户的读写数据绝对不经过 MON 节点(只取图),从而消除了中心化性能瓶颈。
- MDS (Metadata Server):仅在 CephFS 中存在。在提供基于目录和层次结构的文件系统时,需要解析树状结构和权限。MDS 取代了 OSD 来响应各种如
ls,cd,mkdir的元数据系统调用(并将解析完的物理地址给客户端去直接对接 OSD 下载主干数据)。 - **MGR (Manager)**:辅助监控系统的集群健康指标并管理暴露外部接口。
3.2 抽象数据概念
- **Pool (存储池)**:一种逻辑隔离分区。我们可以通过给机械硬盘分配一个 Pool 名叫
hdd-pool用于冷备,给全闪 NVMe 分配一个 Pool 名叫nvme-pool用于 AI 高速训练。针对每个 Pool,我们可以配置不同的副本数(Replica Size = 3)或是纠删码(Erasure Coding)。 - PG (Placement Group, 归置组):对大量 Object 的逻辑分组。这可以说是影响调度性能最重要的概念。由于系统内的 Object(如几十 KB 的小图)多达几十亿个。如果每次 OSD 变动都要去追踪哪些 Object 发生变动将是巨大的算力灾难。Ceph 将成千上万的对象哈希后放入若干个编号固定的 PG 中,后续数据恢复和监控都以 PG 为最小调度单元(比如迁移数据就是迁移一整个 PG)。
4. 极致的技术结晶:概念的化学反应与数据寻址
在一个拥有 1000 块硬盘的 PB 级别存储集群里,当 PyTorch 读取一个叫 /train/dog.png 的文件时,Ceph 怎么知道要去哪一块硬盘(甚至是机架和机房)上把这两百 KB 的数据精确捞出来?
传统的 HDFS 或是元数据服务,会记录一张无限庞大的表:[dog.png] -> [Disk A]。这会导致该查询节点极易宕机卡死。
而 Ceph 放弃了中心字典,采用了极其高超的 CRUSH 算法 进行纯数学函数的客户端本地散列(Hashing)。
4.1 数据切分与路由流程图 (Data Routing Pipeline)
1 | flowchart TD |
4.2 计算步骤极其精妙的解构:
- **File to Object (文件切被割)**:系统将该文件切分成多个通常是 4MB 固定大小对象的序列,赋予全局唯一名称(OID,比如
obj_1)。 - **Object to PG (对象归属)**:对
obj_1的名称进行哈希运算,并将结果取模PG_NUM。这就不可变更地将其归入了一个具体的 Placement Group(例如:计算出等于 PG 42)。 - PG to OSDs (核心: CRUSH):这是最伟大的发明——CRUSH (Controlled Replication Under Scalable Hashing) 算法。
- 客户端从 MON 处拿到非常小的一张 Cluster Map(包含了机房、机柜、宿主机和硬盘的拓扑树)。
- 客户端在其本地直接用公式算出:
CRUSH(PG_42) -> [OSD_3, OSD_9, OSD_45]。 - 这个公式保证了:算出来的 3 个 OSD 副本(假设系统副本数为 3)一定会分散在不同的容错域(Failure Domains)。比如 OSD3 和 OSD9 绝对不会落在同一个机柜内(保证断电时数据不丢)。
这样一来,不需要任何中心查询,任意一台有计算能力的调度客户端就能在一瞬间“算”出数据位于哪里,然后直接跟对应 OSD 发起 TCP 握手通信去捞数据。这是何等惊艳的去中心化性能!
4.3 写入的数据流与强一致性机制
Ceph 遵循极其严苛的一致性设计(相比于追求高吞吐允许丢部分数据的弱一致性系统)。
当发生写入操作时(例如保存 LLM 的 model-epoch-1.ckpt):
- 客户端使用 CRUSH 算出该 PG 的三个 OSD 列表
[OSD_A, OSD_B, OSD_C]。 - 列表排名第一的
OSD_A自动成为主代理(Primary OSD)。 - 客户端只将数据包发送给 Primary OSD_A。
- OSD_A 收到后,内部并行向次级副本
OSD_B和OSD_C转发写入请求。 - 直到 B 和 C 都落盘并向 A 回复 ACK 后,Primary OSD_A 才会统一向客户端返回
Write Success。
这保证了在任何读取时刻(就算同时并发发生宕机主从切换),AI 跑出来的权重永远不会遇到脏数据回退(Silent Data Corruption)。
5. 高性能存储引擎:BlueStore 深水区
传统的 Ceph 在 OSD 写入物理磁盘时,走的是:RADOS 对象 -> 先写入宿主机 Linux 操作系统的 XFS/ext4 文件系统 -> 硬件磁盘 的链路。
这种做法的软肋在于内核双写效应(Journaling Double Write)和文件系统本身的元数据包袱,这在高速 NVMe 时代被放大了延迟。
现代的 Ceph 标配了 BlueStore 存储引擎。
BlueStore **完全绕过了本机的 Ext4 / XFS (Bypass Kernel FS)**。它直接接管裸硬盘块设备!
- RocksDB:使用一个极度优化的嵌入式 RocksDB 来保存 Object 那些海量的元数据和寻址路径。
- BlueFS:由于 RocksDB 自己需要跑在文件系统上,Ceph 手搓了一个小型的 C++ 极简微型文件系统(只限给 RocksDB 自己用)。
- **数据直写 (Direct Write)**:用户真实的业务数据比特流,直接通过异步 IO 落进裸盘地址。
借助 BlueStore 的架构,在应对海量机器视觉碎片图像随机小包读取的机器学习负载中,其 IOPS(每秒读写次数)性能相比原来的 FileStore 飞跃式地提升了 2 到 3 倍。
6. 在机器学习云原生平台中的最佳实践:Rook / CSI
回到我们的 Kubeflow / 原生 Kubernetes 场景。作为一堆分布在物理机上的进程,AI 平台的用户不可能亲自去写 librados 代码或调用命令行管理。
这就不得不提 CNCF 毕业级的大神项目:Rook。
6.1 Rook + Ceph:驯服凶兽
Rook 充当了 K8s 中的 Operator。它让复杂的存储引擎部署彻底“Kubernetes-Native 化”。
你只需要用一个 YAML 写明 UseAllNodes: true, UseAllDevices: true。Rook 的控制器就会:
- 派 DaemonSet 去给节点上的全新裸磁盘自动进行格式化操作。
- 将 OSD、MON、MGR 全部作为 K8s 本生的 Pod(带有 HostNetwork 特权)拉起并维稳。
- 如果一块盘坏了,Pod 发生 CrashLoop,Rook 自动发起数据恢复重平衡(Rebalancing)。
6.2 PVC 到底层数据结构的映射与挂载使用
在 AI 平台(如 PAI 或者自己搭建的流水线)提交一个训练任务时,算法工程师只看得到 PVC (Persistent Volume Claim)。这一切是如何打通的?
1 | sequenceDiagram |
在实际的训练中的选型场景:
场景 1:大规模 NLP 语料预处理清洗
清洗任务往往产生几千万个几十 KB 的分词缓存。建议使用 CephFSStorageClass创建RWX的 PVC,分配给多个 Ray Worker Pod 并发清洗;且强烈建议将 CephFS 的 Metadata Pool (MDS 所需的池) 存放在基于纯 NVMe SSD 的设备组合上,避免海量lsstat导致的寻道超时。场景 2:MLflow 或 HuggingFace 模型仓库构建
对于不可变的、极大的结果压缩包(50GB.safetensors),最佳实践是不要用 K8s 本地 Volume,而是依靠 **Ceph RGW (S3 兼容网关)**。
平台应用或训练代码只需使用原生的boto3(S3 python 包)并配置好 Ceph RGW 的内外网网关入口,将生成的 Checkpoint 以 Http Put 的形式抛给集群的大容量低成本 HDD 后备存储中。不仅杜绝了由于存储满导致容器发生 Pod Eviction 的尴尬悲剧,还能利用存储网关极其廉价地做公网预签名分享(Presigned URL)。
7. 总结:承载智能的汪洋之水
当你在使用 PyTorch 优雅地敲下 torch.save(model.state_dict(), '/data/checkpoint.pth') 时,这背后的 2GB 二进制信息,会迅速经过 K8s 宿主机的网络 namespace、跨越虚拟网桥、被切成了 500 个碎片对象。之后,通过伟大的去中心化算法 CRUSH 被打散映射到浩瀚机房深处的不同物理硬盘内。这一切均在一瞬间完成无感流转,并永远抵御任何硬件级的拔线死亡。
对于现代机器学习平台基建工程师而言,如果没有吃透 Ceph (及其上层 Rook 管理链)就等于建房子没有打好地基。
Ceph 提供的数据统一视角(文件供训练集、块供平台数据库、对象供制品),极高的高可用与强扩展性(无惧 AI 算力潮汐导致的多节点规模激增),让它真正承载起了驱动百模大战的“汪洋之水”,成为了 AI Infra 版图中最为耀眼、稳定且厚重的定海神针。





