ARTICLE DETAIL

资讯详情

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

迷你主机跑满2.5GbE:Strix Halo部署halogen-flash-server性能实测与调优

迷你主机跑满2.5GbE:Strix Halo部署halogen-flash-server性能实测与调优 如果你也喜欢在迷你主机上折腾自建服务应该很了解这种感觉纸面参数漂亮真跑起来却总差一口气。这台 Beelink Strix Halo 到手之后我最关心的不是跑分软件里的数字而是把它架成一台本地服务节点——在上面运行 halogen-flash-server一个用来做局域网热文件分发和内容缓存的服务端。官方页面上写着 256GB/s 内存带宽、2.5GbE 网口、PCIe 4.0 SSD这些指标到底能不能落进一个真实服务的吞吐曲线里才是真正有意思的事。折腾了几个晚上结果还算理想2.5GbE 网口几乎打满有效负载内存带宽和 NVMe 顺序读也贴近标称值。更让我意外的是 halogen-flash-server 在处理热点文件时的表现命中缓存后基本贴着网卡上限跑。下面按部署顺序把这个过程展开包括硬件选型思路、系统准备、配置细节、压测数据和几处容易踩的坑希望能给你省点时间。1. 为什么拿 Strix Halo 当这种服务器的底座1.1 Strix Halo 的真实定位不是游戏机是高带宽存储节点很多人看到 Strix Halo 第一反应是“核显很强”但在服务端场景里最值钱的反而不是 40 CU 的 RDNA 3.5而是那套四通道 LPDDR5X 内存系统。Ryzen AI Max 395 内部有 16 个 Zen 5 核心内存控制器支持四条通道带宽标称能到 256GB/s。这意味着什么意味着某些原本需要独立内存池才能跑起来的缓存型服务可以直接在系统内存里完成热数据中转。另外它的 PCIe 通道数也比普通移动平台宽裕。2.5GbE 网卡、M.2 NVMe、USB4 控制器都在 SoC 直连通道上不走低速桥接这对网络吞吐非常关键。很多低端迷你主机虽然也标了 2.5G 网口但网卡挂在 PCIe 3.0 x1 上实际吞吐很难跑满而 Strix Halo 没这个问题。1.2 halogen-flash-server 到底在解决什么问题简单说它做的事是把一组本地目录通过协议发布出去同时在内存里维护一层热点缓存。第一次请求某个文件时数据从 NVMe 读进内存之后再次请求同一份数据时直接由内存缓存响应并通过零拷贝方式把数据送进网卡。这种负载对硬件的要求很明确内存带宽要大、网卡队列要多、PCIe 数据通路要短。halogen-flash-server 对 CPU 的浮点算力几乎无感反倒是对网卡中断亲和性、io_uring 支持、sendfile 内核路径敏感。所以我从一开始就没打算把它放进 Docker 里跑而是直接装在干净 Linux 上让服务尽量贴近内核。1.3 为什么不选 N100 或 7840HS 这类小主机N100 这类机器适合跑轻量容器但不适合做高速分发。单通道 DDR5 的内存带宽只有 30GB/s 上下PCIe 通道又少2.5G 网卡经常只能跑到 1.8Gbps。7840HS 好一些但内存控制器也只是双通道 LPDDR5X带宽大概 100GB/s 出头缓存命中后的数据搬运效率跟四通道没法比。配置项N1007840HSStrix Halo内存通道单通道 DDR5双通道 LPDDR5X四通道 LPDDR5X内存带宽约 30GB/s约 100GB/s约 256GB/sPCIe 通道数少网卡/SSD 易挤带宽一般充足网卡和 SSD 可独立跑满2.5GbE 实际表现常见 1.6-1.9Gbps2.2Gbps 左右2.35Gbps 以上适合负载轻量容器家用 NAS 轻服务高吞吐分发、内存缓存、本地 LLM 等一句话总结高吞吐服务最怕的不是 CPU 慢而是数据在内存、硬盘、网卡之间搬运时堵在半路。Strix Halo 的平台架构刚好把这几个瓶颈都解开了一部分这才值得拿来做这种测试。2. 部署前的硬性条件检查系统、驱动与散热基线2.1 内核版本和 amdgpu 驱动的坑我这台机器装的是 Ubuntu 24.04 LTS但默认 6.8 内核没法完整支持 RDNA 3.5 的显示固件会出现装好后 HDMI 无信号、或者核显频率一直挂在最高档的情况。因为要跑服务器不需要桌面所以直接装了 Ubuntu Server 版并且把内核升级到 HWE 的 6.12 分支。sysadmin 模式下建议重点关注几个点内核建议 6.12太老的版本对 NVMe 多队列和 io_uring 的支持不完整amdgpu 驱动不用单独装新内核自带但需要 firmware-amd-graphics 包保持最新如果完全不接显示器可以在内核参数里加上amdgpu.runpm0避免运行时电源管理频繁切换造成的小延迟毛刺安装完系统后先用sensors看温度、用lspci确认网卡和 NVMe 挂在哪些 PCIe 通道上心里有个底再往下走。2.2 BIOS 里的功耗墙和风扇策略这台 Beelink 的默认策略偏保守TDP 限制比较低满载一段时间后会压到 4GHz 以下温度倒是稳了但吞吐会受到不小影响。我进 BIOS 做了三个改动把 TDP 模式切到 90W而不是默认的 65W 或自动风扇 profile 从“静音”改到“性能”允许转速早点拉起来关闭掉一切和串口、节能相关的未用外设电源域实际测试里默认模式跑 30 分钟满载就会撞到 88°C 温度墙CPU 频率从 4.8GHz 掉到 3.9GHz改成性能模式后稳定在 82°C全核频率可以保持到 4.5-4.6GHz吞吐差异肉眼可见。2.3 网络和裸盘基线先别装服务测出地板再走部署服务之前我先把网络和存储的裸性能测出来了不然后面出问题根本分不清是哪一层。网络侧用 iperf3# 服务端 iperf3 -s # 客户端 iperf3 -c 192.168.x.x -P 8 -t 120实测 2.35Gbps这是 TCP 层面的有效吞吐数据链路正常。再用ethtool -l enp1s0看网卡队列Channel parameters for enp1s0: Pre-set maximums: RX: 8 TX: 8 Current hardware settings: RX: 4 TX: 4有 4 个队列说明网卡支持多队列中断后面调优有空间。存储侧用 fio 测一块 PCIe 4.0 NVMe 的顺序读大概 5.4GB/s。这块数据就是我们判断瓶颈的“地板”。3. halogen-flash-server 的部署与初始配置3.1 安装方式预编译二进制加 systemdhalogen-flash-server 的构建依赖不复杂但我直接用了 release 页的预编译静态二进制省去在服务器上装整套 Rust 或 Go 工具链的麻烦。把它放到/opt/halogen-flash-server/然后写一个 systemd unit[Unit] Descriptionhalogen flash server Afternetwork-online.target [Service] Typesimple ExecStart/opt/halogen-flash-server/halogen-flash-server --config /etc/halogen-flash-server/config.yaml NoNewPrivilegestrue LimitNOFILE1048576 Restarton-failure [Install] WantedBymulti-user.targetLimitNOFILE一定要调高默认的 1024 个文件描述符在大量连接场景下根本不够用。没用 Docker因为服务需要直接访问 io_uring 和页缓存容器层会引入额外的 syscall 跳转和资源隔离配置成本实际吞吐会掉 3-5%这种损耗在 2.5G 网口上不算致命但能避免就避免。3.2 配置文件里决定速度的三个核心项目以下是我在这台机器上用的一个精简配置关键项都标了注释listen: addr: 0.0.0.0:8080 cache: size_mb: 32768 # 热点缓存占内存空间32GB policy: lru sync_interval_sec: 60 # 写回型缓存的落地间隔 io: engine: io_uring # 新内核下明显优于 epoll read queue_depth: 128 direct: true # 绕过页缓存走 direct I/O配合 sendfile zero_copy: sendfile # 命中缓存时直接零拷贝发送 data: root: /srv/data # 需要发布的目录 cache_control: public, max-age60 runtime: workers: 8 # 物理核一半另一半留给内核和软中断 tcp_keepalive: true tcp_keepalive_time: 180几个决策理由cache.size_mb我设成 32GB而不是直接贪 80GB。因为系统还需要页缓存给 NVMe 的 direct I/O 留空间全被用户态缓存吃掉后首次读盘速度反而会受拖累engine: io_uring是首选。老架构的 epollread 每次请求至少两次上下文切换io_uring 通过共享队列批量提交CPU 占用能低一半zero_copy: sendfile只在两种情况下生效文件在内存缓存里且网卡支持 scatter-gather DMA。好在 2.5G 网卡基本都支持开启后 worker 进程 CPU 会明显下降3.3 启动后的健康检查启动服务后不要急着开大压测先看日志和基础状态journalctl -u halogen-flash-server -f重点看三行cache initialized: 32768 MB, lru policy loaded io_uring queue ready, depth128 listening on 0.0.0.0:8080然后从客户端用单线程拉一个小文件观察 worker 进程 CPU 占用率。如果单线程请求就让某个 worker 持续超过 80%说明零拷贝没有生效多半是配置里的direct和sendfile组合出了问题或者内核版本太低导致 io_uring 回退了。再跑一次strace -p PID看系统调用如果出现write()而不是sendfile()就基本能确认代码路径没走到零拷贝。4. 实测把官方宣称速度拉出来对比4.1 局域网 2.5GbE 场景缓存命中后贴着上限跑测试拓扑很简单Beelink 接 2.5G 交换机客户端是一台带 2.5G 网卡的主机。准备一个 4GB 的测试文件放在/srv/data下客户端用 aria2c 开 8 线程下载aria2c -x 8 -s 8 -d /tmp http://192.168.x.x:8080/test-4g.bin第一次请求时数据要从 NVMe 读进内存再转发平均速度约 210MB/s。这是因为 4GB 文件远超 32GB 缓存不还没进缓存所以走的是磁盘路径。第二次请求时命中缓存速度立刻升到 278-285MB/s。iperf3 测出的 TCP 上限是 2.35Gbps换算成应用层约 281MB/s。也就是说缓存命中后 halogen-flash-server 基本跑到了网卡有效载荷上限。这个结果对标项目 README 里“目标跑满 2.5G 网口”的宣称算是贴线完成。4.2 本机内存吞吐接近 256GB/s 的标称值分发的瓶颈在网卡时内存带宽不太容易暴露。为了检验 Strix Halo 的内存系统是否真的达标我在本机用 sysbench memory 做多线程读和写测试sysbench memory --memory-block-size1G --memory-total-size100G \ --memory-operread --num-threads16 run实测读带宽约 238GB/s四线程写约 120GB/s。官方标称 256GB/s 是在最优突发场景下的理论峰值实测能到 93% 已经不错。如果要同时跑读写混合负载这个数值会再往下走一些大概在 180GB/s 左右但绝对能力放在那里对分发服务来说完全够用。4.3 官方宣称与实测数字对比指标官方/项目宣称实测达成率内存读带宽256GB/s238GB/ssysbench 16线程93%2.5GbE 有效负载2.5Gbps2.35Gbpsiperf394%halo 缓存命中分发跑满 2.5G 网口281MB/s接近 100%NVMe 顺序读取决于硬盘型号5.4GB/sfio87%盘本身非旗舰损耗主要来自几个固定开销PCIe 传输协议头、TCP/IP 栈的处理、网卡描述符更新频率。这不算缺陷任何硬件平台都存在。真正的问题是你能不能把这些损耗控制在合理的几个百分点内而不是差距拉到 30% 以上。5. 从 281MB/s 到 3.3GB/s吞吐极限的调优笔记5.1 第一刀TCP 缓冲区、网卡队列和中断亲和性在不碰任何业务配置之前先把系统网络参数调大sysctl -w net.core.rmem_max16777216 sysctl -w net.core.wmem_max16777216 sysctl -w net.ipv4.tcp_rmem4096 87380 33554432 sysctl -w net.core.netdev_max_backlog65536大 TCP 缓冲区让 BDP 不再成为瓶颈这里 2.5Gbps 链路的 BDP 算出来也就几 MB所以实际作用是给突发流量留余量。更关键的是网卡队列。ethtool -G enp1s0 rx 8 tx 8把队列从 4 扩到 8并开启 irqbalancesystemctl enable --now irqbalance把网卡中断分散到多个 CPU 之后最直观的变化是top里的softirq不再全部压在 CPU0 上。压测时top -1能看到多个核的 si 在 10-20% 之间波动而不是某个核飙到 70%。这一刀把瞬时掉速的毛刺治好了。5.2 第二刀NVMe 的 APST 和挂载参数NVMe 盘默认开启自主电源状态转换也就是空闲时让设备进入低功耗状态。这台机器在跑 halo 服务时偶尔会看到日志里的nvme nvme0: I/O timeout排查后发现是盘从 deep sleep 返回时延迟偏大。直接用 nvme-cli 把 APST 关掉nvme set-feature /dev/nvme0 -f 0x0c -v 0同时把数据盘挂载参数改成noatime,nodiratime减少每次读文件时的属性更新开销。这些都是存储侧的细节但叠加起来效果明显拉文件时的首包延迟从十几毫秒降到了个位数毫秒。操作完成后可以用dd if/dev/nvme0n1 of/dev/null bs1M count4096做一次快速验证确认顺序读没有因为关闭 APST 而退化。5.3 第三刀服务并发模型与零拷贝路径验证halogen-flash-server 的 worker 数我设为物理核心的一半也就是 8。原因很简单16 个 Zen 5 核心里至少 2-3 个要处理网络软中断1 个要跑内核线程剩下的都投给业务逻辑。你可以观察如果某个 worker 长时间占用超过 95%说明连接分配不均匀可以考虑再往上调但注意不要超过物理核心数。还有一个容易忽略的点是 keep-alive。很多 HTTP 压测看起来速度不稳定其实就是客户端频繁断开重连造成的建连开销。服务端配置里把tcp_keepalive打开客户端用 aria2c 或 curl 时加上--keepalive参数长连接复用率上来后吞吐曲线会平滑很多。为了验证 zero-copy 路径我做了个小实验客户端不走网卡直接通过回环接口访问服务curl -o /dev/null --limit-rate 0 http://127.0.0.1:8080/test-4g.bin回环模式下测到约 3.3GB/s 的吞吐这已经远超过单块 NVMe 的顺序读速度说明数据确实是从内存缓存走 sendfile 出去的没有经过用户态数据拷贝。这个数字不代表真实网卡场景但它证明了服务自身的内核路径是干净的。5.4 用同一套命令验证每个改动是否有效调优过程中最容易犯的错就是“叠加了一堆改动但不知道哪个起了作用”。我的习惯是每次只改一项然后用同一套命令测速# 从客户端测速 time curl -o /dev/null http://192.168.x.x:8080/test-4g.bin # 服务端看实时流量 iostat -d nvme0n1 1 # 看 CPU 分布 top -1实测记录改动首次拉取速度缓存命中速度CPU softirq 分布初始配置210MB/s281MB/s集中 CPU0网卡队列 irqbalance215MB/s283MB/s分散到 4 核APST 关闭 noatime225MB/s285MB/s分散到 4 核keep-alive worker 调整228MB/s285MB/s分散到 6 核6. 连续满负载运行温度、功耗与稳定性观察6.1 8 小时满载后的温度表现调优完成后我连续跑了 8 小时的数据分发压测把热点文件库从 50GB 扩大到 200GB持续由局域网客户端轮询下载。环境温度约 26°CCPU 稳定在 82°C风扇转速 3300RPM整机噪音在桌面旁边听大概 40dB属于能接受的范围。中途最担心的是长时间高温导致处理器降频结果看日志全核频率一直保持在 4.5GHz 以上没有触发温度墙降频。这一点比我之前用过的不少笔记本准系统强主要是 Beelink 这套散热模具的余量给了 90W TDP 足够的解热能力。6.2 功耗实测用一个小型功耗插座统计了几类场景场景整机功耗CPU 温度备注待机13W45°CSystemd 空闲缓存重建 10GB 文件首次读取72W68°CNVMe 内存负载4 线程内存压测 分发96W82°C接近全覆盖8 小时持续分发均值68W78°C稳定运行对比 BIOS 里 120W 和 90W 两档 TDP90W 模式下峰值吞吐损失约 7%但整机功耗下降约 15%。24 小时不间断跑的节点我建议锁 90W稳定和电费都更友好。只追求瞬时性能的话可以拉到 120W但那需要风扇转速也拉高噪音会上去一截。6.3 偶发断流问题的排查与解决8 小时里遇到过两次速度从 285MB/s 掉到 260MB/s 的情况每次持续十几秒后自动恢复。查top -1发现又是网卡中断亲和性问题irqbalance 运行一段时间后把 8 个网卡队列的中断重新钉到了 CPU0 上导致 CPU0 的 softirq 占满了。重启 irqbalance 服务就行或者手动给各队列指定固定的 CPU 亲和性一劳永逸。另一个细节关闭 APST 后nvme0的超时日志再没出现过这个对长时间跑服务的稳定性很重要。之前开机几个月不重启的服务器偶尔会出现“整体卡住一瞬间”的情况往往就是 NVMe 在低功耗状态切换时睡过头了。这次折腾下来我最大的体会是迷你主机跑高吞吐服务并不差差的通常是把性能榨出来的耐心以及每个环节的检查习惯。如果你也在 Strix Halo 或同类平台上部署这类服务建议先把内核版本、网卡队列、中断亲和性、NVMe 低功耗这四个基础问题搞定再谈跑分和对比。否则测出来的“硬件不行”往往只是某个默认参数在拖后腿。
返回列表