人人都会AI编程

19.3 存储系统设计

更新时间:2026-07-09

在 19.1 节服务器选型和 19.2 节网络架构设计之后,存储系统是算力中心硬件架构的第三根支柱。一个常被忽视的现实是:存储瓶颈往往比计算瓶颈更隐蔽,但一旦爆发,整个千卡集群的 GPU 利用率会从 90% 直接跌到 30% 以下——几百张卡空转等数据,是算力中心最昂贵的浪费。

本节的核心设计理念只有一条:数据有冷热之分,存储必须分级。把训练数据、模型快照、系统日志这三种性质完全不同的数据混在同一套存储上,是工程上的自我折磨。


一、三大数据类型与核心需求

在动手画架构图之前,先明确你的存储系统要伺候的三类“客户”:

| 数据类型 | 典型大小 | 读写模式 | 核心需求 | 性能敏感度 |
|---------|----------|---------|---------|-----------|
| 训练数据 | 几十 TB–数 PB | 海量顺序读,极少写入 | 高吞吐带宽、低成本容量 | 直接影响 GPU 利用率 |
| Checkpoint(模型快照) | 单次几百 GB–数 TB | 周期性突发写入,偶尔读取 | 高写入带宽、低恢复延迟 | 断点续训时决定恢复速度 |
| 日志与元数据 | 相对较小(TB 级) | 持续小量写入,频繁查询 | 低延迟 IOPS、持久可靠 | 间接影响运维效率 |

关键洞察:如果你让 Checkpoint 写入和训练数据读取共享同一套机械硬盘,两者争抢 IO 带宽,训练吞吐量会出现周期性抖动——每次保存 Checkpoint 的几分钟内,GPU 都可能陷入等待。


二、第一级:训练数据存储——高吞吐、大容量、低成本

数据特点:动辄 PB 级别的文本语料、图文对数据、视频帧切片。一旦预处理完成入库,几乎不再修改,只在训练时被反复顺序读取。

核心指标

  • 聚合读取带宽:这是决定 GPU 是否空闲的第一硬指标。经验法则是:所有训练节点的总读取带宽,至少应是所有 GPU 峰值训练吞吐量的 1.5–2 倍(留余量应对 IO 抖动);
  • 单线程/单节点读取性能:一般要求单节点能跑满至少一张 200Gb/s 网卡的带宽(约 25 GB/s);
  • 容量扩展性:PB 级起步,允许在不中断服务的情况下扩容。

推荐方案——并行文件系统(Parallel File System)

大模型训练场景几乎不会用 NFS 之类的单点存储,而是必须采用并行文件系统,让所有计算节点能同时从多个存储节点并行拉数据。

使用并行文件系统的一个常见困惑是:“为什么我的存储容量明明够,读取速度却上不去?”

这是因为大多数项目误判了瓶颈来源。在并行文件系统中,读写带宽通常受限于存储节点数量,而非硬盘总容量。比如你有 10 个存储节点,每个提供 4 GB/s 带宽,总聚合带宽就是 40 GB/s;如果只有 2 个节点,哪怕每个节点插满硬盘,总带宽也被这两个节点的网卡和 CPU 能力锁死。因此设计存储系统时,应先计算所需总带宽,再反推最少要多少存储节点,最后才填容量。

目前业界主流选型:

| 产品 | 优势 | 劣势 | 适用场景 |
|------|------|------|---------|
| Lustre | 老牌 HPC 标配,成熟稳定,性能极致 | 部署运维复杂,多租户管理弱 | 纯高性能训练集群 |
| GPFS / Spectrum Scale | 企业级功能完备,多站点、分层存储 | 商业许可昂贵 | 大型企业/超算中心 |
| JuiceFS / Alluxio | 云原生友好,POSIX 兼容,可对接 S3 | 需关注元数据服务性能 | 混合云/云上训练 |
| Ceph | 开源,统一存储(对象/块/文件) | 小块随机 IO 强,但顺序大带宽不如 Lustre | 中小规模或通用集群 |

实用建议

  • 如果集群规模在 100 卡以下,万兆 NAS + SSD 缓存层可能够用,不必硬上 Lustre;
  • 超过 200 卡且以训练为主,Lustre 或 GPFS 仍然是最安全的选择;
  • 在多机多卡训练时,同一份数据会被不同节点重复读取,务必在应用层做好 数据预加载(Dataloader Prefetch)和内存缓存(Page Cache),减少实际 IO 压力。

三、第二级:Checkpoint 存储——极致写入带宽与快速恢复

数据特点:Checkpoint 是训练到某个时刻的模型权重和优化器状态的完整快照。LLM 训练的 Checkpoint 体积巨大——一个 70B 参数的模型,单次保存的 FP16 权重约 140GB,加上 AdamW 优化器状态(一阶矩 + 二阶矩)翻 2 倍,瞬间变成约 420GB

核心需求

  • 写入速度:必须能在分钟级完成千 GB 级别的落盘。如果每 4 小时保存一次 Checkpoint,单次保存耗时 30 分钟,GPU 利用率直接损失 12.5%;
  • 读取速度:一旦发生节点故障或训练崩溃,需要从最近的 Checkpoint 快速恢复。恢复时间直接等于昂贵的 GPU 空转时间;
  • 可靠性:Checkpoint 是唯一的“存档”,丢失一次可能意味着数百万美元的重训成本。

推荐方案——本地 NVMe SSD + 并行文件系统分层

业界在 Checkpoint 存储上有个广泛共识:用最快的本地盘承接写操作,再异步搬运到持久化存储

为什么 NVMe?因为 Checkpoint 写入是单次大块的连续写操作,且要求极低延迟。NVMe SSD 的单盘顺序写带宽可达 3–7 GB/s,4–8 块 RAID0 轻松超过 20 GB/s。当分布式训练使用完全同步的 Save(ZeRO Stage 3)时,可能所有 GPU 节点同时写入 Checkpoint,此时总聚合带宽可以粗略估算为:

总峰值写入带宽 ≈ 单节点 NVMe 写入带宽 × GPU 节点数

对于 128 张 A100 的集群,这可能意味着瞬间需要 2 TB/s 级别的写入能力。显然,纯靠远端存储难以稳定承接这种并发。因此当前标准做法是:每台 GPU 服务器的本地 NVMe 作为一级“着陆点”,各节点先并行写到本地盘(速度快且互不争抢),再通过异步任务搬运到高可用的并行文件系统或对象存储中完成持久化。同时保留最近 3–5 个 Checkpoint,手动或自动定期清理旧快照,避免本地盘被撑满。

实用补充

  • 生产环境务必设置保留策略:本地盘留 3–5 个,远端留一周以上;
  • 训练脚本中要启用 异步 Checkpointing(PyTorch 的 Async Checkpoint 或 DeepSpeed 的 Checkpointing Offload),让保存不阻塞训练;
  • 端到端的恢复时间(从“触发恢复”到“训练重新跑起来”)应该成为日常巡检指标,而非等到故障时才发现三个小时都没恢复完。

四、第三级:日志与元数据存储——低延迟、高可靠、方便排查

数据特点:训练框架日志、GPU 状态监控数据、集群调度系统日志、容器日志、错误堆栈信息等。单条不大,但数量庞大,且需要支持频繁写入和关键字检索。

核心需求

  • 高 IOPS(输入/输出操作次数每秒):可能数千个进程同时写日志;
  • 低延迟:日志查询和告警需要秒级响应;
  • 持久性:集群故障时,日志往往是唯一的“黑匣子”;
  • 容量可控:TB 到数十 TB 级别即可。

推荐方案

日志存储没有 Checkpoint 存储那么高的带宽要求,但需要稳定、可靠、易于检索:

  • 短期热数据:直接写本地 NVMe 或小容量 SATA SSD,借助 Loki、ELK(Elasticsearch + Logstash + Kibana)等日志收集管道归档;
  • 长期归档:旧日志压缩后转到廉价 HDD 或对象存储,定期清理;
  • 监控数据(Prometheus / Grafana 底层 TSDB):对 IOPS 和延迟敏感,建议独立部署在 SSD 上,不要和训练 Log 混存。

五、分级方案总览

将上述三层方案汇总为一张存储架构图:

┌─────────────────────────────────────────────────────┐
│  计算节点(GPU 服务器)                               │
│  ├─ 本地 NVMe:Checkpoint 一级写入(异步落盘)         │
│  ├─ 本地 Page Cache:训练数据预读缓存                  │
│  └─ 本地日志代理:实时推送日志到外部日志集群            │
└─────────────────────────────────────────────────────┘
          │                    │               │
    数据读取                Checkpoint     日志流
          │               持久化写入          │
          ▼                    ▼               ▼
┌─────────────┐    ┌──────────────┐   ┌──────────────┐
│ 并行文件系统  │    │ 并行文件系统   │   │ 日志集群      │
│ (训练数据)  │    │ 或对象存储     │   │ ELK / Loki   │
│ Lustre/GPFS │    │ (Checkpoint) │   │ + 时序数据库  │
│ PB 级 HDD   │    │ NVMe/SSD 层   │   │ (监控指标)  │
└─────────────┘    └──────────────┘   └──────────────┘

设计原则总结

  1. 读写分离:训练数据路径(顺序读)和 Checkpoint 路径(突发写)在物理设备上分开,杜绝相互干扰;
  2. 本地优先:所有对延迟和带宽敏感的瞬时 IO(Checkpoint 写入、Dataloader 缓存),尽可能在本地 NVMe 解决第一棒,远端存储负责持久化;
  3. 冷热分层:热数据(近期 Checkpoint、待训练数据集)在 SSD,冷数据(归档 Checkpoint、旧日志)在 HDD 或对象存储;
  4. 可观测性独立:日志和监控存储集群独立部署,不做性能“优等生”,但必须做可靠性“钉子户”。

六、常见误区与避坑指南

误区 1:“我买了几 PB 的万兆 NAS,训练应该够了”

NAS 多为单机头或双机头架构,聚合带宽有上限。百卡级训练集群的并发顺序读请求会轻易击穿 NAS 机头的处理能力,导致所有 GPU 等 IO。百卡以上集群,请直接用并行文件系统。

误区 2:“Checkpoint 写慢点没关系,训练又不差这几分钟”

如果你每 4 小时保存一次 Checkpoint,单次慢 20 分钟,一天 6 次就是 2 小时——你所有 GPU 中约有 8% 的时间在等 IO 而非做计算。8% 的千卡集群浪费,换算成云账单,月度损失是六位数美金级别的。

误区 3:“所有数据都放对象存储,便宜又大碗”

对象存储(S3/COS/OSS)的设计初衷是高延迟、高吞吐、低成本容量,适用于归档和低频访问。直接把它挂载为训练数据源,单次数据加载的延迟抖动会导致 GPU 利用率心电图式波动。正确做法是让它做冷数据归宿,热数据仍在并行文件系统上。


存储系统设计本质上是对 IO 行为的深刻理解和分层妥协。在下一节(19.4 供电与散热设计)中,我们将转向算力中心最“硬核”的物理约束——当你把几百千瓦的 GPU 塞进一个机房,供电和散热就变成了比代码更棘手的工程问题。