FEATURED · 精选文章

Open Lustre云上部署:ZFS OST对象存储替代本地磁盘

发布时间 / 2026/8/28 19:52:29
来源 / 创域科博编辑部
栏目 / 资讯中心
Open Lustre云上部署:ZFS OST对象存储替代本地磁盘 这次我们来看一个存储基础设施项目把 Open Lustre 这套老牌并行文件系统搬到云上并且让 OST 不落在本地磁盘而是落在 ZFS 之上、ZFS 再基于对象存储构建。项目标题已经写得很直白Open Lustre in the cloud, with ZFS OSTs on object storage not disks。也就是说过去 Lustre 集群里最贵、最难维护的 OST 数据面现在可以用对象存储替代物理硬盘。这个方向解决的问题很明确云上做 HPC 文件系统时本地 SSD/NVMe 容量有限、成本高而对象存储便宜、弹性大、容量几乎无限但延迟和 IOPS 都不适合直接暴露给 Lustre 客户端。项目给出的思路是用 ZFS 在中间做一层本地缓存和元数据抽象把对象存储包装成 OST 的持久化后端。这篇文章会先把项目的核心架构和适用边界拆清楚再给出一套可以在测试环境验证的部署流程、功能测试方法和排错思路。如果你正在纠结云上并行文件系统怎么选或者好奇 Lustre 能不能和对象存储共存这篇可以直接收藏。1. 核心能力速览能力项说明项目类型云上并行文件系统部署方案基于 Open Lustre ZFS 对象存储核心组件Lustre MGS/MDT、OSS/OST、ZFS、对象存储S3/OSS 等兼容接口数据面存储OST 不直接使用云盘而是由 ZFS 在对象存储之上构建文件系统语义保持 Lustre POSIX 语义客户端仍通过 Lustre 客户端挂载部署位置云主机 / 容器化环境需支持 Lustre 客户端内核模块关键价值降低容量成本获得近似对象存储的弹性扩展能力适用场景大文件顺序读写、高并发聚合带宽、海量数据分层归档、AI 训练数据集共享不适合场景极致低延迟小文件随机 IO、单客户端小型工作负载实测要求具体 IOPS/带宽数据需按实际对象存储网关和网络环境测试不同云厂商差异较大这里要明确一点这不是一个需要显卡的 AI 项目而是一个存储架构方案。它关注的核心指标是IOPS、吞吐带宽、挂载延迟、创建文件速率和容量成本。2. 这个方案到底解决了什么问题2.1 传统 Lustre 的云上尴尬Lustre 设计之初就是给超算集群用的元数据和数据分开管理。客户端通过 Lustre 网络协议访问元数据服务器和对象存储服务器数据在 OST 上分散读写。传统部署里每个 OST 对应一块本地磁盘或 RAID 卷容量和性能被物理盘绑死。到了云上问题立刻出现本地 NVMe 云盘容量有限单盘最大几 TB大规模训练数据集放不下。大容量云盘单价高数据量一上来存储成本迅速超过计算成本。云盘扩容必须挂载、格式化、迁移数据运维繁琐。Lustre 多节点部署OSS 节点故障后 OST 重建很痛苦。对象存储则没有这些问题容量无限扩展、按量计费、跨可用区冗余。但它的接口是 HTTP 对象语义不是 POSIXLustre 客户端没法直接访问而且小文件随机读性能很差。2.2 ZFS 在中间扮演的角色项目思路不是让 Lustre 直接对接对象存储而是先用 ZFS 把对象存储“伪装”成块设备或卷再让 Luster 的 OST 跑在 ZFS 之上。ZFS 在这里至少提供三样东西数据校验和一致性ZFS 有自己的 checksum 机制对象存储底层的位翻转或静默数据损坏可以被发现。缓存能力ZFS ARC 可以用服务器内存做读缓存减少底层对象存储访问。快照和克隆ZFS 快照可以给复杂数据目录提供恢复点这在传统云盘方案里很常用。从架构层级看数据路径变成Lustre Client - MGS/MDT元数据 - OSS - OST - ZFS 卷/文件系统 - 对象存储适配层 - S3/OSS Bucket最终用户访问的还是 Lustre 文件系统但底层容量来自对象存储。2.3 与 CephFS、JuiceFS 的区别很多读者会想到 CephFS 或 JuiceFS 这类分布式文件系统。区别在于这个方案保留了完整 Lustre 协议栈对于已经使用 Lustre 的 HPC 用户客户端兼容性最好。只要部署一套新的 MGS/MDT/OSS客户端挂载方式和命令几乎不变。而 CephFS 或 JuiceFS 需要换客户端访问方式应用侧和运维习惯都要改变。如果只做数据共享、不追求 Lustre 兼容那 JuiceFS 这类方案可能更简单但如果企业已有 Lustre 作业调度、配额管理、客户端调优体系这个方向的价值就大不少。3. 适用场景与使用边界3.1 适合什么场景HPC 作业共享目录。 多个计算节点要同时读写同一份数据带宽要求高、单节点容量要求一般。AI 训练数据集共享。 训练节点多数据集大希望所有节点看到同一个挂载点避免每节点拷贝一遍。冷热数据分层。 热数据放本地 ZFS 缓存冷数据沉到对象存储降低归档成本。云上渲染农场。 渲染节点多读帧数据、写结果文件顺序吞吐需求优于随机 IO。3.2 不适合什么场景小文件密集随机访问。 对象存储请求延迟普遍在几十毫秒以上即使加 ZFS 缓存冷数据命中率低时性能会很差。单节点小规模使用。 数据量只有几百 GB直接云盘或托管 NAS 更省事不需要引入 Lustre 这套复杂度。对延迟极度敏感的数据库类负载。 这种场景应该用本地 NVMe 或云厂商提供的低延迟文件存储对象存储路径太长。3.3 使用边界对象存储按请求数计费Lustre 元数据操作如果全部穿透到对象存储费用可能很高。所以这个方案必须依赖 ZFS ARC 或额外缓存层来吸收高频读请求。部署前要评估工作负载的读写比例、小文件占比、缓存命中率预期。另外任何文件系统方案都要明确数据安全边界。对象存储可能跨地域复制如果数据涉及内部代码、用户隐私或非公开模型权重需要确认桶的访问策略、加密和生命周期规则。测试环境可以放开生产环境必须做双层权限控制。4. 环境准备与前置条件4.1 操作系统与内核Lustre 客户端依赖内核模块一般建议使用社区维护的 Lustre client 包对应内核版本。官方 Open Lustre 版本对内核有明确支持范围测试前先确认# 查看内核版本 uname -r如果内核版本过新Lustre 客户端模块可能无法加载。稳妥做法是选择一个长期支持版本内核再安装匹配的 lustre-client 包。4.2 服务端组件部署最低需要1 台元数据服务器MGS/MDT可以共用一个节点。至少 1 台 OSS 节点承载 OST。Lustre 网络LNet需要 TCP 互联云上直接用内网 IP。对象存储 Bucket 及 Access Key / Secret Key。ZFS 用户态工具和内核模块。服务端推荐 Ubuntu/Debian 或兼容 EL 的发行版。ZFS 模块和 Lustre 模块可能共用内核编译前要确认内核头文件已安装。4.3 网络规划Lustre 数据面网络建议独立 VPC 子网所有节点之间开高带宽。对象存储访问走云厂商内网网关避免外网流量费。如果对象存储网关在另一地域延迟会明显放大不建议跨地域。4.4 准备验证脚本把下面的脚本保存成env_check.sh用于快速检查环境是否满足基本条件#!/bin/bash echo kernel uname -r echo lustre client which mount.lustre || echo no mount.lustre modinfo lustre /dev/null 21 echo lustre module ok || echo no lustre module echo zfs which zfs || echo no zfs zfs version 2/dev/null || echo no zfs version info echo object storage tools which aws || echo no aws cli which s3cmd || echo no s3cmd echo network ip -brief addr这只是通用模板实际项目如果提供独立安装脚本应优先使用项目自带脚本。5. 安装部署与启动方式下面给出的是通用部署流程适用于在云主机上手动搭建测试环境。实际项目如果提供 Docker Compose 或一键脚本以项目文档为准。5.1 安装 ZFS# Ubuntu/Debian 示例具体包名按发行版调整 sudo apt update sudo apt install -y zfsutils-linux sudo modprobe zfs zfs version5.2 安装 Lustre 服务端和客户端Lustre 服务端和客户端需要在不同环节安装客户端要确保内核模块能加载# 编译客户端模块示例实际需要下载对应内核源码的 lustre 源码 # ./configure --disable-server --enable-client # make -j$(nproc) # make install # modprobe lustre生产环境更推荐直接用发行版对应的预编译 lustre-client 包避免从源码编译遇到内核 API 变化。5.3 配置 MGS/MDT在一台节点上初始化元数据存储# 示例命令参数中的设备名和索引需要按实际环境替换 mkfs.lustre --fsnamelustre --mgs --mdt --index0 /dev/zvol/myvol/mdt mkdir -p /mnt/mdt mount -t lustre /dev/zvol/myvol/mdt /mnt/mdt这段命令假设 ZFS zvol 已经创建好。如果项目走的是对象存储模拟块设备MDT 也可能直接放在对象存储卷上需要按照实际支持情况调整。5.4 配置 OSS/OSTOST 节点上把对象存储通过 ZFS 做底层卷然后格式化为 OST# 先创建 zvol 或 ZFS 数据集大小对应对象存储容量 # zfs create -V 10T zpool/ost0 mkfs.lustre --fsnamelustre --ost --index0 /dev/zvol/zpool/ost0 mkdir -p /mnt/ost0 mount -t lustre /dev/zvol/zpool/ost0 /mnt/ost0关键点在于/dev/zvol/zpool/ost0这个块设备的实际数据后端是对象存储。这通常由一个用户态块桥接服务完成它把块设备请求转换成 S3/OSS 对象请求。这个服务需要单独启动并保持运行否则 ZFS 无法正常读写底层数据。5.5 启动 LNetLustre 网络层也需要配置modprobe lnet # 配置 LNet监听内网 IP lctl network configure # 查看网络状态 lctl list_nids不同版本 LNet 配置方式有变化新版本用 YAML 描述net: - net type: tcp0 local NI(s): - interfaces: eth0保存为lnet.conf启动时加载即可。5.6 客户端挂载mkdir -p /mnt/lustre mount -t lustre 10.0.0.10tcp0:/lustre /mnt/lustre df -h /mnt/lustre如果挂载成功df -h能看到文件系统容量。容量应该和对象存储卷大小匹配而不是本地磁盘大小。6. 功能测试与效果验证这个环节是验证方案能不能用的关键。无论架构多复杂最终用户感知就是挂载点能不能读写、数据能不能持久、创建文件快不快。6.1 基础读写测试# 写入一个大文件 dd if/dev/zero of/mnt/lustre/test.bin bs1M count2048 oflagdirect statusprogress sync # 读取并校验 dd if/mnt/lustre/test.bin of/dev/null bs1M count2048 iflagdirect statusprogress # 检查文件大小 ls -lh /mnt/lustre/test.bin判断标准写入完成后文件大小正确。读取能完整读到末尾无 I/O error。直接 IO 绕过本地缓存能更好反映底层对象存储性能。6.2 文件创建与删除测试Lustre 元数据性能一直是重点小文件创建速率尤其敏感time for i in $(seq 1 1000); do touch /mnt/lustre/small_$i; done ls /mnt/lustre | wc -l time rm -f /mnt/lustre/small_*如果创建 1000 个空文件耗时几十秒甚至更久说明元数据操作穿透到了对象存储性能不理想。正确做法是让 MDT 保留在本地高速存储只有 OST 数据落到对象存储。6.3 OST 分布检查Lustre 会把文件条带化到多个 OST用lfs命令查看# 查看 OST 列表和容量 lfs df /mnt/lustre # 查看某个文件的 OST 分布 lfs getstripe /mnt/lustre/test.bin # 检查文件条带数 lfs getstripe -d /mnt/lustre/test.bin如果只有一个 OST大文件并发带宽会受限。测试时可以强制设置条带数观察多 OST 聚合带宽lfs setstripe -c 2 /mnt/lustre/test_striped.bin dd if/dev/zero of/mnt/lustre/test_striped.bin bs1M count2048 statusprogress6.4 并发读写测试多客户端并发场景可以用fio验证# 通用 fio 测试模板 fio --nameseq-read \ --filename/mnt/lustre/fio_read \ --rwread \ --bs1M \ --size4G \ --numjobs4 \ --direct1 \ --group_reportingfio 参数说明--bs1M大块顺序读贴近 HPC 和 AI 训练场景。--numjobs4模拟 4 个客户端并发。--direct1绕过页缓存。--size4G每个作业读写 4G。结果关注aggrb聚合带宽如果远低于对象存储标称带宽优先排查网络链路或 ZFS 缓存配置。6.5 持久性测试对象存储容量是弹性的但数据要保证重启后还在。测试时把节点重启重新挂载 OST再检查文件是否完整mount -t lustre /dev/zvol/zpool/ost0 /mnt/ost0 mount -t lustre 10.0.0.10tcp0:/lustre /mnt/lustre cat /mnt/lustre/test.bin /dev/null echo persist ok这一步很关键因为对象存储适配层的块映射如果没做好重启后就可能出现数据读不出来或目录结构损坏。7. 接口 API 与批量任务适配Lustre 本身不提供 REST API但可以作为批量任务的数据共享层。如果你有大数据或 AI 训练批量任务可以这样设计计算节点统一挂载同一 Lustre 文件系统。批量任务把输入数据放到/mnt/lustre/jobs/{jobid}/input。任务结束后输出到/mnt/lustre/jobs/{jobid}/output。用lfs setstripe为大文件目录设置更高条带数提升并发吞吐。用 ZFS 快照给目录做版本备份。Python 示例批量任务写共享目录import os import subprocess import uuid mount_point /mnt/lustre/jobs job_id uuid.uuid4().hex input_dir os.path.join(mount_point, job_id, input) output_dir os.path.join(mount_point, job_id, output) os.makedirs(input_dir, exist_okTrue) os.makedirs(output_dir, exist_okTrue) # 这里是模拟任务写入实际场景中替换为你的训练/渲染逻辑 with open(os.path.join(input_dir, config.json), w) as f: f.write({epochs: 10}) # 任务完成后读取共享目录中的结果 subprocess.run([ls, -lh, output_dir], checkTrue)这里要强调批量任务的失败重试要放在应用层。Lustre 和对象存储的组合如果出现短时网络波动任务可以重新读取文件但文件系统本身不会替你做断点续传。8. 资源占用与性能观察8.1 观察什么部署完成后需要持续观察四个层面节点 CPUZFS 校验和、对象存储适配层转换都会吃 CPU。内存ZFS ARC 默认会占用大量内存做缓存如果机器内存有限要限制 ARC 大小。网络内网带宽是否打满对象存储网关请求是否触发限流。对象存储请求数高频 PUT/GET 会产生费用要关注请求账单。8.2 常见性能瓶颈性能瓶颈表现优化方向小文件随机读慢客户端 ls 慢、小文件读取延迟高确保 MDT 在本地高速盘扩大 ZFS ARC对象存储加 CDN 或前端缓存网关对象存储请求限流带宽突然掉到很低降低并发、增大请求体、开启对象存储网关的突发能力ZFS ARC 不足重复读文件仍然慢调大zfs_arc_max但注意留出系统内存LNet 线程瓶颈多客户端并发时单节点带宽上不去增加 NI 通道数调大 LNet 路由配置条带数过低大文件读写只能打满一个 OST对大目录设置更高条带数8.3 降低资源占用的建议# 限制 ZFS ARC 最大占用单位是字节 echo 4294967296 /sys/module/zfs/parameters/zfs_arc_max4GB 限制适合 16GB 内存的小节点生产环境根据数据热度和可用内存调整。注意这个参数不能超过物理内存否则系统会 OOM。8.4 避免端口冲突和进程残留Lustre 服务端端口和 LNet 端口容易冲突。排查时先看监听端口ss -tlnp | grep lnet ss -tlnp | grep lustre如果节点上已有其他服务占用相同端口可以修改 LNet 配置指定监听 IP 和端口范围。停服务时先卸载文件系统再停 LNet顺序反了容易残留挂载点umount /mnt/lustre umount /mnt/ost0 lctl network unconfigure9. 常见问题与排查方法问题现象可能原因排查方式解决方案挂载时报Connection refusedLNet 未启动或 IP 不对lctl list_nids确认服务器 NID重新配置 LNet确认客户端和服务端网络互通挂载成功后df -h卡住MDT 或 OST 未全部恢复服务端执行lfs df查看 OST 状态确认所有 OSS 节点已挂载 OST写文件时报Out of spaceOST 容量不足或对象存储桶容量配额已满lfs df -h查看 OST 容量扩展对象存储桶容量或增加 OST写入速度很低对象存储网关限流、ZFS ARC 命中率低、条带数不足查看网络吞吐和对象存储监控提高条带数、优化缓存、检查网关并发限制重启后数据无法读取对象存储适配层映射未持久化或 ZFS 池未导入查看 ZFS 状态zpool status重新导入 ZFS 池检查适配层日志客户端模块加载失败内核版本与 Lustre 客户端模块不匹配查看dmesg | tail切换到支持的内核版本重新编译模块mkfs.lustre失败设备名不对或 ZFS zvol 未创建执行ls /dev/zvol先创建 ZFS zvol再格式化对象存储认证失败Access Key 或 Bucket 配置错误手动用aws s3 ls测试桶访问核对密钥和桶地域检查桶策略元数据操作极慢MDT 数据落在对象存储上而不是本地盘检查 MDT 挂载位置把 MDT 迁移到本地 NVMe/云盘排查时第一件事永远是看日志。Lustre 服务端日志通常在/var/log/lustreZFS 错误看zpool status对象存储适配层看自定义服务日志。日志是判断问题段的最可靠依据比猜配置靠谱得多。10. 最佳实践与使用建议把方案跑通只是第一步生产上能不能长期稳定运行取决于几个工程细节。10.1 目录结构规划建议把不同 IO 模式的数据分区管理/mnt/lustre/project # 项目共享数据默认条带 /mnt/lustre/scratch # 临时计算数据高条带、低冗余 /mnt/lustre/archive # 归档数据低条带、强调持久 /mnt/lustre/datasets # AI 训练数据集只读热点数据重点做缓存这样每个目录可以设置不同条带数、同步策略和备份周期避免一套参数用到底。10.2 缓存设计对象存储后端最怕热点随机访问。生产环境建议在 OSS 节点配置足够内存给 ZFS ARC。热点数据集用lfs setstripe -c 1或预取脚本预热到缓存。如果预算允许在 ZFS 前面再加一层本地 NVMe 缓存设备把热数据尽量留在节点本地。10.3 数据备份与快照对象存储不等于无限可靠桶的版本管理和跨区域复制需要单独配置。ZFS 快照可以用于逻辑错误恢复但不能替代跨区域备份# ZFS 快照示例 zfs snapshot zpool/ost0snap-$(date %Y%m%d-%H%M%S) zfs list -t snapshot10.4 安全与合规这个方案涉及多节点文件共享和对象存储访问必须注意对象存储桶的访问密钥不能明文写在配置里要用云厂商的密钥管理服务。Lustre 挂载点如果暴露到非信任网络要配置防火墙规则只允许计算节点网段访问。如果共享目录里包含用户隐私、代码仓库或模型权重需要配置配额和审计日志避免误删除或越权读取。如果后续把你的声音克隆、人脸生成、数字人素材或版权资料放在这个文件系统上必须确保这些素材有明确授权否则不能随便共享给多人使用。10.5 升级与回滚不要在生产环境直接升级 ZFS 或 Lustre 核心包。先在测试节点完整验证一遍再批量升级。每次变更前用 ZFS 快照打点回滚时直接回滚快照比重新搭环境快得多zfs rollback zpool/ost0before-upgrade11. 总结与下一步这个 Open Lustre ZFS 对象存储的方案最值得尝试的一点是它在不影响 Lustre 客户端语义的前提下把容量成本转移到了对象存储。对已经存在 Lustre 经验、又想上云的团队来说这是一条值得从 PoC 开始验证的路径。建议先验证三件事对象存储通过 ZFS 包装后大文件顺序读写带宽能否满足训练或 HPC 作业需求。大批量小文件创建时元数据路径是否会把对象存储请求打爆。节点重启后ZFS 池和 OST 能否自动恢复挂载数据是否完整。最容易踩的坑是元数据存储位置和缓存占比。MDT 一定要放在本地高速盘上ZFS ARC 一定要根据机器内存合理配置否则你看到的所有性能问题都会归咎于对象存储而实际是缓存和元数据路径设计不合理。后续可以继续扩展的方向包括Lustre 多 OSS 节点横向扩容测试、ZFS 快照与对象存储生命周期管理联动、客户端高并发 fio 压测、以及把这套文件系统接入 Kubernetes CSI 驱动让容器工作负载直接使用并行文件系统。如果准备在云上试跑建议先用最小三节点拓扑一个 MGS/MDT 节点、一个 OSS 节点、一个客户端节点。跑通基础读写后再逐步加 OSS 节点和条带数不要一开始就追求多节点复杂拓扑那是排障阶段最难受的配置。
RELATED — 相关阅读

相关资讯

LATEST — 最新资讯

最新发布

TODAY — 本日精选

新闻

WEEKLY — 本周精选

新闻

MONTHLY — 本月精选

新闻