去年因为做了个数据量比较大的项目,外加各种模型权重、数据集越来越多,患上了存储空间焦虑症。年底的时候回国扛了一台绿联的 DXP6800Pro ,外加 6 个西数 16T 二手企业盘和 2 个 2T 的致钛 Ti600 的 SSD 到办公室,现在不焦虑存储空间了,但有点纠结怎么用好这个 NAS 。网上搜索+问了问 ChatGPT ,并没有在方案设计上找到什么有建设性的答案。
目前的状态 刷了 Debian12 ,6 个 HDD 用 ZFS 组了个 RaidZ2 ,两个 SSD 做镜像后现在是 ZFS 的 LOG 。本意是想加速一下写入,但似乎并没有起到太大的作用。我自己还搞了个万兆交换机,配合手动配置 IP ,让电脑和 NAS 之间通过万兆局域网连接,平时会通过一个跑在 podman 里的 samba 挂载到(Windows 和 Linux 都有)电脑上。Samba 开了个共享账号给周围的同事用,自己有一个单独的 Samba 账号。本来还搭了个 Aria2 ,但因为 podman 容器里挂载目录的权限问题比 docker 要复杂一些,所以还没跑通。
总结来说,现在的 NAS 用起来有以下几个痛点
鄙人的核心诉求大概如下(重要性从高到低)
如果可以,我希望达到这样一个效果
为了达到这样一个效果,我调研到了下面几个结论
基于以上结论和一些来自 ChatGPT 的建议,我得到了目前以下几个关于存储规划的方案
在应用规划上,目前的 Samba 方案暂时没有找到合适的替代;考虑过利用 Nextcloud 实现 WebDav ,但其本身的性能实在堪忧,所以暂时没有用上。
其他一些补充和 Q&A
目前的问题
在此感谢社区内的诸位,祝大家春节愉快,阖家欢洛!
![]() |
1
iBugOne 10 天前 ![]() 作为一位将楼主提到的方案和技术全部摸过的普通 V2EX 用户,我的看法是:
> 不要纠结太多,不要有“一定要把这个那个的性能和带宽都跑满”的想法,否则因为木桶效应的存在,你总是会陷入不断升级每个部件的循环中(直到所有部件的性能都严重过剩)。 [关于连续读写性能] 由于所有数据最终都是存储在 HDD 阵列上的,尤其是大量连续读写的数据,因此 HDD 阵列的性能决定了“任意资料”(尤其是冷资料)的读取性能。如果你真的想跑满万兆网络,请增加 HDD 到至少 8 块(假设你使用 RAID-Z2 ,此时有 6 块数据盘,按单盘 200 MB/s 的速度估计,可以达到 1200 MB/s )。 [关于随机读写性能] 请扔掉 SSD ,你不需要把它利用起来,否则只会起反作用。给你的 NAS 加更多的内存用于 ZFS ARC 。 根据 USTC 镜像站的数据 [1],对于冷热分明的数据,ZFS ARC 能够提供足够好的命中率,而 L2ARC 仅有不到 1/3 的命中率。结合“ARC 命中率足够高”这一点,根据 Amdahl 定律,考虑到 L2ARC 还会占用 ARC 来维护它自己的 metadata ,盲目使用 L2ARC 并不能带来更好的性能,不如节约下来 SSD 的寿命做点别的,哪怕只是用作系统盘( rootfs )。 对于冷数据,我不认为任何文件系统能够处理好这种情况,除非你上全闪(显然钱包不会很开心),没有必要也不应该考虑冷数据随机读取的性能,而 ZFS 由于它的日志式设计,可以将随机写 buffer 起来转换成顺序写 [6],因此你也没有必要使用 SLOG [7][8]( NAS 应该不会有 O_SYNC 写入吧)或者考虑任何形式的 SSD 作写缓存的用法。 [关于 ZFS] 对于 NAS 这种场景,你需要适当调节 ZFS 的参数,具体可以参考链接 [1](镜像站就是一个巨大号的 NAS ,该文章所提及的大部分参数在这里同样适用),减少碎片率和 HDD 的 I/O 次数,以及增加分配给 ARC 的内存量(没错,这个建议归根结底还是“加内存”)。 [关于 LVM] 建议扔了不要用,你已经在用 ZFS 了,没有任何必要使用 LVM 和 LVMCache 。LVMCache 的性能很差(见 [1] 的截图)并且算法很原始 [1];而 ZFS 的 ARC 是一个非常先进的、自动调节的算法 [2](只是需要更多内存)。同时 LVMCache 有各种大大小小的坑,尤其是 writeback 模式下 [3],甚至还会把 GRUB 搞糊涂 [4],我们为此花费了不少精力去调查研究,并且自己 patch 代码 [4] 解决或者只是绕过这些问题。相信你没有抖 M 到这个程度( 且不说 ZFS 无论如何不应该跑在其他形式的 RAID 或缓存机制上 [5],有了 ZFS ,你也没有任何必要再在上面套一层 LVMCache (同理,这也会让你失去 ZFS 的一大半高级特性和性能优化)。 [其他] 「如果哪个硬盘坏了,我能有个办法及时知道」→ 你需要的是基于硬盘 SMART 信息的报警功能,请自行调研 smartd ( apt install smartmontools )的报警功能。 「很多人不推荐 writeback 缓存策略是因为」→ 见上,我有另一批完全不同的理由不推荐 LVMCache 。 [关于更换方案] 个人推荐你换掉那个小的、CPU 性能差、内存容量少的定制 NAS 主机,而是重新搭一个台式机,可以用更好的 CPU ( 7950X / 9950X + X870 / X870E 等,甚至选用带 IPMI 的主板,不过预算可能压不住),配更好的电源和更好的机箱(便宜:半岛铁盒 F20 ;结实牢固、设计合理:分型工艺 Define 7 XL ),这些看似周边的部件反而是一个更可靠的 NAS 的基础。 软件方面我没有任何想法,自己在 Ubuntu 上把(自认为能折腾的)都折腾过了,建议以个人熟悉的软件栈为主。 [结论] 整体性能够用就好,点到为止,不要盲目追求极限。 [最后] 以上全部思考来自我自己搭建和管理服务器的亲身经历。 [最后的最后] 打了这么多字,给点个“感谢”送点铜币吧(暴露了,其实我是来骗铜币的)。祝楼主和其他 V 友春节愉快,阖家欢洛! [参考资料] [1]: https://lug.ustc.edu.cn/planet/2024/12/ustc-mirrors-zfs-rebuild/#mirrors4 [2]: https://www.usenix.org/conference/fast-03/arc-self-tuning-low-overhead-replacement-cache [3]: https://docs.ustclug.org/services/mirrors/4/volumes-old/#ssd [4]: https://github.com/taoky/grub/commit/85b260baec91aa4f7db85d7592f6be92d549a0ae [5]: https://serverfault.com/q/545252/450575 [6]: https://ibug.io/p/62 (我的博客) [7]: https://superuser.com/q/1428707/688600 [8]: https://openzfs.github.io/openzfs-docs/Performance%20and%20Tuning/Workload%20Tuning.html (注:以上链接中 1, 3, 6 均是我写的,或者我参与编写/校对的) |
2
eric107008 OP @iBugOne 昨天还在拜读 [201.ustclug]( https://201.ustclug.org) 中关于 ZFS 和 LVM 相关文章,在这儿遇见 iBug 本尊有种教科书里的人物跑到了现实中的既视感,非常亦可赛艇 [鞠躬]
我确实深入考虑了你说的全 HDD ZFS 方案,也研读过 UTSC 镜像站相关的许多内容(如前面提到的 201 )。目前来说仍然在进行思想斗争主要是这台 NAS 的使用场景与镜像站有着较大不同。我看到镜像站相关的很多文章讨论的是“读取的时候尽可能减小存储设备负担”的问题,因为镜像站的使用场景似乎是“少量且确定的写”(镜像站通常会有计划地进行同步)+“大量且随机的读”(没人知道哪个 PCDN 什么时候开始刷流),这时候 ZFS 针对读操作的优化就显得非常有用。同时,镜像站使用的是内存更大,CPU 性能更强的专业服务器硬件,有充足的内存资源支持 ZFS 的 ARC 缓存。在镜像站的使用场景下,ARC 的作用被非常充分地发挥了出来。相比之下,这台 NAS 面向的场景是日常工作过程中的数据存储。通常的使用场景是,为了某个明天打算跑训练的模型,把某个数据集下载下来,稍微做一些预处理,训练的时候写个 data loader 从 NAS 上读取数据。其通常会面对的是支持大量耗时且高 IO 的数据处理过程中工作站上的 SSD 装不下那么多数据的问题。 从这个角度来说,最理想的情况是,某种我不知道的东西可以“预约”SSD ,同时让 NAS 自己异步地在 SSD 和 HDD 之间 migration 。比如我即将要跑个数据处理,大量的中间数据和结果会通过网络写到 NAS 的 SSD 上,然后 NAS 自己在后台吭哧吭哧把这些数据慢慢挪到 HDD 里的同时,我处理完数据要跑模型训练的时候可以继续用 SSD 上处理好的数据集。等到我用完了这些数据,这些数据还会在 HDD 上好好呆着当作收藏(bushi),或是下次用的时候再或是慢慢从 HDD 读取或是“预约”一下挪到 SSD 上。倒不是因为 ZFS 或 LVM 好还是不好,而是纯粹地这台 NAS 它既是一个用于存储冷数据的 NAS ,又是半个工作站的外置硬盘。 不过显然这有些既要又要了。所以 ZFS 依然是我非常认真考虑的选择。 |
![]() |
3
min 10 天前
这 nas 的主要负载到底是随机读+随机写,还是顺序读?
#2 里面说的训练数据的存储和访问应该是顺序读为主? 这种情况如果不用全闪,应该尽可能增加盘的数量以提升整个 nas 的吞吐量。 而#2 里面这句话“这台 NAS 它既是一个用于存储冷数据的 NAS ,又是半个工作站的外置硬盘”,就比较有意思了。 这种情况感觉就应该上全闪方案,两种工作复合通杀。 |
![]() |
4
ryd994 10 天前 via Android
既然是装 truenas 为什么要买成品?组一套洋垃圾价格便宜,内存有 ECC ,内存上限还高(上 TB 也可以实现)。洋垃圾内存可能比你的 SSD 还便宜。
“为了某个明天打算跑训练的模型,把某个数据集下载下来,稍微做一些预处理” 可以下载之后触发脚本,把数据复制到 SSD 上。 “训练的时候写个 data loader 从 NAS 上读取数据” 可以用两个 data loader 分别从 HDD 和 SSD 上读取对应的数据。写个脚本自动寻找并生成相应的配置。 也可以用 mergefs 把两个储存“合并”起来读取。 预约 SSD:你可以用 cron 定期移动/删除 SSD 上的缓存 速度慢:HDD 不应该用 RAID10 而应该用 RAIDZ2 。6 盘 RAIZ2 的顺序读写速度显著优于 6 盘 RAID10 (只要 CPU 不是瓶颈)。而且 Z2 的安全性高于 RAID10 。RAID10 只能保证丢失一盘时的数据安全,如果不巧丢了一对就不行了。损坏一盘重建的时候,其镜像盘也同时损坏的概率非常高。Z2 可以保证损失**任意**2 盘的情况下的数据安全。Z2 的缺点是随机写入,但是你这个场景应该不需要随机写入性能。 |
![]() |
5
ryd994 10 天前 via Android
如果你一开始就走洋垃圾路线,内存加满,根本就不需要纠结 SSD 和 HDD 之间的数据移动。操作系统的读写缓存/ZFS 的 ARC 可以自动管理好内存缓存。
|
6
caomingjun 6 天前
@iBugOne 想借楼问一个关于 ZFS 安全性的问题,这个问题有点小白但是一直没有找到足够权威的文章来回答。
ZFS 同时知道文件系统级别的信息和奇偶校验的信息。考虑多个硬盘损坏(以至于超出了 RAIDZ/RAID 的冗余)但是都只损坏了少部分扇区的情况。对于 ZFS ,如果只是少数几个扇区上的数据的损坏超出了冗余,其他位置上存储的文件应当是可以被 ZFS 直接正常读取甚至继续使用的。相反,硬件 RAID 在这种情况下则会直接出现重建失败和数据无法读取,虽然理论上可以读出,但是需要比较麻烦的数据恢复过程。 事实上是这样的吗?当出现上述情况的时候,ZFS 的表现是怎样的? 我的新 NAS 已经确定要用 ZFS (通过 TrueNas 系统) 了,问这个问题主要是在考虑每个 VDEV 要多少硬盘。越多硬盘读取速度会越快,管理也越方便;但是如果是硬件 RAID ,更多硬盘也意味着重建失败率更高、一旦失败损失的数据更多。 |
![]() |
7
iBugOne 6 天前 ![]() @caomingjun ZFS 除了奇偶级别的校验,所有的数据也都有额外的校验( checksum ,方法是哈希而不是 XOR ,默认算法是 fletcher4 ),所以即使没有 RAID ,ZFS 也能知道哪些数据块是损坏的,并且汇报给上层(虽然应用程序可能就只在 read 的时候得到一个 EIO ,并不知道具体细节),并且整个过程不影响其他完好的数据库。在有 RAID 的情况下,ZFS 就可以利用奇偶校验提供的冗余信息来尝试恢复这些数据。
同样,在重建的时候,ZFS 也会把所有数据都读出来并且利用 checksum 确认完整性,然后只修复损坏的数据,因此重建的失败率也取决于数据量。而硬件 RAID 没有这一层额外的 checksum ,就没法判断数据的完整性了,并且硬件 RAID 并不 content-aware ,所以你的理解是正确的:重建的时候要全盘重建。但至于“只是少数几个扇区上的数据的损坏超出了冗余”,就要看 RAID 的实现了,我没有键过这种情况,不好评价。 关于 RAIDZ 盘数推荐,可以看我博客文章( 1 楼的链接 [6])里面的第 5 个引用(标题为 How I Learned to Stop Worrying and Love RAIDZ ),这篇引用里的推荐是至少 5 盘 Z ,6 盘 Z2 ,11 盘 Z3 ,但同时也不要太多盘。 剩下的内容和细节可以阅读 Linux 201 关于 ZFS 的页面:<https://201.ustclug.org/ops/storage/zfs/>(我还没写完,但最近忙,只能断断续续地偶尔补一点) |
8
eric107008 OP ![]() 自上次讨论以来,结合最近一段时间的探索、配置和尝试,获得了一些阶段性的成果和结论,在此与大家分享。
首先,非常感谢 @iBugOne 提供的富有深度的见解,感谢铜币已经送上。如果大家觉得某个帖子的内容对你有所帮助,在收藏之余也还请同样点个感谢或者稍作回复 [对,也是来骗铜币的] 。 **目前的方案** 1. 4 个 HDD 单独组成了一个 RAID-Z2 ZFS 存储池,服务于备份、非性能敏感的长期温-冷数据存储。 2. 2xSSD+2xHDD 各自 RAID1 后,以 SSD 为 cache 组成了 LVM 。通过一些参数配置,使得尽可能更多的随机读写全部由 SSD 承接。 3. 在应用上,搭建了两套应用软件,包括一些数据库、少量的虚拟机磁盘、数据处理平台和其他性能相对敏感的应用被放在了 LVM 中,而 ZFS 作为数据仓库和备份的同时也承担了一些非性能敏感的大容量存储挂载。另外还有一系列的脚本和 cron 实现了包括监控、快照、备份等自动化维护。 **目前的方案带来的一些效果** 经过了一些简单的测试和近段时间的使用体验来看,基本达到了如下效果: LVM 上: 1. 对于跑模型训练时的数据集这样的典型需求,大部分的读写可以跑满性能瓶颈。具体来说,小文件的随机读写可以在万兆局域网内跑出大约 500M/s 的速度,这基本是这两块 SSD 的随机读写性能的平均水平。大文件的顺序读写可以在万兆局域网内达到 6G+/s ,这也基本达到了 SSD 的性能极限。 2. 以上性能的前提是,数据集是在最近刚刚经过预处理而写进 LVM 的,这意味着使用场景符合 LVM“最近写入的数据往往会在短时间内被读取”这一假设。 在 ZFS 上: 大部分情况下多线程的综合读写(顺序+随机混合)最高可以达到 1.7G/s 左右,这也在纯 HDD 组合成的 RAID-Z2 阵列下的合理范围。 **一些补充结论** 1. 这台 NAS 与 iBug 非常熟悉的镜像站的使用场景有比较大的差别,主要在于读写数据的方式和频率不同。尽管依然存在文件大小带来的随机读写或顺序读写的区别,但这台 NAS 服务的对象并不是来自五湖四海访问镜像站的开发者们,而是几个确定的工作站并且有规划地进行数据的读写。这意味着读写由于相对有计划并其数据形式可预测,进而可以提前规划数据的流向,把需要 SSD 承接的部分尽可能让 SSD 承担,同时有计划地将“降温”的数据打包(从而将许多小文件变成一个大文件)落盘到更适合顺序读写的存储中。在这样的使用场景下,LVM+SSD Cache 依然可以通过一定的配置带来相当不错的收益。 2. LVM 本身的设计缺陷依然存在并且依然需要一些 tradeoff 。比如来自 UTSC 的同学们踩坑踩出来的 chunk size 和 blocks 数量等配置问题,以及脏块迁移问题。或许对于不同的场景,依然需要更加灵活、现代、先进的缓存适应和管理技术。在经过了一些调研后逐渐发现缓存和存储系统的优化一直是也将在很长时间内依然是学术界和工业界深入研讨的问题。在此向许多在这一领域辛勤探索的先驱者们致敬。 3. 一些方案的优点并不是绝对的,而是在某个特定的场景下,某种特定的需求中才会被体现出来。例如 iBug 倾情推荐的纯 ZFS 方案,本身是一个非常优秀的方案。我在配置和使用过程中也深刻体会到了这个方案本身的先进性。但不得不承认,这个方案对于镜像站这样一个内存充足、读取远大于写入的特殊场景下过于适应,以至于人们容易忘记在一些限制,例如空间、内存、经费有限的场景下,这个方案的优势可能难以发挥出来。一些人引以为豪的好主意,在忽略了讨论问题的背景和题设的情况下,这样的答案也没什么建设性。总的来说,还是要根据自己需求和一定的知识储备,选择适合自己的方案。 非常感谢所有参与讨论的朋友们,愿大家合家欢咯,万事如意~ |