十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

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

国产C86服务器云测试实战:从基准测试到性能调优全记录

国产C86服务器云测试实战:从基准测试到性能调优全记录 最近这半年我大部分时间都泡在机房里反复折腾一台搭载国产C86处理器的服务器。起因很简单上面给了个任务要把这个平台送进国际云测试的第一梯队。说白了就是不能光在PPT上讲性能得用公开、通用的基准测试方法跑出成绩让做云基础设施的同行认可。整个过程中踩坑不少也把很多“我以为没问题”的细节重新梳理了一遍。这篇就当作项目总结把C86平台做云测试的方法论、参数选择、实测思路和排障过程完整记录下来。无论你是做服务器选型还是搞云计算基础设施甚至是刚接触基准测试的测试工程师这里面的内容应该都能直接用上。1. 一个国产C86平台的云测试到底在测什么1.1 为什么“跑分”不能直接当云测试成绩先说清楚一个概念。很多人一听到测试第一反应就是“跑个分”。跑分当然要看但云测试绝不是拿个工具跑一下就完事。云测试的重点在于这套硬件跑云操作系统、虚拟化、数据库、容器等真实负载时性能能不能打稳定性行不行有没有明显的瓶颈。C86这个词圈内人应该不陌生指的是采用x86指令集架构的国产处理器。因为指令集兼容性好主流的Linux发行版、Windows Server、数据库软件、虚拟化平台都能直接跑生态优势明显。但“能用”不等于“好用”性能是否达到一线水准尤其是和海外主流x86服务器放在同一张基准表里对比时到底处于什么位置就需要用一整套标准的云测试方法来回答。我这次定的测试目标很明确分四层第一层是基础性能CPU、内存、存储、网络这四项是云主机的“地基”第二层是虚拟化能力跑KVM虚机、容器看资源隔离和调度带来的损耗第三层是典型应用负载数据库、Web服务、消息队列这类云上最常见的应用第四层是稳定性长时间高负载跑看有没有降频、死机、内存泄漏、软锁等问题。只有这四层全部合格才有资格谈“国际第一梯队”。1.2 选定测试项的取舍逻辑测试项不是拍脑袋选的。国际云厂商和硬件厂商做性能验证时通常会参考几个比较通用的行业基准所以我这次也尽量向这些标准靠拢避免自说自话。基础性能这一块我选了SPEC CPU 2017测CPU整数和浮点能力Stream测内存带宽fio测存储IOPS和延迟iperf3测网络吞吐。为什么选这几个因为它们在云计算行业里属于“通用语言”你跑出来的分数别人可以复现也可以横向比较。如果只用自己写的脚本跑一遍哪怕结果好看国际同行也不认。虚拟化方面我用的是KVM自带的kvm_unit_tests加自研的压力脚本同时用UnixBench跑了一遍虚机和物理机的性能差值。很多人喜欢只看物理机分数但云测试的真正价值在虚拟化后的损耗。损耗越低说明这个平台做云主机时能给用户更多真实算力。应用层我选了MySQL和Redis分别代表关系型数据库和缓存类场景。测试方法用的是sysbench和memtier_benchmark选择它们是因为负载模型清晰能直接对比不同CPU平台在相同数据库压力下的表现。稳定性测试则放到最后用stress-ng把CPU、内存、磁盘全部压满连续跑72小时期间每分钟记录一次温度、频率、功耗和错误日志。这一步最枯燥但往往最能暴露问题。2. 测试环境搭建配置、参数和每一步背后的为什么2.1 硬件与软件基础配置测试环境尽量贴近真实云主机部署场景我没有用开发板或者特殊定制的工程样品直接用的量产服务器整机。硬件配置大致是这样双路C86处理器具体型号这里就不细说了单颗核心数在64核心左右支持超线程内存配了16条32GB DDR5总共512GB跑满所有内存通道存储是三块企业级NVMe SSD组RAID外加两块SATA SSD做系统盘网络是双口万兆直接连测试交换机。软件环境上操作系统用的是Rocky Linux 8.8内核版本5.14。这版系统我在其他x86服务器上也验证过虚拟化支持和性能稳定性都不错方便后续对比。测试工具全部用源码编译不开系统自带的版本原因后面会讲。这里有一个非常重要的操作刷固件。拿到服务器第一件事我不是装系统而是先到厂商官网把所有固件BIOS、BMC、磁盘控制器固件更新到最新版本。很多性能问题其实不是CPU不行而是出厂固件里的微码或电源管理策略太保守。刷完固件后重启进入BIOS再把电源模式设为Performance关闭所有节能相关的C-states选项。这一步不做后面的测试成绩可能直接差10%以上。2.2 这几个系统参数直接影响最终成绩系统层面有几个参数是我在多次测试后确认必须调整的不走这些配置会严重影响最终结果。第一个是NUMA。C86平台是典型的NUMA架构两颗CPU各连着一部分内存CPU访问本地内存和远端内存的时延差很多。Linux默认的NUMA策略是“先本地后远端”这本身没问题但如果测试工具没有做CPU绑定线程会在两颗CPU之间来回切换内存访问就会频繁落到远端性能直接打折扣。所以每次跑性能测试前我都会用numactl工具把进程绑定到固定的CPU核心和对应的NUMA节点上。比如测试单路性能时进程就绑在node0的CPU核心里内存也强制从node0分配。用一行命令示例numactl --cpunodebind0 --membind0 ./your_benchmark第二个是超线程。C86处理器的超线程开启后在多线程负载下通常能提升20%左右的多核分数但对单线程延迟和某些虚拟化场景反而有负面影响。我做了两组对比发现数据库这类延迟敏感型负载关闭超线程更稳而SPEC CPU这种高并行的计算负载开超线程更好。所以不要迷信“更多线程更好”具体负载要具体测。第三个是内核的透明大页和NUMA平衡。默认开启的透明大页THP在数据库场景下容易造成内存分配延迟抖动我一般在跑数据库负载时用hugepages手动分配并关闭THP跑CPU基准时则保留默认。内核的NUMA自动平衡numa_balancing也建议在基准测试时关闭避免线程迁移干扰结果。具体操作是将以下参数写入/etc/sysctl.confkernel.numa_balancing0 vm.swappiness10 vm.dirty_ratio30 vm.dirty_background_ratio52.3 用“理论带宽”反推硬件是否满血一个我经常用的检查手段先算理论性能再和实测数据对照判断硬件有没有满血运行。这个方法特别适合新平台的首轮测试能快速定位是硬件问题还是软件问题。以内存带宽为例。DDR5内存的单根带宽计算公式是频率乘以8字节再乘以通道数。我这台服务器是16条DDR5-4800内存每条CPU有8个内存通道理论峰值带宽就是4800MT/s × 8字节 × 8通道 ≈ 307.2 GB/s单颗CPU。用Stream测试时如果实测带宽低于理论值的70%基本可以断定内存频率没跑满或者BIOS里没开启对应配置。后来我发现这台服务器默认BIOS下内存跑在4000MT/s而不是4800手动开启XMP配置后带宽立刻提了接近15%。这个方法也适用于CPUSPEC CPU的速率分数可以换算成每秒操作数再和主频乘核心数算出的理论吞吐量对比。如果单核效率明显偏低可能是在编译测试程序时用的编译器优化级别不对。后面会展开讲编译器的问题。3. 基准测试实操从安装到出数的完整过程3.1 SPEC CPU 2017跑起来前的准备工作SPEC CPU 2017是当前国际上最权威的CPU计算性能基准云测试里衡量CPU算力基本绕不开它。很多人拿到工具包就直接开跑但这样跑出来的成绩只能说明“你跑了个SPEC”不能说明“你跑好了SPEC”。准备工作分三块编译器、工具链、运行控制。首先是编译器。SPEC允许使用不同的编译器官方推荐GCC和Intel编译器。在不同平台上编译器对代码的优化效果差异很大。C86平台完全兼容x86指令集所以GCC和Intel编译器都能用但建议用GCC 12以上版本并对-march参数做优化。我这次用的是GCC 12.3编译参数里加了-marchx86-64-v3因为这套指令集已经覆盖了主流服务器CPU的特性能更好地发挥C86的性能。其次是工具链。SPEC依赖一些基础库比如libgomp、OpenMP运行时安装时要用源码编译不要用系统自带的老版本。系统自带的库可能性能不足甚至导致某些测试项无法运行。安装SPEC时我建议自定义安装目录不要放在默认的/usr/local下避免后续权限和路径问题。最后是运行控制。SPEC CPU 2017分成speed速度看重单任务延迟和rate速率看重吞吐量两种模式云测试两者都要跑。跑rate模式时要特别注意并发数不是直接把核心数拉满就好。C86支持超线程32核开超线程变成64线程但rate模式跑64个副本时L3缓存和内存带宽会成为瓶颈分数反而会低于32副本。我用32副本和64副本各跑了一遍发现整数测试用32副本成绩好浮点测试在64副本下也没超过32副本太多所以最终采用物理核心数作为rate副本数。跑一次完整的SPEC CPU 2017需要很长时间speed模式大概4到6小时rate模式更久要8到10个小时。期间机器负载是满的不能再跑其他任务。# 进入SPEC目录后先配置环境 source shrc # 编译所有测试项 runcpu --actionbuild --tunebase all # 跑speed模式 runcpu --tunebase --sizeref --noreportable speed # 跑rate模式使用物理核心数作为副本数 runcpu --tunebase --sizeref --rate32 --noreportable rate3.2 执行测试和监控要点测试开始之后很多人以为就等着数就行了其实监控才是关键。为什么同一台机器昨天跑出来的成绩比今天高5%十有八九是散热或者频率策略在作祟。我用turbostat实时记录CPU频率、温度和功耗开跑后第一件事就是确认所有核心的频率是否达到标称的满载频率。C86处理器在满载时如果散热不到位或者BIOS功耗墙设得太保守就很容易降频频率一旦从标称值降下来SPEC分数必然难看。另一个监控重点是内存带宽。跑Stream的时候用perf工具看内存控制器的带宽利用率如果测试中带宽长期高于90%说明内存已成为瓶颈此时加CPU频率对成绩没有帮助反而要考虑内存配置优化。我整理了一套自己常用的监控命令组合一条命令就能把所有关键信息打出来while true; do date turbostat --num_iterations 1 --quiet sleep 5 mpstat -P ALL 1 1 | grep -E 平均|Average done日志输出到文件跑完测试后回头分析能精确定位是哪个时间点出现了性能回落。3.3 虚拟化场景下的云测试差异物理机的基准测试跑完才开始真正意义上的“云测试”。云测试里虚拟化是绕不开的一环。C86平台支持KVM虚拟化我在宿主机上创建了一个4核8GB的云主机实例然后在虚机里再跑一遍UnixBench、MySQL和Redis测试和物理机数据做对比。这一步能看出一件很重要的事虚拟化层的开销到底有多大。实测下来C86平台的KVM虚拟化损耗大概在5%到8%之间这个数字处于国际主流水平。损耗主要来自三块中断处理、内存地址转换和CPU调度。如果你的虚机性能明显低于这个范围建议先检查宿主机CPU是否开启了VT-x再确认vCPU的绑定策略。这里分享一个虚拟化性能优化技巧把vCPU用taskset绑定到指定的物理核心上并开启CPU的pinned模式中断请求IRQ也要绑定到和vCPU不同的物理核心上避免中断和计算抢同一个核。操作方式大致如下# 查看vCPU对应的线程ID virsh vcpupin win01 0 4 virsh vcpupin win01 1 5 # 查看并设置IRQ亲和性 cat /proc/irq/128/smp_affinity_list绑定前后MySQL的TPS从大约8200提升到了10300效果非常明显。4. 排障实录成绩不好看的时候先别急着下结论4.1 性能骤降的第一嫌疑NUMA和频率整个测试中最折腾的一段是第一次跑完SPEC rate模式后成绩比预期低了接近20%。当时第一反应是CPU有问题后来查了一圈问题出在NUMA和内存频宽上。双路平台上两个NUMA节点之间需要通过互联通道通信。当rate跑满64个副本时一半线程访问本地内存一半线程访问远端内存远端内存访问的时延比本地高了接近一倍。SPEC rate模式又是典型的内存敏感型负载时延一上来整数和浮点分数都受到明显影响。解决方式不是开32副本而是把测试工具改成显式分配内存。我在跑SPEC时给runcpu加了环境变量让每个副本优先绑定到本地内存节点。具体修改方式是在SPEC的配置文件中加入numactl包装或者在启动命令前直接绑定numactl --interleaveall runcpu --tunebase --sizeref --rate64 --noreportable rate在NUMA架构下使用interleave内存交错策略可以让所有线程均匀分配在本地和远端内存上避免某些线程全部扎堆访问同一节点的内存。调整后rate分数回升了约12%。第二个嫌疑是频率。检查turbostat日志时发现满载运行20分钟后整机平均频率从3.2GHz掉到了2.8GHz。服务器在跑基准测试时是封闭在机柜里的环境温度接近30度散热风扇的转速策略跟不上。后来我把服务器从机柜里挪到开放环境并手动把风扇转速调到70%频率就稳住了。这里也要提醒大家跑基准测试前最好确认机房的散热能力否则测试结果会随着季节和空调状态漂移数据没有可复现性。4.2 问题速查表整理了这段时间最常遇到的问题做成一张速查表方便大家在实际测试时对照排查。问题现象大概率原因快速排查方式解决手段SPEC分数低于预期NUMA内存访问失衡用numastat查看内存分配比例绑定NUMA节点或用interleave策略长时间运行后性能下降CPU降频或散热不足turbostat看频率和温度调整风扇策略、增强散热内存带宽不达标内存频率未跑满或通道未全开dmidecode查看内存频率和通道数BIOS开启XMP或手动设置频率虚机性能低于物理机10%以上vCPU未绑定或IRQ抢占virt-top查看vCPU占用检查IRQ亲核性绑定vCPU到固定核心IRQ分散到其他核Redis延迟抖动大内核NUMA平衡机制干扰查看dmesg是否有迁移日志关闭kernel.numa_balancing长时间高负载后内存报错内存ECC错误或温度过高查看BMC日志和EDAC报告排查内存条或调整风道网络吞吐忽高忽低网卡队列中断未均衡查看/proc/interrupts的分布开启RPS或设置多队列这7个问题基本覆盖了我在C86平台云测试中遇到的绝大部分坑其中NUMA和频率问题出现的频率最高几乎每换一个测试场景都要重新排查一遍。4.3 一个被忽略的隐藏因素测试工具自身的编译选项还有一个容易被忽略的细节同一款测试工具编译选项不同成绩能差出好几个点。以sysbench为例它默认编译时不带特定的CPU指令集优化。我在编译sysbench时修改了CFLAGS./configure CFLAGS-O2 -marchx86-64-v3加了-march参数后CPU能用到AVX2等更宽的向量指令跑MySQL压测时的TPS提升了约6%。Redis的memtier_benchmark也是一样默认编译时没有启用Intel或AMD特定的优化路径都是用通用代码加上-march参数后时延能降低不少。这就是我之前强调用源码编译工具的原因。发行版的二进制包为了兼容性通常采用最保守的编译参数那些默认参数完全没有发挥出C86平台在较新指令集上的优势。同时还有一点调度器设置。Linux的默认调度器是CFS在云测试场景下如果同时跑多个没有亲属关系的高负载进程CFS的调度延迟会影响时延敏感的测试结果。我建议在跑Redis或MySQL时使用SCHED_FIFO实时优先级或配置cgroup的cpu共享份额。比如给Redis设置较高的cpu.weight让它在竞争时优先获得调度时间。5. “国际第一梯队”怎么理解以及测试完成后还能做什么5.1 判断“第一梯队”的客观标准聊到最后回到标题里那个“国际云测试第一梯队”的说法。这既不靠宣传也不靠自评关键是有没有可对比的客观数据。我的判断逻辑很简单在同一套测试方法、同样测试物料和相近配置下把C86平台跑出来的成绩和当前国际主流x86服务器放在一起比。具体参考维度有三个一是性能绝对值。SPEC CPU 2017的整数和浮点分数要和同核心数、同时代的海外主流服务器处于同一区间差距不能超过10%到15%。内存带宽、存储IOPS、网络PPS这些基础指标也要达到同级别。二是虚拟化损耗率。KVM虚机的性能损耗如果能控制在10%以内就能满足大多数云生产环境的SLA标准这在过往的测试中也是国际主流虚拟化平台的表现。三是稳定性。72小时满载测试无宕机、无错误、无明显性能衰减这是云厂商敢把一款硬件放进可用区的最基本要求。最终这套C86平台在我的测试里物理机性能达到了同代际主流x86平台约九成的水平虚拟化损耗保持在8%左右长稳测试未发现致命问题。作为国产x86兼容平台这个成绩确实算站稳了国际云测试第一梯队的位置。客观说单核性能和海外旗舰产品还有差距但多核扩展、内存带宽这些云上最看重的指标已经追到同一水平线。5.2 测试完成后的新想法测试做完数据交上去事情并没有结束。云测试本来就是反复迭代的过程我在这个项目里还有几个后续想继续补上。第一是高负载下的长时间内存压力测试。SPEC和Stream能说明峰值性能但内存控制器的稳定性需要更长时间的验证。我准备加跑一轮72小时的memtest86和Linux内核自带的ksmstress看ECC纠错日志有没有增长。第二是更多真实云原生负载的接入。现在测了数据库和缓存但云上还有大量Java微服务、大数据计算、AI推理任务。后续想用开源压测工具对Tomcat、Spark和TensorFlow Serving做一轮专门的测试这样能覆盖更广的云上业务。第三是国产操作系统和数据库的适配测试。云测试不只是测硬件的峰值还要跑通国产化软件栈的组合。比如在C86平台上跑OpenAnolis或openEuler系统搭配TiDB或OceanBase验证在云环境中的兼容性、稳定性和性能。这一步对最终落地很有价值。最后再分享一个小技巧。跑云测试时记得把每轮测试的固件版本、BIOS设置、内核参数、编译器版本和测试工具的commit号全部记录下来。我在项目中途就因为升级了一次固件导致前后两轮SPEC分数差异巨大如果当时没有留记录根本定位不到是BIOS微码变了。做好版本管理比优化分数更重要没有可复现性的测试数据等于没测。
返回列表