自建 FreeNAS 一个月的使用体验杂谈

距离完成上一篇文章所述的自建 NAS 已经过去了一个月。在这一个月的时间里,我完成了数据的迁移,旧 NAS 的 decommission,这个过程也是我不断摸索 FreeNAS 与 ZFS 的一个过程。

本文主要分享我尝试使用过的存储池配置,以及 FreeNAS、ZFS 使用过程中的感受。顺便讨论哪些地方可以省钱。

存储池配置

主存储池目前使用4个 6 TB 西部数据红盘(WD60EFRX 也就是老版本 CMR 型号,非SMR),我尝试了使用 RAIDz2 (类似 RAID6)和两个 mirror vdev (类似 RAID10)进行配置。使用4个硬盘时,理论上两种配置方法在空间利用率和顺序读写吞吐率两个方面是非常类似的。有所不同的是以下几点:

  • RAIDz2 的随机读写 IOPS 低于 mirror vdev
  • RAIDz2 可以在任意两个硬盘丢失时存储池仍然正常工作,而两个 mirror vdev 组成存储池时,一旦任意一个 vdev 的两个硬盘同时丢失,整个存储池将无法正常读写
  • RAIDz2 重建时对存储池内的硬盘的总读取量至少是 mirror vdev 的两倍

在实际使用空间约 4 TiB (总容量 40%) 的情况下,此时无论是使用4盘 RAIDz2 还是使用两个 mirror vdev 组成存储池,理论上单盘可达到 140-150 MB/s 左右的读写吞吐率,也就是整个阵列达到 600 MB/s 和 300 MB/s 左右的读写吞吐率。实际使用过程中发现,mirror vdev 的性能显著高于 RAIDz2,顺序读写非常接近 600 MB/s 和 300 MB/s 的理论读写吞吐率;然而 RAIDz2 却只有约 300 MB/s 和 220 MB/s 的读写吞吐率。

最终,考虑到 mirror vdev 各方面的性能较好,并且日后扩展时可以一次向存储池里加入两个硬盘组成的新 mirror vdev,我决定保留 mirror vdev 的配置。

由于银欣 CS381 的8个硬盘位分布在两个独立供电的 SAS 背板上,为了提高可靠性,我将每个 vdev 的两个 mirror 硬盘安装在不同的背板上,这样如果有一边的供电或 SAS 连接线出现故障,存储池还能继续工作。

启动盘

前文中我提到,使用两个 WD SN550 作为启动盘是极其浪费的行为,可以使用两个 U 盘镜像安装系统,原因如下,

  • FreeNAS 的系统盘仅占用约 1 GB 的空间,剩余空间无法挪作其它用途,使用 SSD 安装系统太浪费;
  • FreeNAS 的系统盘并不会经常发生写入。日常只有一个 SQLite 数据库会在 NAS 配置发生变更时写入,以及系统升级时 FreeNAS 会建立一个新的 dataset 用于存储新版系统,基本不用担心出现类似 Linux 发行版的 apt/dpkg 升级产生的大量零碎写入,从而导致 U 盘寿命降低;
  • FreeNAS 的通知功能非常完善,如果 U 盘发生损坏,或被意外断开连接,在一分钟内就能收到报警邮件,考虑到 U 盘更换方便,无需拆机,并且非常便宜,可以准备足够多的备用盘,甚至将 U 盘插在机器上作为热备盘,单盘出现故障可以非常快速地进行替换。
意外移除 U 盘时发出的警告邮件
意外移除 U 盘时发出的警告消息
  • FreeNAS 非常容易备份与重装,即便安装系统使用的两个 U 盘同时发生损坏,其后果也不是灾难性的。实测 FreeNAS 重装并还原配置仅需5分钟,而且所有的配置都是完美还原。退一步讲,即使没有备份配置文件,也不会丢失存储池,只会丢失类似系统设置,SMB share 设置等等。
  • X470D4U 主板上的 M.2 NGFF 硬盘难以更换,需要拆机,导致实际上 mirror boot 的作用不强,并不能在启动盘发生故障时继续维持 uptime,更换硬盘时仍然要关机。

基于上述考虑,我将启动盘更换到两个 32 GB U 盘镜像启动,并且释放了两个 SN550 SSD。

L2ARC

L2ARC 也就是所谓的读缓存,用于 L2ARC 硬盘不需要任何的可靠性,只需要读写速度足够快,满足要求即可。

FreeNAS 默认配置下 L2ARC 写入速度太慢,可以说几乎没有什么用,需要在系统设置里加上几个 Tunable

  • vfs.zfs.l2arc_write_boost
  • vfs.zfs.l2arc_write_max

将这两个 Tunable 的值设置为 ARC 最大的写入速率,例如我将其设置为 1073714824 。其余还有一些类似 vfs.zfs.l2arc_noprefetch 与 vfs.zfs.l2arc_norw 的 Tunable 也可以视情况进行修改。

在我的实际使用过程中,L2ARC 对虚拟机读取有非常好的加速效果,尤其是那些非24小时开启的虚拟机,由于距离上一次使用时间较久,内存中的 ARC 缓存早已被新的内容替代,在开机过程中经常有着非常高的 L2ARC 命中率,体验提升明显。如果没有 L2ARC,这种情况下虚拟机内的 Windows 10 在开机后的几分钟内会出现非常明显的卡顿感。

开启一个系统盘位于 SMB 上的 Hyper-V 虚拟机

需要注意的是,L2ARC 一般建议配置为经常随机访问的热数据的大小,如果经常随机访问的数据比内存小,则完全没有使用 L2ARC 的必要,因为所有的内容都可以在内存里保留缓存。除此之外,L2ARC 在 NAS 重启后内容会全部失效,因此如果 NAS 不能维持足够长的 uptime,L2ARC 的意义不是特别大,甚至可能造成无意义的 SSD 写入,缩减 SSD 寿命。

大约 45 GB 的 ARC 与 300 GB 的 L2ARC 缓存

写入优化

FreeBSD 默认配置下最大只会使用 4 GB 内存作为脏数据缓冲区,而实际测试后我发现,当存储池持续写入速度约为 300 MB/s 时,最佳的写入缓冲区大小为 8 GB,因此设置 vfs.zfs.dirty_data_max 为 8589932492。

测试复制一个 20 GB 的大文件

如果将这个数值设置得过小,则会无法完全有效利用内存作为写入缓冲区,导致短暂的 IO 负载下的性能下降;如果设置得过大,则会出现持续写入数据时性能不平稳的问题,即写入速度经常达到 1 GB/s 的线速,但很快速度降为0,持续几秒后继续 1 GB/s 一段时间,然后再次降低到0。当我将其设置为 8 GB 时,可实现短暂的写入达到 1 GB/s 的线速,后面慢慢降低速度,最终接近 300 MB/s。理论上微调一些其它地参数(例如 throttle)可在更大的缓冲区配置下实现类似的平稳效果,但是我的时间有限,没有仔细研究。

日常复制文件时,产生的更多是 async 写入,可以完全使用内存作为 buffer,接近 HDD 的理论写入速度,缺点是如果断电可能会导致缓冲区中最近写入的数据丢失。对于经常写入的重要文件所在的 dataset,可以将 sync 设置为 always,这样所有的写入请求都会是 sync 写入,也就是在任何时间断电都不会丢失已经写入的数据。

SLOG

Sync 设置为 always 的缺点非常明显,正常情况下顺序写入大约有 300 MB/s 的 HDD 存储池,将 sync 配置为 always 后由于 ZFS 的 ZIL 等开销,性能降低为 1 MB/s。使用 SLOG 可以缓解这个问题,但是 ZFS 在写入 SLOG 时会设置 FUA bit,消费级硬盘通常没有掉电保护,设置 FUA bit 后写入性能通常非常差。即便如此,也比 HDD 的 1 MB/s 要好得多,作为重要文件的存储空间,已经是足够好的性能了。

型号吞吐率
WD SN550 250GB140 MB/s 突发, 40 MB/s 持续
Crucial MX500 1TB80 MB/s
Intel Optane 16G100 MB/s
Intel Optane 32G200 MB/s
Intel Optane 58G/118G370 MB/s
Intel Optane 280G1600 MB/s
一些已知的消费级硬盘 SLOG 写入性能

如果不带掉电保护的消费级硬盘做 SLOG 并设置 sync 为 always 时,性能显著高于 MX500 和 SN550,甚至于接近其标称的最大写入速度,这并不是一个好消息,因为最大的可能是 SSD 主控没有正确实现 FUA bit,或 ZFS 由于一些原因没有正确地将 SLOG flush 到盘上,这种情况下的 SLOG 没有任何作用,与将 sync 设置为 disabled 无异

显然作为 SLOG,最具性价比的是 16 GB 的 Intel Optane 模块,可以以极低的价格(每个约 100 CNY)购买盒装版本两个,安装于主板上的 M.2 槽,做 mirror 用于 SLOG,以将 sync 写入性能提升到 100 MB/s。当然,更大容量的 Optane 写入性能也更好,但是由于 SLOG 不是传统意义上的写入缓存,使用持续写入性能远超存储池写入性能的模块做 SLOG,或者容量大于脏数据缓冲区的模块(例如本文提到的 8 GB),是没有任何意义的,SLOG 在任何情况下都不能让你获得高于 sync 设置为 disabled 时的持续写入性能

硬件改进

上一篇文章发布后,有人抱怨这一套硬件太贵,但是实际上有很多地方都是可以省的,并且大多数都是可以日后再扩展。这里简单讲一下哪些是可以省的,哪些是不能省的。

不能省的

  • 机箱和主板。这是整套方案的核心,暂时不在这篇文章里讨论其它的方案。
  • 电源。本来就是消费级电源,用在 NAS 上基本上是贴着底线走了。
  • ECC 内存。ZFS 对硬盘上的任何数据都有完整性校验,但对内存里的数据没有做任何的校验,如果内存发生了翻转,那么轻则造成数据损坏,最严重的情况下甚至可能导致 ZFS 关键数据结构损坏,而丢失整个存储池。

可以省的

  • CPU。AMD 在 5 月发布了基于 Zen 2 的 Ryzen 3 产品,因此这套方案最低可以选用 Ryzen 3 3100 或 3300X。
    • 考虑到单线程性能的差距,不推荐使用任何 Zen、Zen+ 产品
    • 考虑到 ECC 内存支持,不推荐使用任何 APU。虽然 Ryzen Pro APU 具有 ECC 支持,但是目前并没有正规渠道零售,只有来路不明的淘宝散片,而在这样的一个项目中我们希望避免任何来路不明的硬件。
  • 内存容量。可将 2 × 32 GB ECC 内存缩减至 1 × 16 GB ECC 内存,对于基本的 NAS 功能,16 GB 内存绰绰有余,其中仍可用 8 GB 作为写入缓冲区,而剩下的空间甚至还可以安装一两个虚拟机或者 Jail。
  • 网卡。如果对万兆网络没有需求,可以使用板载千兆网卡替代,日后有需求了再购买安装。
    • 不推荐使用任何来路不明的网卡,如二手、拆机网卡等,我的亲身经历告诉我此类网卡可能会造成系统稳定性问题。
    • 不推荐使用消费级网卡,例如基于 Aquantia 芯片,或基于 Realtek 芯片的网卡,对 FreeBSD 的支持可能较差。
  • 启动盘。如前文所述,可以使用两个质量较好的 U 盘作为 mirror 启动盘,相比消费级 SSD 不会有显著影响稳定性的问题。
  • HBA。如果只需要使用 SATA 硬盘,不需要使用 SAS 硬盘,可以使用 SATA 转 Mini SAS 的连接线,将主板上的8个 SATA 接口连接到背板。X470 的 SATA 接口支持热插拔,性能上也没有明显的缺陷。

如此精简过后,整机最低仅需要人民币约 6000 元,并且几乎保留了所有的优点和扩展性,相比原方案约 11000 元的价格,性价比显得高了不少。

总结

FreeNAS 真香。

自建 FreeNAS 一个月的使用体验杂谈》有7个想法

  1. noli

    同使用 FreeNAS 路过。没有上 ECC 因为 CPU 只是赛扬的。
    最多的钱和注意力都投资在 HDD 上了,选了 HGST。
    iocage 管 jail 真的舒服。
    mirror vdev 是怎么个玩法?

    回复
  2. 杜先生

    请问版主板 两个 Tunable 的 VFS.ZFS.L2ARC的值是怎么计算的呢?

    FreeNAS 默认配置下 L2ARC 写入速度太慢,可以说几乎没有什么用,需要在系统设置里加上几个 Tunable
    vfs.zfs.l2arc_write_boost
    vfs.zfs.l2arc_write_max

    回复
  3. fine

    你好
    我在应用 truenas 的过程中发生了一些很奇怪的数据表现,正好向你请教一下。
    我是 6 个 12T 氦盘组的 raidz1 ,nas 里 shell 测试,写入1.3G/s 左右,读取2G/s 左右
    带宽使用 iperf 验证能有 7.5g 以上
    但是实际的 smb 读写性能只能达到写入 200mb 以下,读取 500 左右。
    远远低于测试验证数据,有点疑惑,向你也请教一下~
    感谢

    回复

回复 David Huang 取消回复

您的电子邮箱地址不会被公开。 必填项已用*标注