ARTICLE DETAIL

资讯详情

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

Linux性能基准测试实战:主流压测工具与流程详解

Linux性能基准测试实战:主流压测工具与流程详解 做 Linux 运维和性能调优的人迟早会撞上一个词Benchmark。说白了就是拿一套标准化的测试工具在固定负载下把服务器的 CPU、内存、磁盘、网络这几大件挨个“称”一遍得到可对比的数值。我刚入行时也觉得跑分挺虚的直到有一回生产大促前做扩容采购的机器参数看参数都挺好上压测才发现某一批 NVMe 在混合读写场景下掉链子。从那以后我就养成了习惯凡是新机器上线、驱动更新、内核升级、虚拟化平台调整都要先跑一轮 Linux Benchmark 测试工具做底数留档。这篇内容主要写给两类人一类是刚接手服务器、想知道手上机器真实水平的运维新手另一类是被领导要求“做个性能对比”但不知道从哪下手的开发或测试。我会把主流的压测工具按 CPU、内存、磁盘、网络四个维度拆开讲再带你完整跑一遍我的日常压测流程最后把我在真实环境中踩过的坑尤其是那些测试结果互相打架、数据对不上的情况一次性抖出来。1. 先搞清楚 Benchmark 到底在回答什么问题很多人上来就装软件、跑命令、看分数但没想明白自己到底要回答什么问题。Benchmark 不是日常监控它做的是“在可控条件下制造最大压力把硬件能力的上限和拐点逼出来”。这套思路能解决的问题本质上只有三类。1.1 性能基线、容量规划、回归对比三个最常见的场景第一类是性能基线。新采购的服务器、刚装好的操作系统、调整过 BIOS 之后的机器都得跑一遍底层数据。以后出了问题才知道“正常”是什么样子。第二类是容量规划。比如你要上 200 个容器每个容器分配 2 核 4G那这台 64 核 256G 的物理机到底扛不扛得住裸金属的单点瓶颈是 CPU 还是内存带宽得靠压测数据推算不能全靠拍脑袋。第三类是回归对比也是最容易被忽略的。内核从 5.4 升到 5.15、业务从裸机迁到虚拟机、驱动固件更新了性能是升了还是降了必须用同样的工具、同样的参数在前后各跑一遍用数据说话。这里我要多说一句日常看到的 top、free、iostat以及 Grafana 上的监控曲线负责回答“现在系统忙不忙”而 Benchmark 负责回答“这台机器在最严苛的负载下到底能出多少活”。两套东西是互补的监控解决“发生了什么”压测解决“能扛多大”。1.2 选工具前必须先定指标矩阵选工具之前我习惯先画一张指标矩阵把要测的维度和关注项列清楚。CPU 维度看的是整数运算、浮点运算、核心扩展性内存维度看的是带宽和延迟磁盘维度看的是顺序读、顺序写、随机读、随机写这四大件再加一次混合读写网络维度看的是 TCP 吞吐量、并发连接数和 UDP 性能。定好矩阵再选工具思路就顺畅了。我日常最常用的组合是CPU 用 sysbench 和 stress-ng内存用 sysbench memory 和 lmbench磁盘用 fio网络用 iperf3整机综合跑分用 UnixBench。这些不是平台自带的但都是活跃维护的开源工具包管理器里基本都有装起来不费劲。后面我会逐个讲包括它们的局限性和替代方案。2. 按使用场景梳理 Linux 主流的 Benchmark 工具网上关于 Benchmark 工具的清单一搜一大把但多数只是把名字列出来没告诉你它适合什么场景、有什么坑。这里我按自己的实战经验重新梳理一遍希望能帮你少走弯路。2.1 CPU 与内存sysbench、stress-ng、7z 实测经验sysbench 是我最常用的 CPU 压测工具原因是它足够简单又足够稳定。它的 CPU 测试模式是计算一定范围内的质数通过--cpu-max-prime控制计算量得分就是每秒完成的事件数。这个测试虽然偏整数运算但胜在结果稳定、可复现性高特别适合做前后对比。如果你想同时压满所有核心配合--threads参数就行。stress-ng 则是另一个极端它有上百个压力场景可以做非常细粒度的压力制造。比如我想模拟高上下文切换、模拟页错误风暴、模拟内存带宽饱和它都能实现。它更适合做“压测到崩溃找极限”的场景但对结果横向对比不友好因为场景太多标准不统一。还有一个我经常用的偏门工具是7z b它调用 7-Zip 的压缩解压算法能同时测到 CPU 的整数运算、内存带宽和并行能力。跑完会输出 MIPS 分数在对比同型号 CPU 的工程样品和正式版时特别好用。如果不想装太多工具7z b可以当轻量 CPU 压测的备选。内存方面sysbench memory 模式也有专门的测试它通过分配指定大小的内存块并执行读写操作来测试传输速率。注意它默认是顺序读写如果要做随机访问的延迟测试还得用 lmbench 的bw_mem和lat_mem_rd。lmbench 的老牌地位不用多说但编译时容易报错需要装好 gcc 和 make建议直接用发行版包管理里的版本。2.2 磁盘压测fio 是绕不开的重武器磁盘性能测试我基本只用 fio。它的地位在存储领域相当于“手机界的相机评测标准”测试结果是否可信关键看参数怎么配。fio 的强项是可以用 job 文件描述任意 IO 模型顺序读、顺序写、随机读、随机写、混合读写每种场景还能叠加队列深度、IO 引擎、块大小、同步或异步模式。这里必须提醒一句千万别用dd去测磁盘性能。dd走的是系统缓冲结果受 page cache 影响太大第二遍跑出来的数据经常比第一遍高好几倍测出来的完全是“缓存命中”的数字不是真实磁盘能力。fio 则可以通过direct1绕过缓存直接访问设备测出来的数据才具有参考意义。后面第三节我会给出一套完整的 fio job 配置你可以直接抄作业。2.3 网络带宽iperf3 的正确打开方式网络性能测试首选 iperf3它基于 TCP 和 UDP 开发测的是两台机器之间的最大可用带宽。我见过不少人把它当成“测延迟”的工具其实延迟测量需要另外的工具比如ping、mtr或者qperf。iperf3 主要干两件事TCP 吞吐和 UDP 速率、丢包率。注意 iperf3 和 iperf2 不同iperf3 默认是单线程的要跑满多队列网卡必须用-P参数起多个并发流。而且它只支持一个客户端连接服务端不适合做“多客户端连一个服务端”的并发测试。这类场景需要换成 iperf2 或者 netperf。这些细节我在问题排查那一段还会展开这里先不啰嗦。2.4 整机综合跑分与自动化UnixBench、Phoronix Test Suite如果要做整机综合性能对比逃不开 UnixBench。它是一套老牌的 Unix 综合性能测试包含系统调用、进程创建、管道吞吐、Shell 脚本执行等一系列测试项最后给出一个评分。虽然单项测试的算法偏老但正因为算法固定它才适合做跨架构、跨操作系统之间的整机对比比如 ARM 和 x86 的对比、Linux 和不同发行版的对比。另一款要重点提的是 Phoronix Test Suite。它是个自动化测试框架集成了成百上千种测试用例从编译内核到跑图形渲染全都有。它的核心价值是标准化和自动化同一套测试在 A 机器跑完换到 B 机器跑结果直接生成对比报告归档起来非常方便。做长期性能跟踪时我通常会用 PTS 的脚本定期触发压测任务比手工一条条跑命令省心得多。3. 动手实录从零搭建一套可复现的压测流程理论讲再多不如跑一遍实在。这一节我完整复现一次我在物理机上做性能基线的过程包括环境检查、工具安装、参数配置和结果解读。这套流程可以直接拿来当模板。3.1 第一步采集硬件信息和系统配置压测前先记录硬件信息这是很多人忽略的一步。没有准确的硬件信息结果跑到最后根本没办法解释。我至少会采集这些内容# CPU 型号、核心数、线程数、频率 lscpu # 内存容量和类型 sudo dmidecode -t memory | head -50 # 磁盘型号、固件版本、容量 lsblk -d -o NAME,MODEL,SERIAL,SIZE smartctl -i /dev/nvme0n1 # 网卡型号和速率 lspci | grep -i ethernet ethtool eth0 # 当前系统版本和内核 cat /etc/os-release uname -a跑完这些命令后把输出存成一个文本文件命名带上日期和机器名。比如srv-node01-20250105-hardware.txt。以后出问题再对比这个文件就是最原始的底账。这里特别看两个容易被忽略的点一是 CPU 的 governor也就是频率调节策略。压测前必须确认它是performance模式而不是powersave否则频率上不去结果会偏低很多。二是 NUMA 架构信息。凡是想压满整台物理机性能的测试都要关注进程是不是都跑在了某一个 NUMA node 上导致另一个 node 的内存带宽闲置。3.2 第二步安装工具工具安装不展开讲太多Debian 系和 RedHat 系分别用对应的包管理器就行# Debian/Ubuntu sudo apt install -y sysbench stress-ng fio iperf3 lmbench sudo apt install -y unixbench # 部分仓库可能没有需要源码编译 # RHEL/CentOS/Rocky sudo dnf install -y sysbench stress-ng fio iperf3Phoronix Test Suite 建议直接用官方脚本安装它能自动拉取依赖和测试用例curl -fsSL https://phoronix-test-suite.com/install.sh | bash安装完成后先快速确认工具都能正常调用sysbench --version、fio --version。我遇到过 AIO 引擎相关的内核模块没加载导致 fio 报错的情况后面第五部分会说排查方法。3.3 第三步sysbench CPU 和内存压测详解CPU 压测我用的命令是sysbench cpu --threads32 --time60 --cpu-max-prime20000 run--threads32是并发线程数一般设置成物理核心数不要直接设成超线程数否则结果会虚高。--time60是压测时长基线测试我至少跑 60 秒。--cpu-max-prime20000是质数范围值越大计算量越大线程间竞争也更充分。跑完看events per second这个数值就是 CPU 能力的相对指标。对比测试时这三个参数必须完全一致否则结果没有可比性。内存压测我分两部分。先用 sysbench 快速测带宽sysbench memory --memory-block-size1M --memory-total-size30G --threads32 run--memory-block-size1M表示每次读写 1MB 块--memory-total-size30G表示总共读写 30GB 的数据量总数据量要明显大于 CPU 缓存容量否则数据都命中 L3 缓存了测到的是缓存速度不是内存速度。再用 lmbench 测延迟lmbench/bin/lat_mem_rd 256M 256参数含义是 256MB 范围内的随机读延迟遍历 256 次。输出会按从 0.5MB 到 256MB 的容量分档给出延迟重点关注 64MB 之后趋于稳定的部分那个数值基本反映了内存访问的真实延迟。3.4 第四步fio 磁盘四类典型场景磁盘压测最关键的环节是写 fio job 文件。我不会用一句话的长命令因为 job 文件可以存档、复用还能保证不同批次测试的参数完全一致。下面是一份完整的fio-baseline.ini[global] ioenginelibaio direct1 bs4k iodepth32 size8G runtime120 time_based1 group_reporting1 filename/dev/sdb [seq-read] rwread stonewall [seq-write] rwwrite stonewall [rand-read] rwrandread stonewall [rand-write] rwrandwrite先说这些参数为什么这么配。ioenginelibaio是 Linux 异步 IO 引擎能充分发挥 SSD 的并发能力。direct1跳过页面缓存直接读设备测的是真磁盘性能。bs4k是块大小这是最接近数据库在线事务处理负载的块大小云厂商标称的“4K 随机读 IOPS”也是这么测的。iodepth32是队列深度表示同时挂起 32 个 IO 请求模拟生产环境的高并发。size8G是每个作业操作的数据量取设备空间的适当比例避免拿整块盘做测试导致数据丢失。runtime120配合time_based1让测试固定持续 120 秒。运行方式fio fio-baseline.ini跑完后重点读IOPS和BW数值别只看clat平均值。新盘顺序读 IOPS 高但延迟大随机读性能差的盘往往 clat 会异常波动。响应时间的百分位数据才更接近真实体验。需要特别注意的是上面这份配置会把/dev/sdb上已有数据全部写坏正式环境千万别直接对数据盘跑写测试。我一般只在空盘、或者专门的测试盘上做写压测。如果一定要在生产磁盘上测请把filename指向一个新建的临时文件并加上size4G这种受控大小而不是写满全盘。3.5 第五步iperf3 双向带宽测试iperf3 测的是两台机器之间的网络吞吐。先在服务端启动监听iperf3 -s -p 5201然后在客户端发起测试iperf3 -c 10.0.0.1 -p 5201 -t 60 -P 8-P 8表示同时开 8 个并发流这样才能把多队列网卡带宽打满。单向测完后我还会把/etc/rc.local或 systemd 服务里两边角色互换再测一次因为很多业务流量是双向的而网卡收发路径性能并不总是一致。UDP 模式一般用来测网络的极限丢包率命令是iperf3 -c 10.0.0.1 -u -b 10G -t 30通过调整-b的值观察丢包率从 0% 开始上升的拐点这个拐点对应的带宽才是网络的实际容量。生产环境里带宽拐点和监控曲线上的应用吞吐量对照起来看非常直观。3.6 记录结果并做批次化管理每跑完一轮我的习惯是把原始输出完整保存下来不要只摘抄几个关键数字。因为有些结论可能是在后来才发现数据有问题的原始输出里才有线索。我自己的目录结构是bench-results/ node01/ 20250105_r1/ hardware-info.txt sysbench-cpu.txt sysbench-memory.txt fio-baseline.txt iperf3-tcp.txt如果要跑多轮求平均可以用脚本批量执行。这个不展开了但建议至少跑 3 轮取中位数而不是平均值因为第一轮往往会因为缓存预热、频率爬升等因素偏高中位数更能代表稳定性能。4. 压测结果怎么解读别被数字带偏很多新手看到结果把几个 IOPS 数字往报告里一贴就完事但这一步恰恰是最容易翻车的。数据差得离谱常常不是硬件问题而是你的解读方式有问题。4.1 相同硬件不同 Benchmark 测法结果可能差好几倍我拿一块中端 SSD 举例用fio --bs128k --rwread --iodepth128测顺序读能轻松跑到 3GB/s 以上换fio --bs4k --rwrandread --iodepth1测单队列随机读可能只有 3000 IOPS 出头。测出来的数字一个像固态盘一个像机械盘不是盘缩水了而是测试模型完全不同。所以解读任何 Benchmark 结果第一件事是回头看测试参数而不是看结论。看到有人报“这块盘性能不错4K 随机读 80000 IOPS”得问一句队列深度是多少、几线程跑的。队列深度 1 和队列深度 64 的结果没有可比性。第二件事是确认结果图里的单位。fio 输出的BW可能是 KiB/s 也可能是 MiB/siperf3 默认输出 Mbits/secsysbench 则用 events/sec这三个维度单位完全不同。往报告里写的时候我建议统一换算成业务侧能看懂的指标比如数据库关注 IOPS 和延迟百分位视频存储关注顺序带宽 MB/s。4.2 结果的波动来源节能策略、超线程、NUMA、虚拟化CPU 频率波动是最大的隐性干扰源。现在服务器 CPU 都支持动态调频powersave模式下频率会降到标称基础频率以下测出来的结果可能只有performance模式的 70%。所以在压测脚本开头我一般会先执行cpupower frequency-set -g performance # 验证当前策略 cpupower frequency-info超线程也会带来干扰。跑 CPU 压测时如果线程数设成了逻辑核数超线程的两个逻辑核会争抢同一个物理核的执行单元跑分反而可能低于只用物理核的数量。这个在不同代数 CPU 上表现差异很大建议 32 物理核的机器先试--threads32再试--threads64记录差异。服务器上如果开了超线程这个数据对你的服务部署形态很有参考价值。NUMA 架构的影响在内存压测里最明显。如果你把 32 个线程全部绑定在 node0 的 CPU 上但内存却分配到了 node1跨 node 访问内存的延迟会远高于本地内存。用numactl --hardware查看节点分布后建议用numactl --cpunodebind0 --membind0跑关键测试避免调度器把线程打散到不同 node 上导致数据抖动。另外只要机器上有 KVM、Docker、QEMU 这类虚拟化层裸金属测试结果就不能直接等同于容器内结果。容器有 cgroup 的 CPU 配额和 IO 限制虚拟机有虚拟化开销和抢占风险。所以我做对比时有个习惯物理机裸测是一套数据容器内再测一套两端差出来的部分就是虚拟化平台消耗的那部分性能。4.3 做前后对比时尽量保证哪些变量不变回归测试的可靠性取决于变量的控制。我自己有一个“压测变量清单”每次对比前逐项核对内核版本和启动参数特别是isolcpus、nohz_full这类影响调度的参数CPU 调频策略统一设为performanceBIOS 级别设置包括超线程开关、睿频开关、NUMA 相关选项磁盘文件系统类型和挂载参数比如noatime、barrier这些是否一致网络压测时确认对端机器也没有额外负载有一回我对比两台同型号机器A 机器结果明显好于 B排查半天发现 B 机器的磁盘分区恰好挨着另一个高负载 VM 的虚拟磁盘底层存储互相抢 IO 资源。这种环境因素不控制好跑多少次都没用。5. 常见问题与排查技巧实录最后这部分我把过去几年经常被问到、以及自己翻过车的几个问题集中整理一下。每一段都是踩过坑之后摸索出来的处理方式。5.1 压测时 CPU 频率忽高忽低结果乱飘表现是 sysbench 跑出来的 events per second 每隔几秒就掉一截整体看着像锯齿一样。解决办法就是确认 CPU governor 是否被系统服务改回 powersave。有些发行版自带 TuneD 或 power-profiles-daemon会周期性覆盖手动设置。我的处理方式是# 确认当前模式 cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor # 如果反复变回 powersave创建 systemd 服务固化设置 sudo systemctl disable --now tuned power-profiles-daemon如果做完这些频率还是乱跳再看散热。压测时间长了 CPU 撞到温度墙降频表现也是频率周期性跌落这时要用sensors查温度看 CPU package 温度是否接近 Tjmax。这种降频在笔记本和刀片服务器上尤其常见。5.2 fio 随机写测试降速、结果远低于标称值一个典型现象是 fio 随机写跑到一半IOPS 突然掉头向下。这不是磁盘坏了多半是触发了 SSD 的写缓存耗尽和垃圾回收机制。消费级 SSD 的 SLC Cache 用完后写入速度会大幅下降企业级盘虽然好一些但长时间高负载写测试也会进入稳态期。这时候如果只是做基线建议加一项 fio 的状态监测# 测试过程中实时查看块设备状态 iostat -dx 1看到aqu-sz或者%util猛涨基本可以确认是存储固件在搬数据。正确做法是把压测分成预热阶段和正式测试阶段或者直接用fio --stonewall把顺序写和随机写分别跑避免相互影响。另外注意老盘剩余空间不足时写放大效应明显建议测试盘保留至少 20% 空余空间。5.3 iperf3 单线程跑不满带宽iperf3 单线程速度上不去这个我见得太多了。前几代 CPU 网卡单队列场景下一个进程很难把 10G 网卡跑满。解决思路是提高并发-P 8起多流。但如果加了并发还是上不去就要查瓶颈在哪。先看 CPU 占用是不是打满一个核软中断都堆在一个核上然后用ethtool -S eth0看中断分布再考虑设置网卡多队列# 查看网卡队列数 ethtool -l eth0 # 设置队列数量具体以网卡驱动支持为准 ethtool -L eth0 combined 8中断绑核比较繁琐但对延迟敏感的测试场景效果非常明显。排查时还有一个简单工具让 iperf3 服务端换到另一台机器排除是网线、对端网卡的问题。5.4 压测进程被 OOM Killer 杀掉内存测试或者整机压力测试时进程突然消失dmesg里能看到Out of memory: Killed process。通常是因为测试配置的总内存需求超过物理内存系统不得不杀掉进程保护整体。解决办法是合理设定测试规模。sysbench memory 的--memory-total-size不要超过物理内存的一半fio 的size要特别小心如果文件写在 tmpfs 或满盘场景下很容易超限。另外在被测机器上临时关闭 OOM Killer 并不可取因为压测进程一旦失控整机可能直接宕机稳妥做法是把测试进程的 OOM 分数调低# 对测试进程临时设置 echo -1000 /proc/PID/oom_score_adj5.5 压测结果受其他进程干扰严重如果机器上还有业务进程跑着压测数据大概率不准。我通常用 cgroup 把基准测试单独隔离起来或者干脆在专用机器上跑。但现实环境往往做不到完全干净所以至少要记录压测期间机器上还有什么进程。用ps -eo pid,comm,%cpu,%mem --sort-%cpu | head -20在压测前后各截一份快照附在测试记录里。如果是短时间测试还可以用taskset把压测进程绑到特定 CPU 核上避开业务进程所在的核。比如机器有 64 核业务跑在 0-31 核压测就绑到 32-63 核taskset -c 32-63 sysbench cpu --threads32 run这样至少能保证同一台机器上多次测试之间的相对一致性。5.6 工具死活装不上或运行报错fio报io_setup() failed这类错误多半是系统aio-max-nr限制太低调一下参数就能解决sysctl -w fs.aio-max-nr1048576lmbench 源码编译报错的时候不要硬和头文件较劲优先用发行版的包比如 Debian 系直接apt install lmbench。Phoronix Test Suite 安装时如果依赖下载慢可以配置国内镜像源但具体镜像地址根据不同发行版会有差异自行搜索即可。最后说一句实在话Benchmark 跑出来的数字是“对照值”不是“真值”。它最大的意义不在于把硬件性能量化到某个精确的点而在于让你手里有一把尺子能在更新、迁移、扩容之后重新量一量。我的习惯是每台新机器上线前必跑一轮完整压测然后把结果归档到固定目录留好环境信息。以后不管谁问我机器性能怎么样我直接甩一个测试报告出来比嘴上解释一百句都有说服力。
返回列表