需求
- 容量越大越好
- 1-2 块硬盘的冗余
- 硬件转码能力,越强越好
- 至少能跑 Container
硬件选择
NAS
Component | Model | Remarks | Cost (CNY) |
---|---|---|---|
Chassis | 星之海 半人马座 | 8 盘位 7 半高 PCIe 槽 | 1299 |
CPU | AMD Ryzen 3900X | 主力机淘汰 | 0 |
CPU Cooler | Themalright AXP90 X53 | 机箱限高,只能用下压式 | 159 |
MB | MSI X570 Unify | 主力机淘汰 | 0 |
Memory | Kingston 32GB DDR4@3200MHz | 主力机淘汰 | 0 |
GPU | MSI Intel Arc A380 (DG2) | 半高双槽,最强的编解码能力,没有之一(应该) | 899 |
HBA Card | LSI 2308 | 刷 IT Mode,便宜 | 75 |
Data Drive | Seagate EXOS X18 16TB * 8 | 比 HC550 “安静” | 1670 * 8 |
Boot Drive | KIOXIA RC20 1TB | 便宜可靠 | 429 |
PSU | Themaltake SFX 450W | 便宜 | 429 |
Networking
Component | Model | Remarks | Cost (CNY) |
---|---|---|---|
NIC | Intel X520 DA1 * 2 | 最便宜的 10GbE NIC | 130 * 2 |
Switch | QNAP QSW-M408S | 至少三个 SFP+ 和至少 8 个 RJ45 中最便宜的? | 1550 |
Host OS 选择
OS (Distribution) | Pros | Cons |
---|---|---|
Windows Server | 最好的驱动支持 | Windows, Proprietary |
Proxmox VE | 听说靠谱,Open Source | 没用过,内核旧 |
ESXi | 听说靠谱 | 没用过,Proprietary |
UnRAID | Linux,简单,社区好像不错 | 性能受限于单盘,Proprietary |
TrueNAS Core (FreeBSD) | 听说靠谱,OOTB ZFS,WebUI | FreeBSD |
TrueNAS Scale (Debian) | Linux,OOTB ZFS,WebUI | 内核旧 |
Arch Linux | 常用 Distro,文档全 | 配置成能用相对麻烦 |
最后上面的一个也没有选,用了从没用过的 Distro,NixOS。选它的原因有两个:
- Unstable Channel 可以 Rolling Upgrade,Stable Channel 又可以像普通 Distro 一样冻结版本。
- NixOS 或者说 Nix 的一个特点是,它是 Declarative 的。只要配置一样,可以产出同样的 OS 或者 Package。因为我不打算给 Boot Drive 做任何 RAID,快速恢复 Host OS 的快速恢复(配置)能力很重要。使用 NixOS 并备份配置即可达成目的,Ansible + 其他 Distro 应该也是可以的。
另外不能小看 TrueNAS 的 WebUI 的含金量,毕竟 ZFS 的 Management WebUI 少的可怜。除了 TrueNAS 自带的这个之外,我仅仅搜到两个基于 Cockpit 的 cockpit-zfs-manager 和一个 Early Access 还卖 $49/year 起的 Poolsman。前者是开源免费的,但是看起来功能比较简陋;后者看起来不错,接近 TrueNAS 的那个,但是有点贵。TrueNAS 整个 OS 可都是免费的。我选择放弃 Management WebUI,用 Netdata 做一个 Readonly 的 Dashboard 就行了。
ZFS
安装
ZFS 在 Linux 上已经有比较好的支持了,一些面向存储的 Distro 基本都有开箱即用的 ZFS,比如 TrueNAS Scale 和 Proxmox VE。其他的 Distro 可以参考 OpenZFS Doc 或者 ZFS - ArchWiki。
我不需要 Root On ZFS,所以复杂的部分就跳过了 :)。
创建存储池
想着有 8 * 16TB 的 Raw Capacity,就多一点冗余,决定用 RAIDZ2 做一个大的 Pool。
ZFS 有别于一般的文件系统,它自己就是一个 Volume Manager。所以创建存储池的时候只需要告诉 ZFS 磁盘就行。磁盘的 ID 一般使用 /dev/disk/by-id/
即可。有 WWN 也有型号+序列号,我选择了后者。
-o ashift=12
是因为绝大多数现代的 HDD 都是 4KB 的 Sector,具体可以参考 Advanced Format Disks
zpool create -f -o ashift=12 -m /mnt/data data raidz2 \
ata-ST16000NM000J-{DISK_SERIAL_NUMBER} \
ata-ST16000NM000J-{DISK_SERIAL_NUMBER} \
ata-ST16000NM000J-{DISK_SERIAL_NUMBER} \
ata-ST16000NM000J-{DISK_SERIAL_NUMBER} \
ata-ST16000NM000J-{DISK_SERIAL_NUMBER} \
ata-ST16000NM000J-{DISK_SERIAL_NUMBER} \
ata-ST16000NM000J-{DISK_SERIAL_NUMBER} \
ata-ST16000NM000J-{DISK_SERIAL_NUMBER}
zpool status -v
pool: data
state: ONLINE
scan: scrub repaired 0B in 00:00:01 with 0 errors on Sun Dec 18 10:45:27 2022
config:
NAME STATE READ WRITE CKSUM
data ONLINE 0 0 0
raidz2-0 ONLINE 0 0 0
ata-ST16000NM000J-{DISK_SERIAL_NUMBER} ONLINE 0 0 0
ata-ST16000NM000J-{DISK_SERIAL_NUMBER} ONLINE 0 0 0
ata-ST16000NM000J-{DISK_SERIAL_NUMBER} ONLINE 0 0 0
ata-ST16000NM000J-{DISK_SERIAL_NUMBER} ONLINE 0 0 0
ata-ST16000NM000J-{DISK_SERIAL_NUMBER} ONLINE 0 0 0
ata-ST16000NM000J-{DISK_SERIAL_NUMBER} ONLINE 0 0 0
ata-ST16000NM000J-{DISK_SERIAL_NUMBER} ONLINE 0 0 0
ata-ST16000NM000J-{DISK_SERIAL_NUMBER} ONLINE 0 0 0
其他配置
均以 NixOS 的 /etc/nixos/configuration.nix
为例,其他 Distro 需参考各自的文档。
Import on Boot
在 NixOS 上,只需要在 /etc/nixos/configuration.nix
里面加上一个 Option 就可以在 Boot 的时候 Import 上面创建的存储池。
boot.zfs.extraPool = [ "YOUR_POOL_NAME" ]
ARC Size
boot.kernelParams = [ "zfs.zfs_arc_max=ARC_MAX_SIZE_IN_BYTES" ];
or
boot.extraModprobeConfig = ''
options zfs zfs_arc_max=ARC_MAX_SIZE_IN_BYTES
'';
Automatic Scrubbing
services.zfs.autoScrub.enable = true;
Intel DG2
Intel DG2 目前需要 Linux 6.0 和 Mesa 22.2 才能支持。这也是没有选择 TrueNAS 和 UnRAID 的原因。
NixOS 22.11 自带的内核是 5.15 LTS,跟换内核只需要在 /etc/nixos/configuration.nix
里面设置一下 boot.kernelPackages
就可以了,但是之前用到的 ZFS 并不是 DKMS 的,所以这里最高只能安装 Nixpkgs 中的 ZFS 2.1.7 所支持的最新 Kernel。NixOS ZFS 的文档也描述了如何设置,boot.kernelPackages = config.boot.zfs.package.latestCompatibleLinuxPackages;
即可。所幸,目前 ZFS 2.1.7 @ Nixpkgs 能支持的最新的 Kernel 是 linuxPackages_6_0
。
仅仅是 Linux 6.0 并不能使 Intel DG2 被正确驱动。dmesg
可以看到如下信息,其中 56a5
是 Intel Arc A380 的 ID,需要 force_probe
才行。
[ 10.171063] i915 0000:30:00.0: Your graphics device 56a5 is not properly supported by the driver in this kernel version. To force driver probe anyway, use i915.force_probe=56a5 module parameter or CONFIG_DRM_I915_FORCE_PROBE=56a5 configuration option, or (recommended) check for kernel updates.
按照提示,设置 modprobe.conf
,在一般的 Distro 上,应该在 /etc/modprobe.d/
下新建一个文件写入 options i915 force_probe=56a5
。在 NixOS 上,则是在 /etc/nixos/configurations.nix
中添加如下设置。
boot.extraModprobeConfig = ''
options i915 force_probe=56a5
''
重启后,查看 /dev/dri
,相比之前多了 renderD128
即可。
ls /dev/dri/
by-path card0 renderD128
10GbE
原以为 10GbE 也是像 1GbE 一样即插即用的,毕竟现在 DataCenter 都已经 40Gbps+ 了,然而事情并没有那么简单。
Windows NIC Driver
Intel X520 DA1 在 Windows 上是需要手动安装驱动的,参考这篇文章安装驱动。简单来说就是从官网下载驱动并手动安装 PROXGB/Winx64/NDIS68/ixn68x64.inf
即可。
Linux NIC Driver
Intel X520 DA1 (82599) 在 Linux 上是开箱即用的,驱动是 ixgbe
,即使它是 PCIe 2.0 * 8,而我的主板只剩 PCIe * 4 可用了。
lspci | grep 82599
24:00.0 Ethernet controller: Intel Corporation 82599ES 10-Gigabit SFI/SFP+ Network Connection (rev 01)
dmesg | grep ixgbe
[ 9.702824] ixgbe: Intel(R) 10 Gigabit PCI Express Network Driver
[ 9.702827] ixgbe: Copyright (c) 1999-2016 Intel Corporation.
[ 9.886350] ixgbe 0000:24:00.0: Multiqueue Enabled: Rx Queue count = 24, Tx Queue count = 24 XDP Queue count = 0
[ 9.886640] ixgbe 0000:24:00.0: 16.000 Gb/s available PCIe bandwidth, limited by 5.0 GT/s PCIe x4 link at 0000:21:02.0 (capable of 32.000 Gb/s with 5.0 GT/s PCIe x8 link)
[ 9.886952] ixgbe 0000:24:00.0: MAC: 2, PHY: 19, SFP+: 5, PBA No: G30771-004
[ 9.886955] ixgbe 0000:24:00.0: 24:1c:04:f3:72:8b
[ 9.888269] ixgbe 0000:24:00.0: Intel(R) 10 Gigabit Network Connection
[ 9.896611] ixgbe 0000:24:00.0 enp36s0: renamed from eth0
[ 13.283241] ixgbe 0000:24:00.0: registered PHC device on enp36s0
[ 13.453178] ixgbe 0000:24:00.0 enp36s0: detected SFP+: 5
[ 13.597726] ixgbe 0000:24:00.0 enp36s0: NIC Link is Up 10 Gbps, Flow Control: RX/TX
[ 16.304564] ixgbe 0000:24:00.0 enp36s0: NIC Link is Down
[ 17.861740] ixgbe 0000:24:00.0 enp36s0: NIC Link is Up 10 Gbps, Flow Control: RX/TX
测速和排查
使用 iperf3 测速发现,任何一端作为 Server,单线程都无法跑满 10GbE。观察测速时两边的 CPU 占用,发现并没有吃满任何一个 CPU 核心。要跑满 10GbE,至少需要四个线程 -P4
。搜索发现 V2EX 上的一个帖子 Windows 10 的 10G 网络性能非常糟糕,有什么办法优化吗?,OP 的 Root Cause 是火绒。我并没有除 Windows Defender 之外的任何安全软件,尝试卸载 Windows 网络相关的软件,并再次测速,并没有任何变化。另外尝试设置两边的 TCP Send/Receive Buffer 和 Jumbo Packet(Frame),有一些提升,但是距离 10Gbps 还很远。
~ took 4s
❯ iperf3 -c 192.168.2.6
Connecting to host 192.168.2.6, port 5201
[ 4] local 192.168.2.11 port 56650 connected to 192.168.2.6 port 5201
[ ID] Interval Transfer Bandwidth
[ 4] 0.00-1.00 sec 556 MBytes 4.66 Gbits/sec
[ 4] 1.00-2.00 sec 562 MBytes 4.71 Gbits/sec
[ 4] 2.00-3.00 sec 568 MBytes 4.77 Gbits/sec
[ 4] 3.00-4.00 sec 564 MBytes 4.73 Gbits/sec
[ 4] 4.00-5.00 sec 574 MBytes 4.81 Gbits/sec
[ 4] 5.00-6.00 sec 564 MBytes 4.73 Gbits/sec
[ 4] 6.00-7.00 sec 565 MBytes 4.74 Gbits/sec
[ 4] 7.00-8.00 sec 567 MBytes 4.75 Gbits/sec
[ 4] 8.00-9.00 sec 574 MBytes 4.81 Gbits/sec
[ 4] 9.00-10.00 sec 568 MBytes 4.77 Gbits/sec
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval Transfer Bandwidth
[ 4] 0.00-10.00 sec 5.53 GBytes 4.75 Gbits/sec sender
[ 4] 0.00-10.00 sec 5.53 GBytes 4.75 Gbits/sec receiver
iperf Done.
~ took 10s
❯ iperf3 -c 192.168.2.6 -R
Connecting to host 192.168.2.6, port 5201
Reverse mode, remote host 192.168.2.6 is sending
[ 4] local 192.168.2.11 port 56652 connected to 192.168.2.6 port 5201
[ ID] Interval Transfer Bandwidth
[ 4] 0.00-1.00 sec 680 MBytes 5.70 Gbits/sec
[ 4] 1.00-2.00 sec 687 MBytes 5.77 Gbits/sec
[ 4] 2.00-3.00 sec 685 MBytes 5.74 Gbits/sec
[ 4] 3.00-4.00 sec 687 MBytes 5.76 Gbits/sec
[ 4] 4.00-5.00 sec 686 MBytes 5.75 Gbits/sec
[ 4] 5.00-6.00 sec 688 MBytes 5.77 Gbits/sec
[ 4] 6.00-7.00 sec 686 MBytes 5.75 Gbits/sec
[ 4] 7.00-8.00 sec 683 MBytes 5.73 Gbits/sec
[ 4] 8.00-9.00 sec 684 MBytes 5.73 Gbits/sec
[ 4] 9.00-10.00 sec 687 MBytes 5.76 Gbits/sec
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval Transfer Bandwidth Retr
[ 4] 0.00-10.00 sec 6.69 GBytes 5.75 Gbits/sec 0 sender
[ 4] 0.00-10.00 sec 6.69 GBytes 5.75 Gbits/sec receiver
iperf Done.
在原本的 Windows 机器上使用 ArchLiveISO 测速,可以跑到约 9.4Gbps。只好暂时认为 Windows,Intel 的驱动或者 iperf3 on Windows 三者中至少有一个有性能问题。
Samba
最开始 Samba 的性能(Linux Server, Windows Client),符合测速,仅能跑 5Gbps 左右。在开启 Jumbo Packet(Frame) 和修改 TCP Buffer Size 之后,Windows Client 向 Linux Server 写入可以接近 1GBps,但是读取仅有一半。