
如果你在Linux上跑过业务迟早会碰上这个绕不开的问题这台机器、这套系统、这个服务到底行不行靠“体感”回答不了跑起来卡不卡、响应快不快都太主观想得到一个能说服自己也能说服别人的答案就得用Linux Benchmark测试工具用标准化的方法压一压、测一测让数据出来说话。我最初接触benchmark是因为一台新采购的服务器。运维同事说新机器CPU主频比旧机器高了不少跑同样一套Java服务应该稳了。结果业务上线后接口平均耗时反而涨了查半天没头绪最后用sysbench和fio各跑了一圈才发现瓶颈在磁盘随机读跟CPU一点关系没有。从那时起我就养成一个习惯不管是新机器验收、代码优化对比还是排查疑难性能问题先把benchmark跑一遍让数据帮我缩小范围。这篇文章不会只列工具清单我会把我实际用过的、踩过坑的完整经验拆开讲哪些场景该选什么工具命令怎么敲参数怎么调结果怎么读以及最重要的——为什么你跑出来的数字可能根本不靠谱。如果你也是做运维、做后端开发或者单纯想把手上的Linux机器吃透这篇应该对你有用。1. 为什么说Linux性能不能靠“体感”来判断1.1 Benchmark是什么解决了什么问题很多刚接触Linux的朋友会把benchmark和压力测试混在一起。其实两者是同一类思路在不同阶段的表现benchmark更偏“量一下这台机器在某类负载下的成绩”强调可重复、可对比压力测试更偏“使劲灌流量把系统压垮看它什么时候崩”强调找出上限。实际使用中两者经常互相配合但如果你要告诉别人“这台服务器性能不错”benchmark给出来的数字才是硬通货。Benchmark解决的核心问题有三个第一是可量化把“快不快”变成“每秒能处理多少请求、多少IOPS、多少MB/s”第二是可对比同一套测试方法下A机器和B机器谁更强一目了然第三是可追踪系统升级、参数调整之后数字是变好还是变差一比便知。这也是为什么很多开源项目会把自己跑的benchmark分数贴在项目首页里——比如某些C性能测试不跑个基准分谁也不敢说自己的优化有效果。从业务角度看benchmark的价值更直接。我见过不少同事在优化接口时先凭感觉改配置改完再用压测工具验证。这种做法的问题在于方向不明确如果一开始就用benchmark把CPU、内存、磁盘、网络的基线摸清楚你会很清楚地知道该往哪个方向使劲。比如CPU密集型服务瓶颈大概率在运算能力高并发读服务瓶颈多半在磁盘随机IO或者网络延迟数据库服务内存带宽和磁盘同步写可能才是关键。方向对了优化才不会白费。1.2 分类全景你的业务该测哪一类Linux环境下的benchmark工具太多了先有一个分类框架才不会乱。按被测对象来分大致可以分成五类CPU / 计算性能专注整数、浮点、加密、压缩等计算能力。内存性能带宽、延迟、分配与拷贝效率。磁盘 / 文件系统性能顺序读写、随机读写、不同块大小、不同队列深度下的表现。网络性能带宽、延迟、丢包、并发连接能力。综合性能把上面多类组合在一起模拟真实场景。另有一类专门针对某个应用或语言运行时做基准测试的工具比如针对C的Google Benchmark、针对Java的JMH。这类工具更适合做代码级别的性能回归对比用来回答“我改完这一版代码性能是升了还是降了”而不是衡量整台机器。有了这个分类面对性能问题时先问自己我怀疑瓶颈在哪如果完全没头绪就先跑综合测试再根据结果深入单项测试如果已知方向直接选对口工具别浪费时间去全量压测。效率也是工程的一部分。2. 主流测试工具一览选型之前先看这张表2.1 轻量级专用工具 vs 重量级综合套件工具选型不复杂但很多人一开始容易犯的错是“什么都想装一套”。实际上大多数场景只需要两三个工具就能覆盖。我按自己的使用频率把工具整理成了表格先看再选。工具主要用途安装方式适合谁sysbenchCPU、内存、线程、数据库压测apt/yum/dnf 直接装快速摸基线fio磁盘/文件系统基准包管理器或编译安装存储性能深度测试iperf3网络带宽测试包管理器直接装内网、公网带宽评估ping / traceroute / mtr网络延迟、路径探测系统自带或包管理器快速定位网络问题Phoronix Test Suite综合基准多套件全自动官方脚本/包管理器全面评估、跨机器对比UnixBench类Unix综合性能评分编译安装老牌综合评分stress-ngCPU、内存、IO压力模拟包管理器直接装稳定性测试、温度测试Google BenchmarkC代码级微基准源码/包管理器C项目性能回归表格里的工具我都实际用过。看到这里肯定有人问UnixBench和Phoronix Test Suite是不是重复了不完全重复。UnixBench偏“传统Unix环境下的综合跑分”用几何平均打分适合快速给一台机器算个总分Phoronix Test Suite则是平台级的自动化套件能调度几十种真实应用做测试生成可上传对比的报告。两个工具定位完全不同一个是单项总分型一个是多场景综合型。2.2 我常用的工具组合与适用场景日常工作中我很少一次性装上全部工具一般按场景组合着用。新机器验收时我会先用sysbench快速跑一轮CPU和内存再用fio测磁盘用iperf3测内网带宽相当于给机器拍一张“体检照”。这套组合半小时能跑完足够发现明显问题。比如我曾用这套流程发现某云主机的磁盘延迟比宣传的高出好几倍最后拿着fio的输出找服务商核对对方承认是存储节点超卖。代码优化阶段比如自己的C项目我会用Google Benchmark在代码里埋基准测试同时用sysbench确认基础环境的稳定性确保测试结果不是被机器波动带偏。因为如果你改了一版代码测得性能提升3%结果第二天机器温度变了3%的差异完全可能是噪声。深度性能排查时比如遇到数据库慢查询我会先跑fio的随机读写再用sysbench跑一下数据库压测定位是存储问题还是SQL问题。这个思路比直接看慢日志更接近根因因为慢日志只能告诉你“慢”不能告诉你“为什么慢”。所以选型逻辑不是“哪个工具最强大”而是“当前问题最可能出在哪一层”。先小后大先专项后综合这样最省时间。3. CPU与内存压测sysbench从入门到看懂结果3.1 sysbench的安装与基础参数解读sysbench是我用得最频繁的benchmark工具没有之一。理由很简单安装方便、参数清晰、输出结果可读性好而且几乎每一个Linux发行版的软件源里都有。在Debian/Ubuntu上安装只需一行命令apt-get install -y sysbench在CentOS/RHEL系列上yum install -y sysbench如果用的是比较新的版本也可以dnf install sysbench。装完先看一下帮助了解支持的测试类型sysbench --help里面会列出cpu、memory、threads、mutex、fileio、oltp等测试模块。实际使用中CPU、内存、fileio这三个最常用oltp一般用来做MySQL等数据库的基准压测需要额外配置数据库环境复杂度更高日常快速评估用得少。先看CPU测试的基本命令sysbench cpu --threads4 --time30 --cpu-max-prime20000 run参数拆开看--threads指定并发线程数一般设成物理核心数或逻辑线程数--time指定跑多长时间默认10秒我习惯至少30秒太短容易受瞬时负载影响--cpu-max-prime是核心逻辑让每个线程不断计算质数到指定的最大数值越大单次计算量越大可以理解为“一次考试的题目难度”。这个测试输出的核心指标有两个events完成的事件总数和events per second每秒事件数。每秒事件数越高代表CPU在该类计算负载下的吞吐越高。注意sysbench的CPU测试主要验证整数运算能力不完全等于真实应用的全部性能但它作为快速横向对比已经非常高效。3.2 CPU测试实操与结果解读我会在同一台机器上分别测单线程和多线程因为排查问题时你会发现有些任务是单线程瓶颈有些是多核扩展性问题。你要的数据不是单次分数而是两种模式的差异。单线程测试sysbench cpu --threads1 --time30 --cpu-max-prime20000 run多线程测试sysbench cpu --threads8 --time30 --cpu-max-prime20000 run做完之后对比单线程和多线程的吞吐提升倍数大致能判断这台机器的多核扩展性。如果8线程比1线程提升不到3倍那多核收益就比较低可能是调度问题、超线程问题或者散热降频。举个例子某次我在一台塔式服务器上测8线程的events per second居然比4线程时还低测温才发现散热器积灰严重高负载下CPU已经撞了温度墙。解读结果时还要看一个容易被忽略的信息总耗时。sysbench报告会输出总时间和总事件数。如果time30但实际跑了31秒多说明测试过程中有些事件排队了系统负载偏高。遇到这种情况最好先确认同一时刻没有别的任务在抢占资源否则你测出来的“机器性能”实际上混进了业务负载数字会失真。对于长期运行的服务器我还会顺手执行一下uptime看load average是不是已经很高。如果1分钟负载都大于核心数那直接换一台空闲机器测不用纠结。3.3 内存测试的注意点内存测试命令也简洁sysbench memory --threads4 --memory-block-size1M --memory-total-size10G --memory-operwrite run这里重点看几个参数--memory-block-size是每次操作的数据块大小--memory-total-size是测试总数据量--memory-oper指定读还是写。不同组合对结果影响很大大块顺序读写测的是内存带宽小块随机读写测的是内存延迟和分配效率。我的习惯是分别测write和read。先写后读因为有些系统内存分配策略对首次写入有较大开销如果你只测read结果可能偏高因为写入路径没有跑。多线程内存测试时要注意某些虚拟机或低端处理器在内存带宽争抢时性能跳水很严重如果跑出来的带宽随着线程数增加反而下降那说明内存通道或虚拟化环境可能存在瓶颈这是很常见的坑。另外提醒一点sysbench的内存测试走的是系统分配内存的路径受页面大小、NUMA等因素影响。在NUMA架构的多路服务器上跨NUMA节点访问内存会导致成绩明显变差。如果条件允许可以用numactl把测试进程绑定到指定节点再分别对比这样能更准确判断内存访问模式。这个细节在排查生产环境性能问题时很有价值因为数据库、缓存类应用对内存访问局部性非常敏感。4. 磁盘性能测试fio才是那个绕不过去的工具4.1 fio的核心概念磁盘性能测试我几乎只用fio。原因很简单它足够灵活能模拟各种真实负载结果指标也足够细。但fio的参数很多新手容易被吓跑。其实抓住几个核心概念就够了。第一个是ioengineI/O引擎决定用什么样的方式去执行I/O。最常用的是libaioLinux原生异步I/O和sync同步I/O。测云硬盘或SSD时我一般用libaio这样才能发挥硬件的高并发能力测普通机械硬盘或想模拟最简单场景时用sync更直白因为机械盘本身队列深度就不高。第二个是iodepth队列深度表示同一时刻有多少I/O请求在排队。这个参数非常关键现代SSD依靠大量并发请求才能发挥出性能队列深度太低带宽和IOPS都上不去。刚开始测存储时我用iodepth1结果一块标称500MB/s的SSD只测出100多MB/s还以为是盘坏了后来把深度调大才正常。你可以这么理解队列深度就是餐厅里同时排队的顾客数量机械硬盘这个服务员一次只能服务一个但现代SSD是个快手排队的人越多反而越能体现它的翻台能力。第三个是rw读写模式。read、write是纯读纯写randread、randwrite是随机读随机写rwmixread、rwmixwrite是混合读写。实际使用中随机读写更接近数据库、文件服务器等真实业务顺序读写更接近视频存储、日志归档。第四个是bs块大小。顺序读写用较大块比如1M随机读写用较小块比如4K。这也跟真实业务吻合数据库随机读通常是4K到16K的页视频存储顺序写通常是1M以上。如果你用4K的块测顺序写数字一定会偏低因为机械硬盘和SSD对大块顺序写的优化机制完全发挥不出来。4.2 用fio模拟顺序读写、随机读写先看一个经典的顺序读测试fio --nameseqread --filename/tmp/testfile --size2G --rwread --bs1M --ioenginelibaio --iodepth32 --direct1 --numjobs1 --time_based --runtime60这个命令有几个细节要说明。--direct1表示绕过操作系统页面缓存直接读写设备这是让测出的数字更接近硬件真实能力而不是内存缓存的速度。--time_based配合--runtime60表示不管数据是否写完跑满60秒避免因为大文件导致测试时间不可控。随机读测试经典的4K随机读fio --namerandread --filename/tmp/testfile --size2G --rwrandread --bs4K --ioenginelibaio --iodepth32 --direct1 --numjobs4 --time_based --runtime60我习惯把numjobs设到4或8并行跑多个进程模拟高并发业务。注意numjobs和iodepth的关系如果numjobs4、iodepth32那么实际队列深度就是128。别把这两个参数弄混否则你看到的IOPS会比你预期的高很多因为并发进程多了I/O请求自然堆起来。顺序写的测试类似把rwwrite、bs1M即可。随机写测试用rwrandwrite、bs4K。对于数据库这类重写环境我还会加一个混合读写场景fio --namemixrw --filename/tmp/testfile --size2G --rwrwmixread70 --bs16K --ioenginelibaio --iodepth32 --direct1 --numjobs4 --time_based --runtime60rwmixread70表示读占70%、写占30%很接近OLTP业务的I/O特征。如果你测的是一个以写为主的服务就把比例反过来。4.3 结果指标怎么读IOPS、带宽、延迟fio跑完会输出一大段报告真正需要重点看的指标是IOPS每秒I/O次数随机读写的核心指标。BW带宽单位MB/s顺序读写的核心指标。latavg、p99、p99.99平均延迟和高百分位延迟判断存储稳定性的关键。clat和slat完成延迟和提交延迟clat更接近用户感知的响应时间。我最看重的其实是高百分位延迟。有些硬盘平均延迟好看但p99.99惨不忍睹这种盘跑数据库时就会出现偶发慢查询。你想想数据库一条慢查询哪怕只占1%对用户体验的伤害可能比平均慢20%还大因为它的表现是“偶尔卡一下”极难排查。所以在验收存储设备时我会把p99和p99.99单独记下来和厂商给的宣传数值做对比通常会发现差距。另外提一个常被忽略的点测试文件本身会影响结果。同一个盘如果测试文件创建在文件系统上会受到文件系统开销影响如果你想知道裸设备性能可以指定--filename/dev/sdb这类设备名。但生产环境大多跑在文件系统之上所以用普通文件测试也足够关键是要保证每次测试用的文件大小、位置一致否则跨次数值对比没有意义。我一般固定用/tmp/testfile这个名字每次测试前先删除旧文件避免上一次测试的数据残留在页面缓存里。5. 网络基准测试从iperf3到延迟的完整链路5.1 iperf3测带宽带宽测试我用iperf3两端都装上一台做服务端一台做客户端。服务端iperf3 -s客户端iperf3 -c 192.168.1.10 -t 30 -P 4-i可以设置结果打印间隔比如-i 1表示每秒打印一条结果-P 4表示用4个并发流同时测。并发流数很重要单流测出来的带宽往往不是网卡的真实上限尤其是现在很多千兆万兆网卡单流时协议栈处理能力跑不满必须用多流才能压到线速。测完看结果里的SUM行单位是Gbits/sec或Mbits/sec。如果服务端和客户端之间的交换机是千兆口最后数字大概率在940Mbps左右达不到1000是因为以太网帧本身有开销这属于正常现象。如果有人跟你说他在千兆网络下测到999Mbps多半是测试方式有问题或者用了什么特殊网卡。5.2 延迟测试与进阶带宽之外延迟同样重要特别是对实时性要求高的服务。最基础的延迟测试工具是ping和traceroute。ping看的是往返时延traceroute看的是路径上的每一跳能帮你定位延迟是出在本机局域网还是跨广域网的链路上。进一步测试可以用mtr它能结合ping和traceroute持续探测路径每个节点的丢包率。排查“用户说网络卡但ping服务器又不丢包”这类问题时mtr特别有用因为它能做到长时间看趋势而不是只看一两秒的瞬时状态。如果你要测的是TCP或UDP这种传输层性能可以用iperf3配合反向测试或双向测试。双向测试命令是iperf3 -c 192.168.1.10 -t 30 --bidir双向测试能考察网卡和协议栈在上下行同时打满时的表现这个场景在真实业务里很常见比如文件存储服务同时有大量上传和下载。很多服务器的瓶颈恰恰出在双向流量上单测一条方向看不出来。5.3 网络测试注意事项网络测试最大的坑是测出来的结果“很好”但真实业务依然慢。原因多半是测试流量模型和业务差异太大。比如业务是大量小包的多次请求而iperf3默认会尽量把带宽打满所以测小包性能时应该减小块大小或改测UDP包iperf3 -c 192.168.1.10 -u -b 100M -l 64这里-l 64指定UDP包大小为64字节模拟小包场景。小包性能才是网络转发设备的真正考验因为包速率PPS上去了CPU中断处理压力才是瓶颈。另一个坑是测试机本身性能。如果你用一台CPU很弱的机器跑iperf3单流就能把CPU占满测出的带宽上限其实是CPU上限不是网络上限。这种情况建议用-P 4把负载分散到多核或者换更强的机器做测试端。跨公网的网络测试还要注意中间链路可能被运营商限速或丢包。结果如果和预期差异大多跑几遍配合mtr看路径别急着下结论说某一段网络有问题。有时候是你自己机房的交换机端口协商出了问题有时候是对端机房的防火墙策略在捣乱没有抓包确认之前别轻易下判断。6. 综合测试与自动化Phoronix Test Suite串起全流程6.1 安装与初始化如果不想一个个工具测过去而是希望对一台Linux机器做一个全面、可复现、可对比的评估Phoronix Test SuitePTS是目前最省心的选择。它本质上是一个测试框架内置几十种真实应用基准测试从编译性能、图像处理到数据库压力还能自动生成对比报告。在Debian/Ubuntu上用一行命令安装apt-get install -y phoronix-test-suite也可以从官网下载tar包直接运行。装完先做一次非交互式初始化phoronix-test-suite batch-setup这个命令会写入默认配置包括是否自动上传结果、是否交互式提问等。我建议在跑正式测试前先执行phoronix-test-suite list-available-tests看看当前环境能跑哪些测试项。很多测试项依赖编译工具链如果没装gcc、make部分项目会失败。这一步能提前发现环境依赖问题避免测试跑到一半才报错浪费时间。6.2 跑一次完整测试并生成报告PTS的测试项非常多以常见的compress-7zip为例跑一次phoronix-test-suite benchmark compress-7zipPTS会自动下载测试包、编译、运行然后生成结果文件。如果同时跑多个测试项phoronix-test-suite benchmark compress-7zip build-linux-kernel这样会把两个测试串起来结束后统一输出报告。报告默认是HTML格式包含测试环境信息CPU型号、内存大小、内核版本、每一项的分数以及同型号处理器在其他用户那边的历史平均分。这个历史对比功能是PTS最有价值的地方之一。你测一台机器它能告诉你这台机器在同类硬件中处于什么水平省得自己满世界找参考数据。对于有两台机器要做采购决策的场景PTS的横向对比报告比任何参数表都有说服力。6.3 怎么和其他机器对比跨机器对比是PTS最擅长的事。先把每台机器上的测试结果上传到OpenBenchmarking数据库phoronix-test-suite upload-result然后可以用--compare参数做对比测试或者直接在网页端查看多台机器的成绩。团队里如果统一用PTS做性能验收这些历史数据沉淀下来以后排查“是不是某台机器硬件退化”就有据可查。但注意PTS跑完整套测试时间很长动辄一两个小时。如果只是为了快速验证某个配置优化用sysbench和fio更合适。PTS更适合周期性执行比如每次新版本发布、每季度硬件巡检或者在多台候选服务器之间做横向对比。什么叫“合适”就是你现在跑一次要一两个小时那这个频率就别设太高免得坚持不下来。7. 避坑经验测试结果为什么不可信说到这儿我必须单独开一章聊聊坑。跑benchmark最危险的事不是分数低而是分数看起来挺好实际上条件没控制好数据完全失真。我踩过不少这类坑列几个最典型的。7.1 硬件状态的干扰现代CPU频率是动态的空闲时降到1GHz负载上来后升到最高温度一高还会降频。如果你跑测试的机器旁边有别的任务抢资源或者机箱散热差前后两次测出的分数可能相差20%以上。所以在正式跑benchmark之前尽量做到三点关闭不必要的后台服务、确认CPU温度正常、把性能模式固定下来。在Intel和AMD的Linux环境下可以通过cpupower工具把CPU调到performance模式cpupower frequency-set -g performance这个操作一般需要root权限。对于服务器来说默认的powersave模式在跑benchmark时经常会导致成绩偏低尤其是短时间的测试CPU可能还没把频率抬上去测试已经结束了分数自然不好看。超线程也是个影响因素。有些测试在超线程开启时分数反而下降因为逻辑线程之间会争抢同一条物理核心的执行资源。做CPU密集型性能决策时有条件的话可以分别测一下开/关超线程的成绩再结合真实业务的并发模型做选择。像我遇到过的一个数据库实例关闭超线程之后单核性能提升明显但总吞吐下降最后根据线上并发数据权衡还是选择关掉。7.2 缓存与页面缓存干扰磁盘测试是最容易受缓存干扰的。fio里我特意加了--direct1就是为了绕过页面缓存。如果你忘了加这个参数第一次读文件时数字是磁盘真实速度第二次再读同一个文件数字直接翻几倍因为数据已经在内存里了。这种情况测出的“磁盘性能”实际是内存性能报告写出去会非常误导人。内存测试也有类似问题。如果内存总量很大而测试数据量很小操作可能一直命中某些常驻内存区域跑不出真实带宽。所以sysbench memory测试里我会把--memory-total-size设成至少物理内存的一半甚至更大让测试真正触达整个内存空间否则你测的只是某段缓存的带宽而不是内存子系统的真实能力。还有一个和文件系统相关的隐形坑如果你在btrfs或ZFS这类写时复制文件系统上跑fio得到的结果和ext4、xfs会有明显差异。这不是谁对谁错而是文件系统本身的特性。所以跨机器对比时一定要确认两边的文件系统一致否则你比较的其实有两个变量结果没法归因。7.3 如何设计可复现的测试方法最后给一个非常实际的建议把测试步骤固化成脚本。不要每次靠记忆敲命令否则今天用threads4明天用threads8数据完全没法对比。我自己的习惯是在每个项目目录里放一个bench目录里面写几个shell脚本固定参数、固定输出文件。比如cpu.sh内容大概这样#!/bin/bash sysbench cpu --threads$(nproc) --time60 --cpu-max-prime20000 run sysbench cpu --threads1 --time60 --cpu-max-prime20000 run每次跑完把结果重定向成带日期的文件./cpu.sh result-cpu-$(date %Y%m%d).log这样积累下来的数据比任何一次性的“跑分”都有用。性能是慢慢变化的有了历史基线才有条件谈退化监控。再往后你可以把这些命令接进CI/CD流水线每次重要变更后自动跑一遍把分数变化作为发布的参考门禁。这是我觉得benchmark最有价值的进阶用法——它不再只是“装机后跑一次就完事”的工具而是变成持续保障性能的手段。实测下来benchmark不是什么高深技术但它的价值被很多人低估了。它最大的意义不是让你能背出几个分数而是在性能问题面前给你一个快速缩小范围的手电筒。CPU不对就查计算磁盘不对就查存储网络不对就查链路——数据不会说谎会说谎的往往是测试方法。把我上面这些参数和坑都注意到再测出来的数字基本就能挺起腰杆拿去和别人讨论了。