廉价的全闪存雷电 NAS 折腾笔记:NUC9 操作系统踩坑

news2024/11/22 22:16:35

上一篇文章中,分享了关于低成本全闪存 NAS 的个人方案选择。

本篇文章,来聊聊硬件相关部分,以及软件的基础配置部分,也聊聊雷电组网的踩坑之旅。

写在前面

我使用的设备是 NUC9i5QNX,这台设备的硬件基础规格,可以在 Intel ARK 网站中找到。在上一篇文章《廉价的全闪存雷电 NAS 折腾笔记:组网方案的选择》中,我介绍了这台设备的优势,感兴趣可以自行翻阅。

本文的主角:NUC9

简单来说,NUC 9 支持一大票有用的接口,并且可以通过 PCIe 继续扩展 NVMe 盘位或网卡。

NUC 9 丰富的端口支持

如果你的 NUC9 选择了带有显卡的版本,并且希望用这个显卡跑一些 AI 程序,也可以参考之前写过的两篇文章,来进行折腾:《基于 Docker 的深度学习环境:入门篇》、《基于 Docker 的深度学习环境:Windows 篇》,这两篇文章聊过了在 Linux 和 Windows 环境下,如何简单、正确的配置 GPU Docker 环境。

测试使用的老硬盘

本文中,我在 NUC9 上使用的固态硬盘是很早之前汰换下来的硬盘,所以在写入速度上,并不会特别的亮眼,但好处是发热量小,以及不用额外破费银子。

在开始折腾之前,因为这款设备的发布时间较早(20~21年),所以推荐先升级 BIOS 。

必要的 BIOS 升级

如果你的设备硬件型号也是 NUC9i5QN、NUC9i7QN、NUC9i9QN 之一,可以在 Intel 下载中心,找到 NUC9 的 BIOS 升级程序,下载到今年 5 月 9 日发布的新版本 BIOS 固件。如果你选择了其他设备,请自行寻找合适的 BIOS 程序进行升级。

一般情况下,BIOS 属于我们购买机器后,一般不会关注到的细节。但从个人使用硬件的经验来看,设备发行后的 BIOS 至少要等一年半载才能够填坑完毕,包括并不局限于底层漏洞、硬件设备支持列表完善、BIOS 程序本身的 BUG 等等。我们从 Intel NUC9 BIOS 发行日志中,也可以看到更新 BIOS 的必要性。

我到手的设备默认的 BIOS 版本是 OXCFL579.0045.2020.0617.1710,不用翻看官网,单从命名也看得出来是三年前出厂时的版本。说起来这个版本的构建完成时间点,是在朝九晚五的 Intel 工程师们接近下班后构建的。(一定是 CI,不是人肉整的,哈哈 😄 )

升级 BIOS 的方式有许多种,我的升级方式是:

  1. 翻箱倒柜找到一块 U 盘,在操作系统中对其进行格式化(FAT 格式)。
  2. 将下载好的 QX0072.cap 文件放置到 U 盘根目录,将 U 盘插在设备背板插槽,重启设备。
  3. 在启动设备的时候按着 F7,进入 BIOS 升级工具中。
  4. 选择 U 盘里的升级文件,确保电源稳定的情况下,等待设备升级完毕。

完成 BIOS 升级之后,NUC9 默认是会关机的,所以耐心等待固件升级完毕后,我们开机按着 F2 进入 BIOS 就能够看到更新后的 BIOS 版本啦。

在 BIOS 里,我们可以禁用一些设备,以及开启更节能的休眠,对于长时间运行的设备来说,还是很必要的。

这些我们可以稍晚些再设置,在安装完毕操作系统前,我们先调用全部的性能,把系统安装好先。

如果你只想和快速上手,那么可以跳过踩坑,直接阅读“雷电 NAS 操作系统选择”小节。

我相信我的读者有各种 NAS 操作系统的粉丝,所以这里我们就挨着聊聊常见系统的踩坑之路。

测试硬盘能力

测试 Linux 的磁盘读写能力,我们可以使用 FIO 来进行,首先进行软件的安装:

apt-get install fio 

先来测试顺序读写 10G 的文件,测试结果是大文件读写,磁盘写入能力大概只有 500MB/s 左右:

# fio -filename=test -direct=1 -iodepth 1 -thread -rw=write -ioengine=psync -bs=16k -size=10G -numjobs=1 -runtime=600 -group_reporting -name=write

write: (g=0): rw=write, bs=(R) 16.0KiB-16.0KiB, (W) 16.0KiB-16.0KiB, (T) 16.0KiB-16.0KiB, ioengine=psync, iodepth=1
fio-3.33
Starting 1 thread
write: Laying out IO file (1 file / 10240MiB)
Jobs: 1 (f=1): [W(1)][100.0%][w=479MiB/s][w=30.7k IOPS][eta 00m:00s]
write: (groupid=0, jobs=1): err= 0: pid=6608: Mon Sep 11 23:57:20 2023
  write: IOPS=30.7k, BW=479MiB/s (503MB/s)(10.0GiB/21360msec); 0 zone resets
    clat (usec): min=23, max=1107, avg=31.85, stdev= 3.71
     lat (usec): min=24, max=1107, avg=32.10, stdev= 3.71
    clat percentiles (nsec):
     |  1.00th=[29824],  5.00th=[30848], 10.00th=[31104], 20.00th=[31360],
     | 30.00th=[31360], 40.00th=[31616], 50.00th=[31616], 60.00th=[31872],
     | 70.00th=[31872], 80.00th=[32128], 90.00th=[32640], 95.00th=[33024],
     | 99.00th=[34048], 99.50th=[35072], 99.90th=[55552], 99.95th=[63744],
     | 99.99th=[85504]
   bw (  KiB/s): min=488192, max=494656, per=100.00%, avg=491089.52, stdev=1067.40, samples=42
   iops        : min=30512, max=30916, avg=30693.10, stdev=66.71, samples=42
  lat (usec)   : 50=99.84%, 100=0.16%, 250=0.01%, 500=0.01%, 1000=0.01%
  lat (msec)   : 2=0.01%
  cpu          : usr=5.29%, sys=31.13%, ctx=655383, majf=0, minf=0
  IO depths    : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued rwts: total=0,655360,0,0 short=0,0,0,0 dropped=0,0,0,0
     latency   : target=0, window=0, percentile=100.00%, depth=1

Run status group 0 (all jobs):
  WRITE: bw=479MiB/s (503MB/s), 479MiB/s-479MiB/s (503MB/s-503MB/s), io=10.0GiB (10.7GB), run=21360-21360msec

Disk stats (read/write):
  nvme1n1: ios=0/648710, merge=0/220, ticks=0/13924, in_queue=13934, util=99.67%

测试文件顺序读取,性能相对好一些,900MB/s 的水平:

# fio -filename=test -direct=1 -iodepth 1 -thread -rw=read -ioengine=psync -bs=16k -size=10G -numjobs=1 -runtime=600 -group_reporting -name=read

read: (g=0): rw=read, bs=(R) 16.0KiB-16.0KiB, (W) 16.0KiB-16.0KiB, (T) 16.0KiB-16.0KiB, ioengine=psync, iodepth=1
fio-3.33
Starting 1 thread
Jobs: 1 (f=1): [R(1)][100.0%][r=900MiB/s][r=57.6k IOPS][eta 00m:00s]
read: (groupid=0, jobs=1): err= 0: pid=6642: Mon Sep 11 23:58:29 2023
  read: IOPS=57.5k, BW=898MiB/s (941MB/s)(10.0GiB/11407msec)
    clat (usec): min=15, max=7055, avg=17.13, stdev=10.42
     lat (usec): min=15, max=7056, avg=17.16, stdev=10.42
    clat percentiles (usec):
     |  1.00th=[   17],  5.00th=[   17], 10.00th=[   17], 20.00th=[   17],
     | 30.00th=[   17], 40.00th=[   17], 50.00th=[   17], 60.00th=[   17],
     | 70.00th=[   17], 80.00th=[   18], 90.00th=[   18], 95.00th=[   19],
     | 99.00th=[   21], 99.50th=[   22], 99.90th=[   91], 99.95th=[  149],
     | 99.99th=[  281]
   bw (  KiB/s): min=906208, max=925824, per=100.00%, avg=919847.27, stdev=4588.69, samples=22
   iops        : min=56638, max=57864, avg=57490.45, stdev=286.79, samples=22
  lat (usec)   : 20=96.86%, 50=2.96%, 100=0.08%, 250=0.07%, 500=0.02%
  lat (usec)   : 1000=0.01%
  lat (msec)   : 10=0.01%
  cpu          : usr=4.91%, sys=24.21%, ctx=655367, majf=0, minf=5
  IO depths    : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued rwts: total=655360,0,0,0 short=0,0,0,0 dropped=0,0,0,0
     latency   : target=0, window=0, percentile=100.00%, depth=1

Run status group 0 (all jobs):
   READ: bw=898MiB/s (941MB/s), 898MiB/s-898MiB/s (941MB/s-941MB/s), io=10.0GiB (10.7GB), run=11407-11407msec

Disk stats (read/write):
  nvme1n1: ios=654643/3, merge=0/1, ticks=8465/4, in_queue=8471, util=99.23%

接着再试试随机写入和读取,得到的结果分别是 677 MB/s 和 1412 MB/s:

# fio -filename=test -direct=1 -iodepth 1 -thread -rw=randwrite -ioengine=psync -bs=16k -size=10G -numjobs=1 -runtime=600 -group_reporting -name=write

Run status group 0 (all jobs):
  WRITE: bw=677MiB/s (710MB/s), 677MiB/s-677MiB/s (710MB/s-710MB/s), io=10.0GiB (10.7GB), run=15133-15133msec

Disk stats (read/write):
  nvme1n1: ios=0/645072, merge=0/2, ticks=0/10324, in_queue=10327, util=99.39%

# fio -filename=test -direct=1 -iodepth 1 -thread -rw=randread -ioengine=psync -bs=16k -size=10G -numjobs=11 -runtime=600 -group_reporting -name=read

Run status group 0 (all jobs):
   READ: bw=1412MiB/s (1481MB/s), 1412MiB/s-1412MiB/s (1481MB/s-1481MB/s), io=110GiB (118GB), run=79766-79766msec

Disk stats (read/write):
  nvme1n1: ios=7207624/15, merge=0/4, ticks=799526/11, in_queue=799540, util=99.90%

所以,本文雷电组网之后,最大写入速度估计不会偏离这个写入速度的峰值:503 MB/s 到 710 MB/s。

等稍晚些时候,选择好新硬盘后,再来做数据更新。

TrueNAS(FreeNAS)雷电组网踩坑

TrueNAS 是一款很棒的开源商业化的 NAS 操作系统,从 2005 年项目启动至今有接近二十个年头了。在 2019 年的时候,项目将 FreeNAS 的名字正是调整为了 TrueNAS Core,作为开源商业化 NAS 的一部分存在。

TrueNAS 安装测试

TrueNAS 的安装非常简单,不过系统默认没有雷电驱动,社区里虽然多有讨论,但没有有效的稳定方案可以使用,或源代码可以自行编译驱动。

所以在这个方案里中就不是很合适了,只能暂时放弃啦。

Unraid 雷电组网踩坑

Unraid 相比 TrueNAS 对于雷电支持了,但没有完全支持。

在不极深度折腾的情况下,可以得到有限的雷电支持,如果希望使用 Unraid 来使用雷电组网,那么建议锁定系统版本。

Unraid 虽然支持雷电,但是因为驱动的问题,实际使用上会有不少小问题,包括使用雷电传输时,只有一颗 CPU 在干活,以及基本会耗尽性能,如果未来官方能够将设备驱动源码公开,借助开源社区的力量,或许支持度会有转机。

Unraid 网卡驱动 BUG

考虑到使用雷电网络的稳定性,我放弃了这个方案。

Unraid 激活雷电组网

虽然我没有选择 Unraid 作为雷电 NAS 操作系统,但想到可能 Unraid 是一些同学的心头好,就留下一些资料避免后来人踩坑吧。

当我们将支持雷电的设备和安装了 Unraid 设备连接后,系统界面中默认除了 PCI 设备日志外,是没有任何变化的,你期望的是网卡页面多出一个 thunderbolt 网卡,实际上,默认什么都不会发生。

插好雷电数据线后,我们需要先使用 lspci -nnk | grep Thunderbolt 来查看雷电驱动是否正常工作:

# lspci -nnk | grep Thunderbolt

03:00.0 PCI bridge [0604]: Intel Corporation JHL7540 Thunderbolt 3 Bridge [Titan Ridge 4C 2018] [8086:15ea] (rev 06)
	Subsystem: Intel Corporation JHL7540 Thunderbolt 3 Bridge [Titan Ridge 4C 2018] [8086:2088]
04:00.0 PCI bridge [0604]: Intel Corporation JHL7540 Thunderbolt 3 Bridge [Titan Ridge 4C 2018] [8086:15ea] (rev 06)
	Subsystem: Intel Corporation JHL7540 Thunderbolt 3 Bridge [Titan Ridge 4C 2018] [8086:2088]
04:01.0 PCI bridge [0604]: Intel Corporation JHL7540 Thunderbolt 3 Bridge [Titan Ridge 4C 2018] [8086:15ea] (rev 06)
	Subsystem: Intel Corporation JHL7540 Thunderbolt 3 Bridge [Titan Ridge 4C 2018] [8086:2088]
04:02.0 PCI bridge [0604]: Intel Corporation JHL7540 Thunderbolt 3 Bridge [Titan Ridge 4C 2018] [8086:15ea] (rev 06)
	Subsystem: Intel Corporation JHL7540 Thunderbolt 3 Bridge [Titan Ridge 4C 2018] [8086:2088]
04:04.0 PCI bridge [0604]: Intel Corporation JHL7540 Thunderbolt 3 Bridge [Titan Ridge 4C 2018] [8086:15ea] (rev 06)
	Subsystem: Intel Corporation JHL7540 Thunderbolt 3 Bridge [Titan Ridge 4C 2018] [8086:2088]
05:00.0 System peripheral [0880]: Intel Corporation JHL7540 Thunderbolt 3 NHI [Titan Ridge 4C 2018] [8086:15eb] (rev 06)
	Subsystem: Intel Corporation JHL7540 Thunderbolt 3 NHI [Titan Ridge 4C 2018] [8086:2088]
39:00.0 USB controller [0c03]: Intel Corporation JHL7540 Thunderbolt 3 USB Controller [Titan Ridge 4C 2018] [8086:15ec] (rev 06)
	Subsystem: Intel Corporation JHL7540 Thunderbolt 3 USB Controller [Titan Ridge 4C 2018] [8086:2088]

从上面的日志输出中,我们能够看到通过驱动识别到的雷电设备的控制器是 Intel JHL7540,支持的雷电版本是雷电3。

如果你的设备没有输出任何日志,那么说明你的设备并不支持雷电,或者驱动有问题,需要先解决驱动问题。

如果驱动没有问题,雷电数据线也连接好了,我们将能够使用下面的命令(Linux 内核里的设备管理器)访问和收集雷电硬件信息:

udevadm info -a -p /sys/class/net/thunderbolt0

命令执行完毕后,我们可以看到类似下面的信息,包括雷电网卡的各种详细属性、连接组网的设备的详细信息、约定的网络速率等:

# udevadm info -a -p /sys/class/net/thunderbolt0

Udevadm info starts with the device specified by the devpath and then
walks up the chain of parent devices. It prints for every device
found, all possible attributes in the udev rules key format.
A rule to match, can be composed by the attributes of the device
and the attributes from one single parent device.

  looking at device '/devices/pci0000:00/0000:00:1c.4/0000:03:00.0/0000:04:00.0/0000:05:00.0/domain0/0-0/0-1/0-1.0/net/thunderbolt0':
    KERNEL=="thunderbolt0"
    SUBSYSTEM=="net"
    DRIVER==""
    ATTR{carrier_changes}=="1"
    ATTR{dev_id}=="0x0"
    ATTR{carrier_down_count}=="1"
    ATTR{proto_down}=="0"
    ATTR{address}=="02:4c:3f:xx:xx:xx"
    ATTR{operstate}=="down"
    ATTR{link_mode}=="0"
    ATTR{mtu}=="1500"
    ATTR{gro_flush_timeout}=="0"
    ATTR{carrier_up_count}=="0"
    ATTR{ifalias}==""
    ATTR{netdev_group}=="0"
    ATTR{napi_defer_hard_irqs}=="0"
    ATTR{ifindex}=="5"
    ATTR{broadcast}=="ff:ff:ff:ff:ff:ff"
    ATTR{type}=="1"
    ATTR{dev_port}=="0"
    ATTR{name_assign_type}=="1"
    ATTR{addr_assign_type}=="0"
    ATTR{addr_len}=="6"
    ATTR{threaded}=="0"
    ATTR{tx_queue_len}=="1000"
    ATTR{iflink}=="5"
    ATTR{flags}=="0x1002"

  looking at parent device '/devices/pci0000:00/0000:00:1c.4/0000:03:00.0/0000:04:00.0/0000:05:00.0/domain0/0-0/0-1/0-1.0':
    KERNELS=="0-1.0"
    SUBSYSTEMS=="thunderbolt"
    DRIVERS=="thunderbolt-net"
    ATTRS{prtcstns}=="0x00000003"
    ATTRS{prtcvers}=="1"
    ATTRS{prtcrevs}=="1"
    ATTRS{key}=="network"
    ATTRS{prtcid}=="1"

  looking at parent device '/devices/pci0000:00/0000:00:1c.4/0000:03:00.0/0000:04:00.0/0000:05:00.0/domain0/0-0/0-1':
    KERNELS=="0-1"
    SUBSYSTEMS=="thunderbolt"
    DRIVERS==""
    ATTRS{vendor_name}=="Apple Inc."
    ATTRS{maxhopid}=="15"
    ATTRS{vendor}=="0xa27"
    ATTRS{device}=="0xa"
    ATTRS{rx_lanes}=="1"
    ATTRS{rx_speed}=="20.0 Gb/s"
    ATTRS{unique_id}=="c377841e-xxxx-xxxx-xxxx-ed56be6d2548"
    ATTRS{tx_lanes}=="1"
    ATTRS{tx_speed}=="20.0 Gb/s"
    ATTRS{device_name}=="MacBookPro16,1"

... ...

通过 cat /etc/udev/rules.d/70-persistent-net.rules,我们可以看到系统中自动生成网卡配置:

# cat /etc/udev/rules.d/70-persistent-net.rules 
# PCI device 0x8086:0x1533 (igb)
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="f4:6b:8c:xx:xx:xx", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME="eth0"

# PCI device 0x8086:0x15bb (e1000e)
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="f4:6b:8c:xx:xx:xx", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME="eth1"

参考上面的配置和设备管理器的输出,我们可以创建一个新的文件 /etc/udev/rules.d/71-persistent-net.rules

# Thunderbolt0
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="02:4c:3f:xx:xx:xx", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="thunderbolt", NAME="eth3"

当完成配置信息的创建后,我们执行下面的命令,刷新设备管理器的列表和激活新增的雷电网卡:

udevadm control --reload
udevadm trigger --action=add --attr-match=address="02:4c:3f:xx:xx:xx"

当上面的命令执行完毕后,我们使用下面的命令,分别为网卡手动设置 IP 地址、掩码、 MTU,启动网卡:

ip a add 192.168.123.3/255.255.255.0 dev thunderbolt0
ip link set dev thunderbolt0 mtu 1500
ip link set dev thunderbolt0 up
# 或者使用
ifconfig 192.168.123.3 netmask 255.255.255.0 up

这个时候,连接雷电 NAS 的设备的网卡处应该会有“一些变化”了,我们在连接设备处也设置相同的 MTU、相同网段的新 IP 地址和 IP 掩码后,设备就可以联通使用啦。

激活界面中的网卡信息

虽然通过上面的设置,我们已经能够通过命令行来通过雷电网卡来传输数据了。但是 Unraid 的网络界面中,还是不会出现这个网卡,想要解决这个问题,我们需要手动执行下面的命令:

echo 1 > /sys/bus/pci/rescan

当我们触发设备的重新扫描之后,网页中就会出现一块名为 thunderbolt 的新网卡了。

为了确保设备热拔插,雷电状况展示正常,这里最好写一个脚本,定时的执行这个重新扫描操作。

Unraid 雷电组网的性能问题

如果我们使用 ethtool 来查看一般的网卡信息,将能看到网卡队列情况,这说明网卡支持将输出传输的计算任务负载均衡到多个 CPU 中进行处理,将极大的提升数据吞吐能力,和有效降低整机负载:

# root@NAS:~# ethtool -l eth0

Channel parameters for eth0:
Pre-set maximums:
RX:		n/a
TX:		n/a
Other:		1
Combined:	4
Current hardware settings:
RX:		n/a
TX:		n/a
Other:		1
Combined:	4

但是,倘若相查看或者设置雷电网卡的相关能力的时候,我们会得到“操作不被支持”的错误提示。

# root@NAS:~# ethtool -l thunderbolt0
netlink error: Operation not supported

# root@NAS:~# ethtool -L thunderbolt0 combined 8
netlink error: Operation not supported

在没有驱动支持的前提下,雷电数据传输将只消耗一颗 CPU 的资源,这也会或多或少的影响数据传输效率。

雷电 NAS 操作系统选择:Ubuntu

这里,我选择的是 Ubuntu Desktop:对于一般的硬件,包括电源节能设置、核显驱动支持等都还不错。安装 Ubuntu 的流程和以往并没有太大不同,依旧是老生常谈的三步曲:下载镜像、制作启动盘、安装系统。

关于如何制作镜像启动盘,以及基础的安装过程,参考《在笔记本上搭建高性价比的 Linux 学习环境:基础篇》中提到的内容即可。

一般来说,我们选择 LTS 可以省心很多,不过如果你想要使用更新的特性,也可以考虑非 LTS 的奇数年份发行版,比如 23.04、23.10。Ubuntu 的非 LTS 版本升级到 LTS 版本其实也是非常简单的,未来如果想要升级操作系统版本,可以参考之前的文章《抢先体验 Ubuntu 22.04 Jammy Jellyfish》来进行操作。

雷电组网速度测试

系统安装完毕之后,默认会完成自动组网,我们使用雷电线连接 Mac 和 NUC9,先进行一次传输测试。

我们可以使用年初折腾数据传输时,两篇文章中提到的方法来进行测试:
《MacBook 与其他设备的低成本高性能数据传输方案(一)》、《MacBook 与其他设备的低成本高性能数据传输方案(二)》。

相比较使用 Unraid ,Ubuntu 的好处是雷电设备连接后,能够启动自动组网,所以我们先使用默认配置进行网速测试,依旧是一端执行 iperf3 -s 启动服务,另外一端执行命令,进行实际数据发送,来探测带宽性能。为了避免磁盘性能影响带宽探测,我们使用 -Z 参数(zerocopy),来避免磁盘读写:

iperf3 -c 169.254.123.142 -f GB --omit 3 -Z

当命令执行完毕后,我们会发现速度非常的离谱,远远低于我们的预期:

Connecting to host 169.254.123.142, port 5201
[  5] local 10.11.12.90 port 56571 connected to 169.254.123.142 port 5201
[ ID] Interval           Transfer     Bitrate
[  5]   0.00-1.00   sec  13.2 MBytes  0.01 GBytes/sec                  (omitted)
[  5]   1.00-2.00   sec  8.77 MBytes  0.01 GBytes/sec                  (omitted)
[  5]   2.00-3.00   sec  41.8 MBytes  0.04 GBytes/sec                  (omitted)
[  5]   0.00-1.00   sec  44.8 MBytes  0.04 GBytes/sec                  
[  5]   1.00-2.00   sec  46.9 MBytes  0.05 GBytes/sec                  
[  5]   2.00-3.00   sec  46.4 MBytes  0.05 GBytes/sec                  
[  5]   3.00-4.00   sec  42.1 MBytes  0.04 GBytes/sec                  
[  5]   4.00-5.00   sec  42.7 MBytes  0.04 GBytes/sec                  
[  5]   5.00-6.00   sec  44.9 MBytes  0.04 GBytes/sec                  
[  5]   6.00-7.00   sec  44.7 MBytes  0.04 GBytes/sec                  
[  5]   7.00-8.00   sec  47.0 MBytes  0.05 GBytes/sec                  
[  5]   8.00-9.00   sec  44.9 MBytes  0.04 GBytes/sec                  
[  5]   9.00-10.00  sec  19.5 MBytes  0.02 GBytes/sec                  
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bitrate
[  5]   0.00-10.00  sec   424 MBytes  0.04 GBytes/sec                  sender
[  5]   0.00-10.13  sec   425 MBytes  0.04 GBytes/sec                  receiver

如果你也出现了这个情况,大概率是因为有线网络的路由优先级高于雷电网络,你可以调整网络的优先级来解决问题,或者让设备之间只使用雷电数据线进行连接。

我这边触发了“笔记本电脑的无线网卡”到“NUC有线网络”的数据传输链路。所以,当我将 NUC9 连接的网线拔掉,让设备之间仅有雷电连接后,再次进行测试,发现传输速度确实稍有提升。

但是,提升的速度没有达到预期,这里还需要做两个简单的操作:手动设置设备的 IP、掩码,以及 MTU(比如设置为 9000)。当完成设备相关数值的设置后,再次进行测试,能够看到我们已经能够使用万兆的速度来传输数据啦:

Connecting to host 192.199.199.110, port 5201
[  5] local 192.199.199.100 port 63400 connected to 192.199.199.110 port 5201
[ ID] Interval           Transfer     Bitrate
[  5]   0.00-1.00   sec  1.01 GBytes  1.01 GBytes/sec                  (omitted)
[  5]   1.00-2.00   sec  1.13 GBytes  1.13 GBytes/sec                  (omitted)
[  5]   2.00-3.00   sec  1.20 GBytes  1.20 GBytes/sec                  (omitted)
[  5]   0.00-1.00   sec  1.13 GBytes  1.13 GBytes/sec                  
[  5]   1.00-2.00   sec  1.13 GBytes  1.13 GBytes/sec                  
[  5]   2.00-3.00   sec  1.17 GBytes  1.17 GBytes/sec                  
[  5]   3.00-4.00   sec  1.19 GBytes  1.19 GBytes/sec                  
[  5]   4.00-5.00   sec  1.13 GBytes  1.13 GBytes/sec                  
[  5]   5.00-6.00   sec  1.13 GBytes  1.13 GBytes/sec                  
[  5]   6.00-7.00   sec  1.18 GBytes  1.18 GBytes/sec                  
[  5]   7.00-8.00   sec  1.12 GBytes  1.12 GBytes/sec                  
[  5]   8.00-9.00   sec  1.23 GBytes  1.23 GBytes/sec                  
[  5]   9.00-10.00  sec  1.18 GBytes  1.18 GBytes/sec                  
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bitrate
[  5]   0.00-10.00  sec  11.6 GBytes  1.16 GBytes/sec                  sender
[  5]   0.00-10.00  sec  11.6 GBytes  1.16 GBytes/sec                  receiver

iperf Done.

这里不指定 iperf3 的格式化参数,传输速度可能会更直观一些:

# iperf3 -c 192.199.199.110   -Z      
Connecting to host 192.199.199.110, port 5201
[  5] local 192.199.199.100 port 52954 connected to 192.199.199.110 port 5201
[ ID] Interval           Transfer     Bitrate
[  5]   0.00-1.00   sec  1.14 GBytes  9.75 Gbits/sec                  
[  5]   1.00-2.00   sec  1.16 GBytes  9.97 Gbits/sec                  
[  5]   2.00-3.00   sec  1.16 GBytes  10.0 Gbits/sec                  
[  5]   3.00-4.00   sec  1.17 GBytes  10.0 Gbits/sec                  
[  5]   4.00-5.00   sec  1.17 GBytes  10.0 Gbits/sec                  
[  5]   5.00-6.00   sec  1.16 GBytes  10.0 Gbits/sec                  
[  5]   6.00-7.00   sec  1.16 GBytes  10.0 Gbits/sec                  
[  5]   7.00-8.00   sec  1.16 GBytes  9.99 Gbits/sec                  
[  5]   8.00-9.00   sec  1.16 GBytes  9.96 Gbits/sec                  
[  5]   9.00-10.00  sec  1.17 GBytes  10.0 Gbits/sec                  
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bitrate
[  5]   0.00-10.00  sec  11.6 GBytes  9.97 Gbits/sec                  sender
[  5]   0.00-10.00  sec  11.6 GBytes  9.97 Gbits/sec                  receiver

iperf Done.

这个速度已经能够达到万兆光纤、万兆电口的速度啦,理论上雷电组网的速率还能够进一步挖掘,这个工作会在后续的文章中继续进行。

使用命令行设置网卡的 MTU

简单来说,MTU 会影响数据传输的效率。上文中,我们设置了 MTU 为 9000,这个数值实际上是 macOS 支持的最大值。

上面的操作,其实我们可以用命令行来完成,搭配一些简单的脚本,就能够实现雷电设备连接后的自动化操作了,核心的命令是 networksetup

# networksetup --help | grep MTU

networksetup -getMTU <hardwareport or device name>
networksetup -setMTU <hardwareport or device name> <value>
networksetup -listvalidMTUrange <hardwareport or device name>

上面的三个命令是目前 macOS 支持的 MTU 设置命令,分别是获取网卡的 MTU、设置网卡的 MTU,以及查看系统硬件支持的 MTU 数值范围。

因为命令需要使用到设备名称,所以我们需要通过 networksetup -listnetworkserviceorder 命令来获取所有的可用的网络设备和它的系统名称:

# networksetup -listnetworkserviceorder

An asterisk (*) denotes that a network service is disabled.

(1) USB ACM
(Hardware Port: USB ACM, Device: usbmodem14401)

(2) AX88179A
(Hardware Port: AX88179A, Device: en9)

(3) USB 10/100/1000 LAN
(Hardware Port: USB 10/100/1000 LAN, Device: en7)

(4) USB 10/100/1G/2.5G LAN
(Hardware Port: USB 10/100/1G/2.5G LAN, Device: en12)

(5) Link2TP
(Hardware Port: USB 10/100/1G/2.5G LAN, Device: en12)

(6) Thunderbolt Bridge
(Hardware Port: Thunderbolt Bridge, Device: bridge0)

(7) Wi-Fi
(Hardware Port: Wi-Fi, Device: en0)

(8) iPhone USB
(Hardware Port: iPhone USB, Device: en6)

假设这里我们需想要操作的网卡为 “Thunderbolt Bridge”,那么我们可以执行下面的命令,先来查看这张网卡的 MTU 信息:

# networksetup -getMTU bridge0

Active MTU: 9000 (Current Setting: 9000)

以及使用下面的命令,来设置网卡的 MTU 为 9000:

networksetup -setMTU bridge0 9000

我们不用担心设置会出错,因为在设置的时候,命令会检查你的输入是否在允许范围之内:

# networksetup -setMTU bridge0 65530

Error - 65530 is not in the valid MTU range of 1280-9000
** Error: The parameters were not valid.

SCP 传输实际测试

在不做任何调优的情况下,测试了几次,能够看到传输速度在 450~720 MB/s 之间。和文章开头提到的硬盘能力差别不是太大。

# scp -c aes128-ctr /Users/soulteary/Downloads/ubuntu-22.04.3-desktop-amd64.iso 192.199.199.110:

ubuntu-22.04.3-desktop-amd64.iso                                                                                                                                 100% 4804MB 451.6MB/s   00:10

ubuntu-22.04.3-desktop-amd64.iso                                                                                   100% 4804MB 541.9MB/s   00:08

ubuntu-22.04.3-desktop-amd64.iso                                                                                   100% 4804MB 720.7MB/s   00:06    

ubuntu-22.04.3-desktop-amd64.iso                                                                                   100% 4804MB 691.8MB/s   00:06

当然,除了硬盘本身的写入能力外,这里速度的差异应该还受到了固态磁盘可用缓存、内存缓存等影响,当然,还有加密传输算法的影响,所以相比较上面测试的 1GB/s 的速度而言,有了进一步的降低。

后续实际使用过程中,会考虑使用 SMB3 进行传输,以及更新硬盘,来减少传输性能的损失。

其他思路:ESXi 8 雷电组网支持验证

ESXi 是非常强大的虚拟化系统,在之前的文章中,我们有所提及。但可惜的是,ESXi 中默认是没有可用的雷电驱动的,网上唯一能找到的靠谱内容是多年前苹果雷电外设的内容,驱动是由硬件供应商提供的。

当然,如果我们选择将雷电直通给 ESXi 的具体虚拟机使用,也不是不行,比如将上面的 Ubuntu 操作系统安装在 ESXi 的虚拟机中,然后将雷电网卡和对应的 SSD 直通给设备使用。

相比较直接安装 Ubuntu 而言,这样做的好处是额外做了一个硬件整体的监控程序,以及能够更方便的迁移数据或在保留数据的情况下(毕竟是 NAS,数据和系统基本无依赖关系),使用创建一个操作系统虚拟机副本的方式,进行宿主系统的版本或者软件升级的验证。

新版本的 ESXi 虽然挑设备,但其实对 NUC 9 还是蛮友好的。我验证 NUC 9 使用的 ESXi 版本是 VMware-ESXi-8.0U1c-22088125-depot.zip,如果你想在 NUC9 上安装 ESXi8 ,可以参考早些时候的文章《快速构建和安装干净的 ESXi 8 镜像指南》来折腾一个干净又卫生的安装镜像。

定制 NUC9 使用的 ESXi 8

先使用 docker pull soulteary/easy-esxi-builder:2023.01.29 命令下载 ESXi 容器构建工具:

# docker pull soulteary/easy-esxi-builder:2023.01.29

2023.01.29: Pulling from soulteary/easy-esxi-builder
Digest: sha256:1dbf9eef564c4657a146887603bb38bc079e18bc7144009814bf4b301ff5931a
Status: Image is up to date for soulteary/easy-esxi-builder:2023.01.29
docker.io/soulteary/easy-esxi-builder:2023.01.29

然后将 ESXi 软件包 VMware-ESXi-8.0U1c-22088125-depot.zip、之前文章中提到的 NVMe 驱动、USB 驱动、社区网卡驱动等下在完毕,放在当前目录中,执行下面的命令,得到一个交互式的构建环境:

docker run --rm -it -v `pwd`:/data soulteary/easy-esxi-builder:2023.01.29

分别执行下面的命令,得到一个 600MB 左右的安装镜像文件:

# 添加基础软件包
Add-EsxSoftwareDepot /data/VMware-ESXi-8.0U1c-22088125-depot.zip
# 添加 NVMe 驱动
Add-EsxSoftwareDepot /data/nvme-community-driver_1.0.1.0-3vmw.700.1.0.15843807-component-18902434.zip
# 添加 社区网卡 驱动
Add-EsxSoftwareDepot /data/Net-Community-Driver_1.2.7.0-1vmw.700.1.0.15843807_19480755.zip
# 添加 USB网卡 驱动
Add-EsxSoftwareDepot /data/ESXi80U1-VMKUSB-NIC-FLING-64098092-component-21669994.zip

# 创建一个新的镜像配置
New-EsxImageProfile -CloneProfile "ESXi-8.0U1c-22088125-standard" -name "ESXi-8.0U1c-22088125-standard-nic" -vendor "soulteary"

# 将驱动打进新的镜像配置中
Add-EsxSoftwarePackage -ImageProfile "ESXi-8.0U1c-22088125-standard-nic" -SoftwarePackage "nvme-community"
Add-EsxSoftwarePackage -ImageProfile "ESXi-8.0U1c-22088125-standard-nic" -SoftwarePackage "net-community"
Add-EsxSoftwarePackage -ImageProfile "ESXi-8.0U1c-22088125-standard-nic" -SoftwarePackage "vmkusb-nic-fling"

# 保存新的镜像
Export-EsxImageProfile -ImageProfile "ESXi-8.0U1c-22088125-standard-nic" -ExportToIso -FilePath /data/ESXi-8.0U1c.iso

其他的踩坑说明

雷电 PCIe 扩展卡踩坑

在实际购买过扩展卡之后,个人观点目前市面上的雷电 PCIe 都不建议购买,首先是最高性价比的雷电4 扩展卡挑主板(主板需要固件支持雷电功能),其次是包括性价比不那么高的雷电3 扩展卡,对于 PCIe 接口有要求。

我有一台台式机是联想的“刃 9000K 2023”,这台机器虽然搭载了 Z790 芯片组,但是实际上能够进行扩展的只有一个 PCIe x4 的接口,并且主机设计上,这个接口在显卡的进风口位置,如果安装可能影响显卡的散热。

所以,网络上目前主流的大品牌的雷电 PCIe 扩展卡,在我的场景下均无法使用。包括并不仅限于能够搜索和购买到的联想本家的扩展卡。

联想出品的雷电3扩展卡

不过好在,设备还有一颗 20G/s 的 USB 接口,能够连接 20G/s 的硬盘盒,正巧我有这么一个硬盘盒,后续考虑就用这个硬盘盒来做这台台式机和这台 NAS / DAS 的临时交换空间。

内存的选择和使用

NUC9 i7 和 i9 版本的内存频率可以支持到 3200,但是 i5 版本只能支持到 2666。所以在内存选择上,没必要追求目前的高主频内存,并将高主频内存降级使用,建议使用相对便宜的,合适的内存就好,不必要完全上满,尤其是你不使用虚拟化的时候。

之前测试使用的光威64G内存

在之前测试的时候,我使用了早些时候购买的两根光威 32G 内存,虽然之前购买时还蛮贵的,现在的价格早已降至了当年的 40%。

2021 年支持的新国货订单记录

在跑测试的过程中,因为存在大量数据交换,会时不时“死机”,在排查了一众硬件后,使用 memtest 测试机器,发现了在内存上出现了一些问题。

检测出内存错误

光威厂商还是很靠谱的,大概不到一周的质检售后流程后,很快邮寄回来了两根新的内存。

售后直接换了两条新的内存

不过因为这台机器暂时没有跑比较重的虚拟化,本身 4C8T 的核心数也不算多,就换上了两根从二手市场便宜购置的 16G 内存。目前经过 memtest “烤鸡测试”,发现没有什么问题,在使用 ESXi 进行系统正式替换之前,因为没有大内存使用场景,暂时就不换内存啦。

散热的考虑

因为是 NAS / DAS(直连扩展) 用途,雷电数据线的长度有限,设备会放置在桌面,所以设备发热量的多少,体感还是比较明显的。

NUC 9 连接数据线后的实际位置

所以这里建议不使用带显卡的版本,不使用特别费电或者能够带来不必要热量的硬件扩展,包括并不仅限于万兆网卡、万兆或者 40G/56G 或更高的光纤网卡和光模块。

一根雷电线连接设备,没有额外的发热和太高的成本,真的不香吗?

安装细节拾遗

为了避免一些不必要的麻烦,建议在安装之前,前往 BIOS 关闭 “Secure Boot”。

最后

这篇笔记写于 9 月 1 日,但最近实在是比较忙,所以整理出来时,不知不觉已经月中旬了。

希望在这个月里,能够抽空将这台设备完全配置好,投入使用,更新一篇更为具体和落地的最佳实践 😄

–EOF


本文使用「署名 4.0 国际 (CC BY 4.0)」许可协议,欢迎转载、或重新修改使用,但需要注明来源。 署名 4.0 国际 (CC BY 4.0)

本文作者: 苏洋

创建时间: 2023年09月12日
统计字数: 22330字
阅读时间: 45分钟阅读
本文链接: https://soulteary.com/2023/09/12/cheap-pure-flash-thunderbolt-nas-tossing-notes-nuc9-operating-system-pitfalls.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1006180.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【软件测试】selenium3

自动化测试的概念 自动化测试指软件测试的自动化&#xff0c;在预设状态下运行应用程序或者系统&#xff0c;预设条件包括正常和异常&#xff0c;最 后评估运行结果。将人为驱动的测试行为转化为机器执行的过程。 自动化测试就相当于将人工测试手段进行转换&#xff0c;让代码…

国产视觉检测设备崛起,以AI机器视觉及自研算法破解智造难题

机器视觉作为人工智能的前沿分支之一&#xff0c;被称为智能制造的“智慧之眼”&#xff0c;在工业领域中&#xff0c;能够代替人工完成识别、测量、定位、检测等工作&#xff0c;以实现对设备精密控制及产线智能化、自动化升级。 同时&#xff0c;深度学习和3D视觉的技术升级…

Java本地开发环境搭建

概述 Java语言是企业级应用软件开发语言&#xff0c;本文主要描述Java开发环境的搭建。 如上所示&#xff0c;TIOBE提供2023年9月份全球开发语言的排行榜&#xff0c;其中&#xff0c;Java排名第四&#xff0c;而Python已经跃升到第一位&#xff0c;因为&#xff0c;Python是人…

芯科蓝牙BG27开发笔记6-精简第一个程序

1. 这些IO的控制代码在哪里&#xff1f; 还是蓝牙点灯程序&#xff1a; 首先需要对pinout做一些精简&#xff1a; 为了简化工程&#xff0c;去掉了不必要的IO。 至于PTI接口是什么&#xff0c;怎么用&#xff0c;不知道&#xff0c;现在不考虑&#xff1a; 但是提出以下问题…

第6章_freeRTOS入门与工程实践之创建FreeRTOS工程

本教程基于韦东山百问网出的 DShanMCU-F103开发板 进行编写&#xff0c;需要的同学可以在这里获取&#xff1a; https://item.taobao.com/item.htm?id724601559592 配套资料获取&#xff1a;https://rtos.100ask.net/zh/freeRTOS/DShanMCU-F103 freeRTOS系列教程之freeRTOS入…

应该下那个 ActiveMQ

最近在搞 ActiveMQ 的时候&#xff0c;发现有 2 个 ActiveMQ 可以下载。 应该下那个呢&#xff1f; JMS 即Java Message Service&#xff0c;是JavaEE的消息服务接口。 JMS主要有两个版本&#xff1a;1.1和2.0。 2.0和1.1相比&#xff0c;主要是简化了收发消息的代码。 所谓…

Redis——其他数据类型介绍

概要介绍 Redis中有10种不同的数据类型。之前的blog中介绍了Redis中常见的五大数据类型&#xff1a;String&#xff0c;List&#xff0c;Hash&#xff0c;Set&#xff0c;ZSet。而Redis中还有许多其他的数据类型&#xff0c;一般在特定的场景中使用 Stream 首先介绍一下什么…

笔记本多拓展出一个屏幕

一、首先要知道&#xff0c;自己的电脑有没有Type-c接口&#xff0c;支持不支持VGA 推荐&#xff1a; 自己不清楚&#xff0c;问客服&#xff0c;勤问。 二、显示屏与笔记本相连&#xff0c;通过VGA 三、连接好了&#xff0c;需要去配置 网址&#xff1a;凑合着看&#xff…

代码随想录算法训练营Day42 | 动态规划(4/17) 0-1背包问题理论基础 LeetCode 416.分割等和子集

开始背包问题的练习&#xff01; 1. 背包问题的理论基础 对于面试的话&#xff0c;其实掌握01背包&#xff0c;和完全背包&#xff0c;就够用了&#xff0c;最多可以再来一个多重背包。这里附上代码随想录的图&#xff0c;可以对背包问题进行一个分类。 1.1 十分重要的基础&a…

Java class 文件安全加密工具对比与ClassFinal实战

文章目录 前言常见加密方案对比XJarProGuardClassFinal ClassFinal实战纯命令方式maven插件方式 写在最后 前言 相信不少的同学开发的软件都是用户商业化&#xff0c;对于这些商业运营的项目很多都会直接部署在客户方&#xff0c;这样就可能会导致项目源码泄露。当然&#xff…

每日一题~中序后序遍历构造二叉树

题目描述&#xff1a; 思路分析&#xff1a; 后序遍历分析图 中序遍历分析图 不难看出后序遍历的结果中的最后一个元素就是根节点&#xff0c;倒数第二个元素则是根节点的右子树的根节点&#xff0c;而倒数第三个元素是右子树的新右子树的根节点&#xff0c;依次类推。我们可…

部署ik分词器

部署ik分词器 案例版本&#xff1a;elasticsearch-analysis-ik-8.6.2 ​ ES默认自带的分词器对中文处理不够友好&#xff0c;创建倒排索引时可能达不到我们想要的结果&#xff0c;然而IK分词器能够很好的支持中文分词 ​ 因为是集群部署&#xff0c;所以每台服务器中的ES都需…

springboot redisTemplate.opsForValue().setIfAbsent返回null原理

一、版本 springboot版本&#xff1a;spring-boot-starter-data-redis 2.1.6 redisson版本&#xff1a;redisson-spring-boot-starter 3.11.5 二、场景 Boolean res redisTemplate.opsForValue().setIfAbsent("key","value");以上代码同一时间多次执行…

【校招VIP】常用产品分析之数值分析能力

考点介绍&#xff1a; 产品的生命周期各个阶段都伴随着产品数据的变化&#xff0c;产品经理根据这些数据来判断产品所在阶段并对后期的产品演进进行合理的规划&#xff1b;在产品需求分析阶段&#xff0c;通过数据分析来鉴别用户需求的真伪&#xff1b;在产品上线后&#xff0c…

向量范数及其Python代码

【向量范数】 向量由于既有大小又有方向&#xff0c;所以不能直接比较大小。 向量范数通过将向量转化为实数&#xff0c;然后进行向量的大小比较。 所以&#xff0c;向量范数是用于度量“向量大小”的量。 设向量 &#xff0c;则有&#xff1a; ● 向量的 范数&#xff1a; ●…

IO和进程day06(线程续、同步线程互斥)

今日任务&#xff1a; 1.代码 #include <stdio.h> #include <string.h> #include <stdlib.h> #include <pthread.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <pthread.h> #include <u…

10分钟带你深入理解JavaScript的执行上下文和闭包机制

&#x1f3ac; 岸边的风&#xff1a;个人主页 &#x1f525; 个人专栏 :《 VUE 》 《 javaScript 》 ⛺️ 生活的理想&#xff0c;就是为了理想的生活 ! ​ 目录 &#x1f4da; 前言 &#x1f4d8; 一. JavaScript中的闭包 &#x1f4d8; 二. 执行上下文与闭包 &#x1f4d…

03-Redis主从架构

上一篇&#xff1a;02-Redis持久化 1.主从架构搭建 配置从节点步骤&#xff1a; 1、复制一份redis.conf文件 2、将相关配置修改为如下值&#xff1a; port 6380 pidfile /var/run/redis_6380.pid # 把pid进程号写入pidfile配置的文件 logfile "6380.log" dir …

使用亚马逊云科技Amazon SageMaker,为营销活动制作广告素材

广告公司可以使用生成式人工智能和文字转图像根基模型&#xff0c;制作创新的广告素材和内容。在本篇文案中&#xff0c;将演示如何使用亚马逊云科技Amazon SageMaker从现有的基本图像生成新图像&#xff0c;这是一项完全托管式服务&#xff0c;用于大规模构建、训练和部署机器…

PPPoE适用于Linux操作系统的指南

欢迎来到本文&#xff0c;亲爱的Linux用户&#xff01;今天&#xff0c;我将为你提供一个完整的指南&#xff0c;教你如何在Linux操作系统上设置和配置PPPoE连接。无需担心复杂性&#xff0c;跟着我一步一步来&#xff0c;你将轻松掌握这一技能&#xff01; 第一步&#xff0c…