这两天一直在研究这个话题,踩了几个坑,把遇到的东西整理成文,供有需要的朋友参考。
一个 8 卡训练任务,GPU 利用率长期在 35% 打转,nvidia-smi 看显存是满的,但 iter 时间忽快忽慢。你查了一圈,瓶颈不在模型也不在卡,而在 data loader:数据集是 200 万个小图片和一堆 parquet 分片,挂在 NFS 上,loader 一并发读,存储侧的 IOPS 先崩了。这种场面我见过不止一次——算力堆得再猛,存储喂不饱,卡就是空转。
把训练数据搬进一个 S3 兼容的对象存储,往往是比继续加 NFS 或本地盘更顺手的解法。对象存储天然为多读多写、海量小文件、按需扩展设计,和训练/特征工程的访问模式对得上。RustFS 是其中 100% 兼容 S3 API、用 Rust 写的那一个,本文我把它当一个 AI 训练数据底座来接一遍,命令和参数都用官方真实文档,也把几个"路线图上的事"讲在前面。
1. 为什么训练数据更适合放对象存储
训练/推理/特征工程对存储的真正诉求,和数据库不一样:
- 高并发小文件:loader 往往几十个 worker 同时读,对象存储的 flat namespace 不得 POSIX 锁,随便并发。
- 按需扩展,不停机:数据集从 TB 涨到 PB,加节点即扩,不用重建文件系统。
- 数据集版本可追溯:同一次实验要能复现,数据得留历史版本。
- 和工具链对接:MLflow、DVC、Spark 这些大多走 S3 SDK,换 endpoint 就能用。
- RustFS 官方定位就是"面向 AI 数据中心的高性能对象存储",首页明确写了支撑从 TB 到 EB 的数据规模、为高吞吐小文件场景优化。它主打的是内存安全的 Rust 实现带来的高并发与稳定,不是又一个"能跑就行"的 S3 壳。
2. 直接当 MLflow / DVC 的 artifact store
MLflow 和 DVC 的远端存储都基于 S3 接口,只要把 endpoint 指向 RustFS,原本给 S3/MinIO 写的配置几乎不用改。先起一个 RustFS 实例(生产把 latest 换成固定版本):
# 单机先把数据底座跑起来(生产请固定版本标签,别用 latest)
docker run -d -p 9000:9000 -p 9001:9001 \
-v /data/rustfs:/data \
rustfs/rustfs:1.0.0-rc.1 server /data --console-address ":9001"
# 建一个训练数据桶
mc alias set rustfs http://localhost:9000 rustfsadmin rustfsadmin
mc mb rustfs/ml-datasets
MLflow 接 RustFS 只需改两个环境变量,把默认的 AWS S3 endpoint 换成 RustFS:
export MLFLOW_S3_ENDPOINT_URL=http://localhost:9000
export AWS_ACCESS_KEY_ID=rustfsadmin
export AWS_SECRET_ACCESS_KEY=rustfsadmin
# 之后 mlflow.log_artifact() 直接落进 RustFS 的 ml-datasets 桶
DVC 的 S3 remote 同理,把 endpointurl 指过去就行:
dvc remote add -d myremote s3://ml-datasets/dvc
dvc remote modify myremote endpointurl http://localhost:9000
dvc remote modify myremote access_key_id rustfsadmin
dvc remote modify myremote secret_access_key rustfsadmin
关键点:这不是 RustFS 的特殊集成,而是因为它 100% 兼容 S3 API,MLflow/DVC 的 S3 后端按规范就能用。换存储不用改训练代码,只换 endpoint。
3. 开版本控制,给数据集留后悔药
训练数据最怕两件事:一次错误清洗把桶刷了,或者三个月后想复现某个历史实验却找不到当时的数据。RustFS 的对象版本控制(Versioning,已纳入官方兼容性测试门禁)正好管这个:
# 给数据桶开启版本控制
aws --endpoint-url http://localhost:9000 s3api put-bucket-versioning \
--bucket ml-datasets \
--versioning-configuration Status=Enabled
开了之后,每次覆盖同名对象都会保留旧版本,误删也能回退到指定版本。mc cp 一个 --version-id 就能取回历史快照。代价是存储占用会随版本累积,配合下面的生命周期策略自动清冷数据就行。
4. 性能:小文件场景下它为什么能打
官方 beta.10 的 warp 压测里,同样 4×4 盘、同样并发,RustFS 在 4KiB 对象的 PUT 是 MinIO 的 2.00×,4MiB 对象是 2.85×(数据来自 rustfs.com 官方 benchmark 页,工况固定、可复现)。训练数据正好是小文件 + 高并发的典型,这个差距会直接体现在 data loader 的等待时间上。
不过要老实说边界:这个倍数只在"小对象高并发"工况成立,大文件流式写入差距会收窄;而且 RustFS 还在 rc 阶段(1.0.0-rc.x),生产前固定版本、先备份再迁移,别拿 latest 直接上生产。
5. 路线图上的事:S3 Tables 还没来
如果你想要的是"对象存储里直接管 Iceberg 表",得等一等。RustFS 官方数据管理页把 S3 Tables(Parquet + Iceberg,自动小文件合并、专用元数据层加速查询)标为 Coming soon,目前还在路线图。现在能用的是对象级的能力:版本控制、生命周期、对象锁、事件通知都已可用。等 S3 Tables 落地,训练特征表和原始对象就能在同一个存储里统一管理,那时数据湖和 lakehouse 的边界会更模糊。
6. 总结与下一步
AI 训练数据用 S3 兼容对象存储当底座,比堆 NFS/本地盘更顺手;RustFS 100% S3 兼容,MLflow/DVC 换 endpoint 即用。
- 开版本控制给数据集留历史,误删可回退;代价是存储随版本增长,配生命周期清冷数据。
- 小文件高并发是 RustFS 的强项,官方 beta.10 压测 4KiB/4MiB PUT 达 MinIO 的 2.00×/2.85×;工况限定,别外推。
下一步:把第 2 节的 docker run 跑起来,建 ml-datasets 桶,开版本控制,然后改 MLflow 的 MLFLOW_S3_ENDPOINT_URL 指过去,跑一次 mlflow.log_artifact 验证落桶。
以下是深入学习 RustFS 的推荐资源:RustFS
官方文档: RustFS 官方文档- 给出架构、安装指南和 API 参考。
GitHub 仓库: GitHub 仓库 - 获取源代码、提交问题或贡献代码。
社区支持: GitHub Discussions- 与开发者交流经验和解决方案。
意见反馈:GitHub Issues
本次分享就到这里。技术这东西越研究越有意思,后续有新的收获我也会继续更新。
评论 (0)
暂无评论