并行文件系统过去往往只服务于训练、仿真等高吞吐任务:热数据放在昂贵的高速文件系统里,代码仓库、依赖编译和冷数据则留在另一套环境中。真正消耗工程时间的,常常不是一次 I/O,而是反复复制数据、切换路径、同步权限和等待集群预热。
Google Cloud Managed Lustre 的 Dynamic Tier 试图改变这种分工。它用 SSD 高性能缓存承接热数据和突发写入,以容量池保存较冷的数据,并把两者放在同一个 POSIX 命名空间中。这样,开发者可以在同一挂载点完成 Git 操作、编译、Notebook 开发、训练数据读取和检查点恢复,而不必为每个阶段维护不同的存储路径。
Dynamic Tier 改变的是数据生命周期,而不只是单价
Dynamic Tier 公布的价格为每 GB 每月 0.06 美元,并采用单一费用模式,不再分别计算介质类型、命名空间内部的数据移动或元数据 IOPS。实际使用前仍应确认区域、容量单位和最新定价;例如按十进制 100,000 GB 粗略估算,月度存储费用约为 6,000 美元,但这不包含计算、网络以及其他云资源费用。
更重要的是,它允许热数据和冷数据共享一套路径:
- 高性能缓存(SSD):热数据可获得亚毫秒级读取延迟,交互式测试中平均读取延迟约为 300 微秒。
- 容量池:构建在 Google Cloud Hyperdisk Throughput 之上,平均读取延迟约为 10~30 毫秒。
- 自动分层:训练数据第一次读取后可以晋升到高速缓存;较旧的检查点则可以透明地下沉到容量池。
- 横向扩展:吞吐量随容量线性增长,容量上限可达 80 PB,并面向数万客户端维持热数据的亚毫秒级延迟。
这套模型尤其适合以下访问模式:
- 多轮训练:第一个 epoch 完成后,反复使用的数据已经进入高速缓存;配合较大的预取块,可以降低后续 epoch 的等待时间。
- 突发式检查点写入:新检查点先写入 SSD 缓存,旧检查点逐步下沉,既保留快速恢复能力,也避免所有历史版本长期占用昂贵介质。
- 共享开发目录:代码仓库、虚拟环境、编译产物和数据集共用一个挂载点,减少开发环境与训练环境之间的复制。
- 大规模广播读取:数千个进程同时读取模型权重、容器层或共享库时,存储系统需要避免单文件热点拖慢 GPU 集群启动。
需要注意,自动分层并不会让所有冷数据都具备 SSD 延迟。第一次读取、随机访问大量从未预热的数据,仍可能受到容量池延迟影响。训练框架的读取块大小、预取深度和数据排列方式,依然决定最终效果。
为什么“开发也放在 Lustre 上”值得关注
传统并行文件系统擅长大文件顺序吞吐,却不一定适合 Git checkout、解压源码树或导入 Python 包。这些任务会产生大量小文件、目录遍历和元数据操作。如果开发者不得不把代码放在本地盘,就会重新引入两套环境:本地完成开发和编译,再把产物复制到共享存储或训练节点。
Managed Lustre 针对这些交互式任务进行了优化。公布的测试结果包括:
- 解压 Linux 内核源码约 2 分钟,相比其他文件方案快 4.7 倍;
- 使用 20 个 checkout worker 克隆 CPython 约 40 秒;
- 编译 Python 约 200 秒;
- 在 4,000 多个进程中并行导入 PyTorch,不到 60 秒;
- 2,048 台客户端虚拟机读取同一个 40 GiB 文件时,平均聚合吞吐量为 36.7 GB/s,相比对比方案提升 67%。
这些数字来自特定配置,其中 Managed Lustre 使用每 TiB 500 MB/s 的层级和 108,000 GiB 容量,对照环境也有明确容量条件。因此它们更适合作为验证方向,而不是直接套用到生产环境的性能承诺。客户端机型、网络带宽、条带配置、文件大小和缓存状态都会影响结果。
在自己的挂载点复现实验
下面的命令假设 Managed Lustre 已挂载到 $HOME/LUSTRE_MOUNT。运行前需要安装 fio、git、编译工具和 wget,并确认目录位于 Lustre 文件系统,而不是本地磁盘。
先设置路径并做一次基本检查:
export LUSTRE_MOUNT="$HOME/LUSTRE_MOUNT"
mkdir -p "$LUSTRE_MOUNT"
df -hT "$LUSTRE_MOUNT"
mount | grep "$LUSTRE_MOUNT" || echo "请确认该目录已经挂载到 Managed Lustre"
测量小块、低并发随机访问
这组 fio 参数模拟交互式开发中常见的 4 KiB、队列深度为 1 的读写。每次测试持续两分钟,并跳过最初两秒的预热期:
export LUSTRE_MOUNT="$HOME/LUSTRE_MOUNT"
fio --ioengine=libaio --filesize=100M --ramp_time=2s --runtime=2m \
--time_based --numjobs=1 --direct=1 --verify=0 --randrepeat=0 \
--group_reporting --directory="$LUSTRE_MOUNT" \
--name=randread --blocksize=4k --iodepth=1 --readwrite=randread \
--buffer_compress_percentage=50
fio --ioengine=libaio --filesize=100M --ramp_time=2s --runtime=2m \
--time_based --numjobs=1 --direct=1 --verify=0 --randrepeat=0 \
--group_reporting --directory="$LUSTRE_MOUNT" \
--name=randwrite --blocksize=4k --iodepth=1 --readwrite=randwrite \
--buffer_compress_percentage=50
关注输出中的平均延迟、P95/P99 延迟、IOPS 和带宽。只比较平均值容易掩盖尾延迟,而 IDE、Notebook 和 Python import 对尾延迟往往很敏感。为了区分冷读与热读,可以在文件首次生成后连续运行两次读取测试,并分别保存结果。
测试解压、Git checkout 和编译
下面是一条可以直接改造的开发链路。它会下载 Linux 5.18.9 源码,并将 CPython 克隆、配置和编译到 Lustre 挂载点:
set -euo pipefail
export LUSTRE_MOUNT="$HOME/LUSTRE_MOUNT"
wget -P /tmp https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.18.9.tar.xz
mkdir -p "$LUSTRE_MOUNT/kernel"
time tar -C "$LUSTRE_MOUNT/kernel" -xf /tmp/linux-5.18.9.tar.xz
git config --global checkout.workers 20
rm -rf "$LUSTRE_MOUNT/cpython"
time git clone https://github.com/python/cpython.git "$LUSTRE_MOUNT/cpython"
pushd "$LUSTRE_MOUNT/cpython"
time ./configure
time make -j"$(nproc)"
popd
如果以 root 身份解压,tar 默认可能根据归档内容执行额外的 chown 和 chmod,放大元数据开销。在确认符合权限策略后,可以改用:
tar --no-same-owner --no-same-permissions \
-C "$LUSTRE_MOUNT/kernel" \
-xf /tmp/linux-5.18.9.tar.xz
这不仅是一个基准测试细节,也提示了生产环境中的优化方向:元数据密集型操作要避免无意义的权限变更,并观察目录布局、文件数量和并发创建行为。
验证共享 Python 环境的并发启动
如果集群已经配置 MPI 和主机列表,可以把虚拟环境放在共享挂载点,再从多台客户端同时导入 PyTorch:
export LUSTRE_MOUNT="$HOME/LUSTRE_MOUNT"
python3 -m venv "$LUSTRE_MOUNT/env"
source "$LUSTRE_MOUNT/env/bin/activate"
pip install --upgrade pip
pip install torch torchvision torchaudio
deactivate
mpirun --oversubscribe --hostfile "$HOME/hostfile" -N 4 \
bash -c 'source "$HOME/LUSTRE_MOUNT/env/bin/activate" && python3 -c "import torch; print(torch.__version__)"'
hostfile 每行填写一台可通过 SSH 访问的客户端,例如:
client-01 slots=4
client-02 slots=4
client-03 slots=4
不要在部分节点导入包的同时修改共享虚拟环境。更稳妥的做法是构建新版本目录,完成校验后再通过符号链接或环境模块原子切换。
采用前应验证的四件事
把整个 AI 生命周期放进同一个 Lustre 命名空间,能够减少数据搬运和环境漂移,但并不意味着所有数据都应该无条件迁入。上线前建议完成以下检查:
- 冷热比例:记录训练首轮与后续轮次的命中差异,确认高速缓存足以覆盖工作集。
- 检查点策略:测量突发写入、最新版本恢复和历史版本读取,不要只测试稳定顺序吞吐。
- 元数据压力:单独压测 Git、解压、Python import 和小文件创建;它们与大文件训练吞吐是两类负载。
- 故障与成本边界:核对区域可用性、备份与恢复方式、容量增长、计算和网络费用,以及 POSIX 权限管理方案。
Dynamic Tier 的价值并不是简单地把 HDD 和 SSD 拼在一起,而是让热训练数据、冷历史数据、代码和检查点留在同一个共享工作区。对于反复训练、频繁恢复或大规模并发启动的 AI/HPC 集群,这可能直接减少 GPU 等待和人工数据搬运;对于一次性顺序扫描或很少复用的数据,则应先用真实数据集验证缓存收益,再决定是否集中到 Managed Lustre。