十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Lustre 对象存储化:ZFS OST 架构解析与性能边界

Lustre 对象存储化:ZFS OST 架构解析与性能边界 Open Lustre 跑在云上把 ZFS OST 直接放到对象存储而不是磁盘上——这个思路在 Show HN 上出现后讨论最集中的并不是 Lustre 本身怎么部署而是对象存储的延迟和一致性能不能扛住文件系统底层这层随机读写。它解决的问题很实际云上跑并行文件系统容量层太贵扩容太慢。传统 Lustre 的 OST 背后是本地磁盘或云盘数据量和节点绑死改成对象存储之后容量不再受磁盘限制存储单价也能压到对象存储的档位。这篇文章拆三部分先看懂存储链路到底改在哪再说明复现需要什么条件和验证方式最后给出性能边界和排查顺序。适合看的人要搭云上 HPC 存储、渲染农场、AI 训练数据集共享的工程师以及跑过 Lustre、想降低数据层成本的运维团队。1. 先看懂这个方案到底改的是哪一段1.1 Lustre 在云上跑成本大头就在数据盘Lustre 是传统 HPC 领域最常见的并行文件系统逻辑上分三块MGS/MGT 管全局配置MDS/MDT 管目录、文件名和权限这些元数据OSS/OST 管真正的文件数据。客户端通过 Lustre 网络挂载之后读写数据直接打到 OST。传统部署里OST 下面是本地磁盘或者 SAN 盘云上就是云盘。问题在于云盘是按容量预付费的你规划了 300TB就算只写了 100TB另外 200TB 也照样收钱。而 Lustre 扩容不是简单加一块盘就完事往往要新建 OST、调整条带、迁移数据过程中文件系统可能要停写或者降级。对很多云上业务来说这个成本和时间窗口都很难接受。这个方案改的是最底层这一段OST 不再需要一块真实的磁盘而是把数据落到对象存储上。OSS 节点本身只保留计算和缓存能力容量交给 bucket 去撑。这样容量规划、扩容方式、单价构成全部变了。1.2 为什么专门挑 ZFS而不是直接用 ldiskfsLustre 的 OST 后端可以选 ldiskfs也可以选 ZFS。项目标题特意强调 ZFS不是因为 ZFS 更“高级”而是因为对象存储缺几样东西需要 ZFS 补上。ZFS 写入时会计算校验和读取时会校验数据块损坏的数据能被发现。这一步在对象存储方案里尤其重要。对象存储服务端通常有自己的冗余和完整性保护但客户端到服务端之间的端到端完整性校验仍然需要文件系统自己做。ZFS 的另一个好处是压缩。HPC、科学计算、日志、模型权重这类数据压缩率不低写入对象存储之前先压缩容量和请求费用都能省。还有快照。ZFS 快照对长期运行的共享文件系统是重要的保护手段实验前拍一个配置坏了可以直接回滚。这些能力在“对象存储 裸块”的组合里根本不存在必须有 ZFS 这一层兜住。另外用过 ZFS 的人都知道本地盘场景里经常听到“不要用 RAID 卡要让 ZFS 直通磁盘”的说法。这个项目等于把问题换了个方向对象存储能不能当一个延迟较高的虚拟磁盘让 ZFS 在它上面继续按自己的逻辑管理容量。1.3 数据链路从两层变成了五层理解这套方案的关键是看数据从客户端到最终落盘走了几层客户端 - Lustre OSS 进程 - ZFS 文件系统 - 块或文件映射层 - 对象存储 bucket每一层都可能成为瓶颈或故障点。Lustre 管分布式锁和条带ZFS 管缓存、压缩、校验映射层决定对象存储对象和本地块之间的对应关系对象存储负责最终容量和持久性。传统磁盘方案里ZFS 直接管理磁盘块中间没有映射层。换成对象存储之后这一层就成了整个方案最不确定的地方。它可能是 FUSE 文件系统桥接可能是块设备网关也可能是自定义的 NBD 服务。项目标题只说“not disks”没透露桥接层怎么做落地的时候这一层必须自己补清楚否则讨论 Lustre 参数没有意义。2. 为什么有人愿意把 OST 放到对象存储上2.1 容量单价便宜但账单构成变了如果只看存储容量单价对象存储通常比云盘便宜不少。一个 100TB 的共享池云盘方案每个月要按全部容量计费对象存储则按实际写入量计费而且可以转低频档归档冷数据。但账单构成完全不一样。对象存储的“便宜”只算容量读写都是额外计费的GET、PUT、LIST 请求有单价出网流量也要钱。如果业务是每天写几千万个小文件或者频繁做目录扫描请求费用会迅速把容量省下的钱吃回去最后总成本反而可能更高。所以判断值不值不能只看 GB 单价要先把自己的读写模式算清楚。大文件顺序写、低频读的场景成本模型非常友好高频小文件随机写的场景大概率不划算。2.2 数据与节点解耦扩容思路完全不一样云盘方案最大的问题不是单价而是容量规划和节点绑定。业务从 50TB 涨到 200TB传统做法可能要加多个 OSS 节点、新建多个 OST然后把旧数据重新平衡一遍。对象存储方案里容量上限看起来是“无限”的OSS 节点只承担缓存和转发数据增长时直接增加 OSS 节点即可不需要迁移旧数据。这个特性对突发负载特别有价值。渲染农场、科学计算、AI 训练峰值的时候读多写少平时负载很低OSS 节点可以缩到很小数据仍然完整留在对象存储里。数据与节点解耦是传统 Lustre 部署给不了的弹性。2.3 先从负载类型判断值不值得试适合这个方案的负载大文件顺序写比如 checkpoint、科学计算数据、模型权重。读多写少比如把数据集做成共享池让多个计算节点读取。容量大但访问频率低比如归档、旧数据集、日志保留。不适合的负载高并发小文件随机读写元数据和请求费用会双重爆炸。强一致、事务型写入对象存储的语义不适合数据库类负载。要求亚毫秒延迟的场景任何经过对象存储的读写物理上都很难低于几十毫秒。这里要特别提醒Lustre 的条带能力解决的是“一个大文件被多台机器并行读写”不是“大量小文件随机 IO”。对象存储方案会把小文件问题放大所以筛选负载时要先看文件大小和访问模式。3. 复现之前先确认四件前置条件3.1 对象存储必须 S3 兼容一致性先做一次实测建议优先选 S3 兼容 API 的对象存储这样后续工具链最完整。AWS S3 现在已经是强一致但很多自建对象存储或者部分云厂商的兼容实现仍然可能是最终一致。最终一致意味着一个 OST 块刚写入立刻读可能读到旧内容。ZFS 对底层异常非常敏感底层设备返回不一致的数据ZFS 会认为磁盘损坏甚至把 pool 置为降级状态。动手之前先做一个最小一致性测试用客户端往同一个 prefix 写一个对象立即读连续多轮确认是否每次都读到新数据。如果发现不一致这个方案基本可以先放弃除非在桥接层做额外的同步确认但那样性能会明显下降。3.2 最小节点拓扑和网络规格最小环境建议至少两个节点管理加元数据节点MGS/MDS 放同一台跑 MGT 和 MDT。OSS 节点一个或多个每个节点可以承担多个 OST。对象存储和计算节点如果属于同一个云厂商一定要走内网 endpoint别走公网。公网流量既慢又贵。网络带宽按聚合吞吐估算如果希望客户端能跑到 10GB/sOSS 节点到对象存储的内网带宽必须能打出这个速率而且不能和外部业务共享同一个带宽池。3.3 Lustre、ZFS、内核三者的版本矩阵Lustre 的内核模块必须和当前内核严格匹配ZFS 又要和 Lustre 的编译版本匹配。原始材料没有给出明确版本所以建议先围着一个已验证过的组合做Lustre 使用发行版仓库里的包或者官方支持的内核不要自己编译一个特别新的内核再接旧模块。ZFS 选择 Lustre 文档里列出的兼容版本。先在单节点虚拟机里把三者组合测试通过再上多节点。这个版本矩阵一旦固定尽量少动。对象存储桥接层、ZFS 工具、Lustre 客户端之间的版本经常出现“单独看都正常合起来就报错”的情况。3.4 本地缓存盘是必需品不是可选项如果 OSS 节点完全没有本地 SSD 或 NVMe 盘做缓存所有读写都直接穿透到对象存储延迟和请求费用都会非常难看。所以节点上至少要留一块本地盘给 ZFS ARC 或二级缓存热数据尽量留在本地。缓存盘的大小没有标准答案但可以先按业务热数据量的 5% 到 10% 规划。缓存命中率高这套架构才有实用价值缓存命中率低方案基本就是花着 Lustre 的复杂度拿对象存储的延迟。4. 一条可执行的落地路径从对象存储到 Lustre 挂载4.1 对象存储怎么变成 ZFS 能用的底层存储这是整个方案里最关键的选型。我见到过的做法大致分三类文件级桥接用 s3fs、rclone、ossfs 这类工具把 bucket 挂载成目录然后在目录里创建文件把文件作为 ZFS 的 file vdev。块级桥接用 s3backer 这类工具把 bucket 映射成块设备ZFS 直接使用这个块设备。自定义网关用 NBD 或内核模块把对象存储暴露成网络块设备带本地缓存和写回队列。三种方式的复杂度、稳定性和性能差异很大。文件级桥接最直观但 FUSE 文件系统一旦断线ZFS 会认为底层设备 IO 错误pool 可能被导出恢复时很麻烦。块级桥接要处理块大小对齐和缓存策略。自定义网关效果最好但开发量也最大。我不在这里替你选。建议先拿最小样例分别测一遍启动、断线、重连哪个行为最符合预期再用它往下走。跳过这一步直接配 Lustre后面会花更多时间排障。4.2 ZFS 池和数据集创建示意假设底层桥接层已经准备好ZFS 这一步可以按常规流程处理# 创建 zpool底层设备是对象存储映射出来的块设备或文件 zpool create lustre_pool /dev/mapper/objstore_dev # 设置缓存文件避免重启后找不到 pool zpool set cachefile/etc/zfs/zpool.cache lustre_pool # 创建用于 OST 的 ZFS dataset打开压缩 zfs create -o compressionlz4 lustre_pool/ost0这里注意如果底层是对象存储压缩建议打开省下的是对象存储容量和请求次数。但校验和缓存参数要根据真实延迟调整不要盲目开很多 ZFS feature。如果底层桥接设备延迟已经很高ZFS 的同步写日志会变成灾难这时要么改用异步写语义要么在桥接层做好本地写缓存。4.3 MGT/MDT/OST 配置和客户端挂载Lustre 部分的命令大致是这样# 管理目标MGS 和 MGT 通常放一起 mkfs.lustre --mgs --backfstypezfs --reformat lustre_pool/mgt # 元数据目标 mkfs.lustre --mdt --backfstypezfs --mgsnode10.0.0.2tcp0 \ --index0 lustre_pool/mdt0 # 对象存储目标 mkfs.lustre --ost --backfstypezfs --mgsnode10.0.0.2tcp0 \ --index0 lustre_pool/ost0 # 启动目标 mount -t lustre lustre_pool/ost0 /mnt/ost0这些都是示意命令实际参数要以你确认的 Lustre/ZFS 版本为准。配置里的 NID、文件系统名、索引号必须统一否则客户端挂载时找不到目标。客户端挂载mount -t lustre 10.0.0.2tcp0:/lustre /mnt/lustre挂载成功之后先不要跑大任务先做最基本的目录创建、文件写入、读取、删除验证。4.4 第一轮验证只看四个指标新环境第一次跑通我会只看四个东西挂载是否成功lfs df能看到 OST 和 MDT 状态。顺序写吞吐写一个 10GB 文件看速率是否达到对象存储并发写入的合理水平。小文件操作创建和删除 1000 个 1KB 文件看完成时间和延迟。断线恢复把对象存储 endpoint 暂时停掉或断网观察 Lustre 客户端和 ZFS pool 是等待、报错还是直接挂起。断线恢复这个测试很多人会跳过但在这套架构里必须做。对象存储是外部依赖任何一次网络抖动都会传导到 ZFS 和 Lustre 的 IO 栈上。如果不能优雅降级这个方案就只能停在实验阶段。5. 性能预期和边界别拿对象存储对标本地盘5.1 用一张表直接看差异本地云盘方案的延迟是亚毫秒到几毫秒对象存储单次请求延迟通常在 20ms 到 100ms 以上。ZFS 缓存可以弥合一部分但冷数据首次读取、随机写、元数据更新是躲不过去的。维度本地盘或云盘 OST对象存储 OST带本地缓存单次操作延迟亚毫秒到几毫秒几十毫秒依赖缓存命中顺序读写吞吐高受磁盘和网络限制可接近网络上限靠并发打满小文件 IOPS中到高低元数据和请求费用双高
返回列表