国产算力集群7×24小时稳定性压测实战:从方案设计到问题排查 📅 发布时间:2026/9/9 0:03:18 👁 浏览次数: 国产算力集群这两年越来越多人上手了但很多团队对“能跑起来”和“能稳定跑”之间的差距认识是真不够。我见过不少项目单卡推理测得好好的一上集群做7×24小时长稳压测就露馅显存泄漏、通信超时、节点掉线、性能毛刺各种问题轮流来。这篇文章就把我们团队在国产算力集群上做7×24小时稳定性压测的完整经验做个总结从方案设计、工具选型、实操流程到问题排查都捋一遍给准备做长稳测试的同学一个能直接照着走的参考。1. 压测方案设计先想清楚测什么再动手跑压力1.1 为什么非要做7×24小时长稳测试很多团队对压测的理解还停留在“把QPS打上去看服务挂不挂”跑个半小时一小时就觉得完事了。但稳定性测试和普通性能测试的核心区别就一个字长。7×24小时不是随便定出来的数字它的意义在于让时间把问题暴露出来。我自己在国产算力集群上跑长稳压测的体会是很多问题在短时间压测里根本看不见。比如显存泄漏跑一小时泄露几百MB监控曲线看上去就是一条略微上扬的线不仔细看都发现不了但跑24小时可能就是几十GB的泄漏直接把推理服务打崩溃。再看通信库的内存增长分布式训练或推理场景下集合通信的缓冲区管理如果有问题累积几十个小时后节点间通信会越来越慢最终拖垮整个集群。另外7×24小时这个时间跨度能覆盖到一些周期性因素。比如数据中心的温度昼夜变化夜间温度低服务器散热好性能表现会好一些白天温度上来散热压力增大如果散热设计有缺陷芯片可能触发降频。再比如集群中其他业务的资源争抢不同时段网络、存储的负载不一样这些都会在长时间压测中体现出来。所以长稳压测的本质不是“把机器跑累”而是“给问题足够的时间让它自己暴露”。这个理念一定要在方案设计阶段就传达给所有参与的人不然后面分析数据的时候很容易把真正的问题当成偶发现象忽略掉。1.2 稳定性测试的三个核心维度做了这么多次长稳压测我习惯把稳定性拆成三个维度来看每个维度都有明确的观测指标和判断标准。第一个维度是性能稳定性。简单说就是长时间运行过程中吞吐量、响应时间这些核心指标有没有明显的劣化趋势。判断标准不是“没有掉到0”而是“波动范围是否可控”。比如QPS基线是1000允许的浮动范围一般在±10%以内超过这个范围就要查原因。响应时间的P99尤其值得关注平均响应时间稳定不代表P99没有慢慢爬升很多隐性劣化都是先从长尾延迟表现出来的。第二个维度是资源稳定性。包括CPU使用率、内存占用、显存占用、GPU利用率、磁盘I/O、网络带宽这些。这里的关键不是看瞬时值而是看趋势。我会特别关注内存和显存这两个指标因为它们最容易暴露泄漏问题。资源稳定性的判断标准是在恒定压力下资源占用应该在合理区间内波动而不是持续单调增长。如果RSS常驻内存或者显存占用每过一小时就涨几个百分点即使幅度不大也要警惕。第三个维度是故障恢复能力。长稳压测不只是看“不出问题”还要看“出了问题能不能自动恢复”。比如单个节点宕机集群调度器能不能快速把任务迁移到其他节点推理服务能不能自动摘除异常实例并重新拉起通信库能不能在连接断开后重连。这个维度往往被忽略但恰恰是生产环境最需要的能力。我在压测方案里都会加入故障注入环节专门验证集群在各种异常下的自愈能力。1.3 压测场景设计从单链路到全链路压测场景的设计直接影响测试结论的有效性。我见过有些团队做算力集群压测就是把某个模型推理接口拿来猛打测出来的结果只能说“这个接口能扛多少并发”对判断集群整体稳定性帮助有限。我的做法是分三层来设计场景。第一层是单链路压测挑两到三个有代表性的模型推理链路比如一个文本生成模型、一个视觉模型分别做单链路压测验证单个业务链路的处理能力和资源消耗基线。第二层是混合链路压测把多个推理任务、训练任务混在一起压模拟真实生产环境的负载形态。算力集群上永远不可能只有一个任务在跑任务之间的资源争抢、调度竞争、带宽争抢这些都得压出来才算数。第三层就是全链路压测也就是热词里提到的大模型链路全量压测。这一层不只是打模型推理接口而是把完整的大模型应用链路都拉进来包括前置的文本预处理、Tokenization、检索增强、Prompt拼装、模型推理、流式返回、后处理等各个环节。全链路压测的价值在于发现端到端的瓶颈很多问题单看模型推理环节没问题但整个链路串起来就出问题比如前置预处理环节成为了瓶颈反压到上游导致整体吞吐被拖住。场景设计这块还有一个重要原则压力量级要分阶梯不要一上来就满负荷。我会按30%、50%、70%、85%、100%五档来做阶梯加压每个梯度维持30到60分钟观察指标变化趋势后再决定是否进入下一个梯度。这既是为了保护集群设备也是为了让压测数据更完整——不同负载级别下的稳定性表现对后续容量规划参考价值很大。2. 工具选型与并发模型jmeter 和 k6 到底怎么选2.1 jmeter老牌压测工具的优势和局限Jmeter在压测工具里算得上“老前辈”了很多做接口测试和性能测试的同学第一个接触的压测工具就是它。它最核心的优势是上手门槛低、图形界面友好、生态插件丰富而且不需要写代码就能配置出完整的压测场景这一点对于测试团队来说非常友好。在算力集群压测场景下jmeter比较适合做HTTP接口层的推理服务压测。比如你要压测一个基于HTTP服务的模型推理接口直接用jmeter的线程组模拟并发用户请求就可以。值得注意的是jmeter的执行模式GUI模式只适合调试脚本真正跑压测一定要用命令行模式否则GUI自身的渲染开销会严重干扰测试数据尤其是长时间压测GUI模式跑几十个小时内存占用和CPU波动都会变成数据里的噪声。实际压测命令如下jmeter -n -t testplan.jmx -l result.jtl -j test.log -e -o report/-n表示非GUI模式-t指定测试计划-l保存原始结果-e -o生成HTML报告。还有一个容易被忽略的点jmeter默认在JVM堆内存只有1GB的情况下运行长时间压测很容易GC频繁甚至OOM建议启动前显式调大堆内存JVM_ARGS-Xms4g -Xmx8g jmeter -n -t testplan.jmx -l result.jtl -j test.log -e -o report/jmeter的局限也很明显——它对分布式压测的支持比较笨重需要部署agent节点而且调度和结果汇总的体验谈不上好。如果你压测的目标是集群内部的高吞吐推理服务单台jmeter机器可能本身就成为了瓶颈发压端打不满服务端测出来的上限其实是压测机自己的上限。2.2 k6脚本化压测的现代化选择k6这两年热度上升非常快很多人第一次接触它是因为它用Go语言编写压测引擎性能好单机就能产生很高的并发压力。但我觉得k6真正比jmeter强的地方在于它把压测脚本变成了一种工程化产物可以直接纳入代码仓库做版本管理配合CI/CD做自动化压测。拿大模型推理接口的压测来说k6脚本写起来非常直观import http from k6/http; import { check, sleep } from k6; import { Rate, Trend } from k6/metrics; const errorRate new Rate(error_rate); const inferenceLatency new Trend(inference_latency, true); export const options { scenarios: { ramping_load: { executor: ramping-vus, stages: [ { duration: 30m, target: 50 }, { duration: 2h, target: 50 }, { duration: 30m, target: 100 }, { duration: 2h, target: 100 }, { duration: 30m, target: 200 }, { duration: 2h, target: 200 }, ], gracefulRampDown: 30s, }, }, thresholds: { http_req_duration: [p(99)2000], error_rate: [rate0.01], }, }; export default function () { const payload JSON.stringify({ model: llm-serving, prompt: 写一篇关于算力集群稳定性测试的文章, max_tokens: 512, temperature: 0.7, }); const params { headers: { Content-Type: application/json, }, timeout: 120s, }; const res http.post(http://cluster-endpoint/v1/completions, payload, params); inferenceLatency.add(res.timings.duration); errorRate.add(res.status ! 200); check(res, { response status is 200: (r) r.status 200, response time 30s: (r) r.timings.duration 30000, }); sleep(1); }这个脚本里我用了ramping-vus执行器它会按照 stages 数组里定义的阶梯自动调整并发数。这样做的好处是整个压测过程不需要人工干预脚本自己会跑完从50并发到200并发的完整阶梯过程特别适合7×24小时这种长时间无人值守的压测场景。thresholds 是k6里非常有用的功能。它可以在压测过程中实时判断指标是否超标——比如P99延迟超过2秒就标记为失败错误率超过1%就标记为失败。长稳压测跑几十个小时不可能一直盯着面板有了thresholds跑完直接看结果就知道这次压测有没有达标。这个能力是jmeter原生不具备的要么靠外部脚本分析结果要么就要用监听器人工观察。2.3 并发数怎么确认不是拍脑袋是算出来的“jmeter压测怎么确认系统的并发数”是搜索热词也是很多新手最容易出错的地方。先说结论没有任何一个公式能直接算出“系统最大并发数”并发数只能通过逐步加压探出来的。但作为压测的起点我们可以用一些方法估算初始并发。最朴素的方式是直接用“并发数 QPS × 平均响应时间”这个公式做估算。举个例子假设单实例推理接口的QPS基线是20平均响应时间是1.5秒那么维持QPS 20所需的并发数就是 20 × 1.5 30。这是一个线性近似估算它能帮你判断压测机的并发配置是否和目标吞吐匹配但它不能告诉你系统能扛多大并发。真正的并发数探测要用梯度加压法。还是用k6举例我会设置一段阶梯加压的stages从小并发开始逐步提升export const options { scenarios: { find_max_concurrency: { executor: ramping-vus, stages: [ { duration: 10m, target: 10 }, { duration: 10m, target: 20 }, { duration: 10m, target: 40 }, { duration: 10m, target: 80 }, { duration: 10m, target: 120 }, { duration: 10m, target: 160 }, { duration: 10m, target: 200 }, ], }, }, };每个压力级别维持10分钟同时监控响应时间、错误率、GPU利用率和显存占用。当发现错误率开始上升、P99延迟明显变高、或者GPU利用率不再随并发数提升而增加时就说明已经接近系统的饱和点。这个饱和点之前的并发数才是系统能够稳定支撑的最大并发。这里有个很重要的原则最大并发数本身不是目标系统能稳定服务的并发数才是目标。我跑过很多次压测发现有些系统在某个并发下能扛住几分钟但扛不住半小时——典型的资源泄漏类问题。所以真正有效的并发数确认一定要配合“持续观察”才能下结论短时间探到所谓最大并发后续长稳压测大概率会翻车。3. 7×24小时压测实操过程从环境准备到报告产出3.1 环境摸底与基线测试不考虑清楚就直接跑是在浪费时间很多人在长稳压测开始前容易忽略环境摸底直接上来就跑24小时。我理解大家的时间压力但环境摸底这步省不得省了后面排查问题的时候要多花好几倍的时间。环境摸底要做的事情包括确认集群节点的硬件规格和固件版本、操作系统版本、内核参数配置、GPU驱动版本和CUDA版本以及各节点上的软件栈版本尤其是通信库和推理框架的版本必须完全一致。不同节点驱动版本不一致长时间运行后表现差异会很明显一旦出问题根本分辨不清是代码问题还是环境差异导致的问题。基线测试也是必做项。在正式压测之前我会先跑一组短时间的单链路压测记录每个节点在固定压力下的性能基线数据GPU算力利用率、显存占用、A2A通信带宽、PCIe带宽、内存带宽等。这些基线数据有两大用途一是在长稳压测期间做对比判断性能有没有劣化二是在出现节点级故障时用基线数据快速定位是哪个节点偏离了常规表现。另外第一轮摸底就要把监控一次性配好。我们用的是Prometheus加Grafana那套组合GPU硬件指标用DCGM exporter采集节点级指标用node_exporter采集业务指标通过推理服务自身暴露的/metrics接口采集。三个数据源汇总到PrometheusGrafana上做Dashboard。这是压测的基础能力建设前期投入一两天后面7×24小时压测中会省掉大量人工盯守的时间。3.2 阶梯加压与长稳阶段压测节奏怎么控制正式压测阶段我习惯把7×24小时分成三段来安排加压段、峰值维持段、观测恢复段每段都有不同的目标。加压段一般占4到6个小时。从30%压力开始逐步抬升到100%压力每一步都观察15到30分钟确认各项指标平稳后再继续加压。这里有个经验值如果某一级压力下P99延迟比上一级压力跳升超过50%或者错误率超过0.1%就先停止加压排查清楚原因再继续。很多问题在加压阶段就暴露了这时候发现是运气好因为修复成本最低。峰值维持段是整个压测的主体一般维持16到18个小时用100%的设计压力持续跑。这个阶段重点关注的是趋势变化我在Grafana上会特别关注两条曲线内存占用趋势和显存占用趋势。如果这两条曲线在峰值维持段出现持续单调上升基本可以判定存在内存泄漏或显存泄漏不需要等跑完就可以提前定位了。观测恢复段放在最后两三个小时。把压测压力逐步降下来观察系统在低负载和卸载负载之后的恢复情况。这个阶段往往被忽略但它能看出系统是否存在资源释放不干净的问题——比如高负载下分配的内存在压力降下来之后有没有正常回收连接池里的连接在低负载后有没有及时释放缓存在负载下降后有没有慢慢清掉。资源池这玩意儿回不到原位就说明有问题。还要特别提醒一点7×24小时压测期间日志管理一定要提前做好。不同模块的日志要分开目录存放按照大小和时间做滚动切割避免单个日志文件膨胀到几个GB导致磁盘写满。推理服务的访问日志尤其要控制粒度全量打印HTTP请求体和响应体在长稳压测中是灾难生产上通常只记录关键字段摘要。3.3 监控指标体系别只看QPS和错误率长稳压测的监控指标要比普通压测丰富得多。我习惯把监控指标分成四大类每类下再细化具体指标项。业务类指标是最直观的QPS、平均响应时间、P99/P95延迟、错误率、超时率。这些指标衡量的是用户视角的服务质量是压测是否达标的核心依据。资源类指标包括CPU利用率、内存使用量、磁盘I/O、网络收发带宽、GPU利用率、GPU显存占用、GPU温度、NVLink带宽等。这些指标衡量的是集群设备的健康状态和利用效率。GPU温度这个指标很容易被遗漏但对长稳压测很有参考价值——温度缓慢爬升通常意味着散热系统处理不了持续高负载温度过高会触发芯片降频保护表现出来的就是性能缓慢下降。系统类指标包括文件句柄数、线程数、TCP连接数、内存页交换、上下文切换等。这些指标的作用是辅助定位尤其是当业务指标出现毛刺时先看系统类指标有没有异常波动能快速缩小排查范围——是业务代码的问题还是操作系统层面的资源争抢问题。调度类指标主要适用于集群场景任务排队时长、GPU分配成功率、节点间通信延迟、集合通信带宽利用率等。算力集群压测时调度器的表现直接影响整体稳定性如果某个节点的GPU分配总是超时或者集合通信的延迟在压测后期明显恶化就要重点检查通信库、交换机和网卡的健康状态。3.4 故障注入与异常恢复演练稳定性是衡量“恢复能力”的前面说过稳定性测试的第三个维度是故障恢复能力。这块不主动注入故障就永远验证不了。7×24小时压测期间我通常会在峰值维持段插入两到三次故障注入演练选择在系统完全稳定的状态下进行掐表记录恢复时间。最常见的故障注入方式之一是杀掉推理服务的一个实例进程模拟进程崩溃。重启后观察服务发现实例异常、摘除流量、重新拉起新实例、恢复服务的过程整个自动恢复时间我一般要求控制在5分钟以内。如果超过这个时间说明监控告警、健康检查或者自愈策略存在短板。另一个常用方式是模拟单节点网络抖动。用tc命令给某个节点添加人为的网络延迟和丢包tc qdisc add dev eth0 root netem delay 100ms loss 5%保持十分钟后移除。这个操作模拟了真实网络中很常见的链路不稳定问题可以非常有效地验证通信库的重传机制、超时重试逻辑和集群对链路劣化的容忍度。注意演练完及时移除规则避免影响后续数据。异常恢复演练的结果一定要记录在压测报告里故障注入时间、故障持续时间、受影响范围、自动恢复时长、恢复后指标是否回归基线。这些数据对于评估集群的工程化水平非常有说服力比单纯的“跑了7天没出事”有价值得多。4. 常见问题与排查实录那些压测中踩过的坑4.1 性能毛刺到底是谁的问题长稳压测里最让人头疼的就是性能毛刺——大部分时间指标都正常但每隔一段时间就出现一次响应时间飙高或者吞吐掉坑。这种问题短时间压测几乎看不到7×24小时压测里却几乎是必现场景。排查毛刺问题我的经验是先看时间点。把毛刺出现的时间点和集群日志、系统日志对齐看有没有定时任务在整点触发比如日志切割、指标采集、模型中台的定期权重加载等。这些定时操作如果实现得不优雅很容易造成资源争抢表现为周期性毛刺。我踩过的坑是某版本的日志模块每6小时做一次日志压缩压缩期间CPU冲高直接导致该时段推理P99延迟翻了几倍。排除定时任务后再看是否有GC问题。JVM类服务的长稳压测必查GC日志尤其是CMS和G1的Full GC发生一次就是秒级停顿。如果是Go服务则优先关注GC和协程调度。国产算力集群上有时候毛刺是通信库引起的比如集合通信的周期性拓扑探测、健康检查都会在大规模集群上产生周期性的控制面流量影响数据面性能。4.2 显存泄漏和内存泄漏曲线斜率就是证据显存泄漏是GPU推理集群长稳压测里最常见的坑没有之一。它的特征非常典型显存占用曲线在恒定压力下持续上升从不回落或者在某个水位下会持续累计最终在OOM边缘徘徊。显存泄漏的排查思路是从业务代码入手重点检查推理框架的缓存管理、动态shape场景下的显存分配、流式生成场景下的临时张量释放逻辑。pytorch里尤其要留意torch.cuda.empty_cache()的调用时机有些实现只在显存不足时才释放缓存在高并发长稳压测中会表现出显存占用持续爬升。内存泄漏的排查逻辑类似先区分是堆内泄漏还是堆外泄漏。堆内泄漏用JVM监控和heap dump分析堆外泄漏排查成本高得多涉及DirectByteBuffer、JNI代码、底层通信库的缓冲区管理。国产算力集群的通信库大多基于RDMA如果在消息发送接收过程中缓冲区释放有遗漏长时间运行后内存占用就会持续上涨。RSS趋势是最直接的证据Grafana里把RSS曲线拉出来看如果斜率稳定为正基本可以断定有泄漏只需要顺着分配链路一步步查。4.3 7×24小时压测中的脏数据与测试干扰长时间压测中有一个很容易被忽视的问题脏数据。推理服务通常会有日志记录请求日志和响应日志长时间累积会占用大量磁盘空间。7×24小时全量请求日志的量非常可观如果不做采样或关键信息摘要几亿条日志会把磁盘打爆测试在半夜失败的概率极高。另外压测目标集群可能同时被其他研发团队的调试任务占用这种干扰很难控制。我的经验是把压测的目标节点标注清楚和运维约定压测期间的资源隔离策略压测期间不接受其他作业调度到这个节点组。同时监控系统中要做资源隔离告警——一旦检测到非压测任务占用了压测节点的资源立刻告警避免数据被污染还不知道。4.4 问题速查表现象优先级排查路径显存占用持续上涨P0检查推理框架缓存管理重点看动态shape、临时张量释放和空缓存调用时机RSS持续上涨P0区分堆内/堆外泄漏检查JNI、通信库缓冲区管理重点看RDMA收发路径周期性性能毛刺P1对齐定时任务检查日志切割、指标采集、热加载配置再看GC停顿P99持续走高P1检查连接池、线程池、缓存命中率优先看长尾延迟分布变化GPU温度缓慢爬升P1检查散热策略、风扇转速、环境温度评估是否触发降频保护节点间通信延迟增大P2检查网卡丢包、交换机端口错误、通信库超时重传参数、链路质量恢复后指标不回归基线P0检查连接池泄漏、线程泄漏、缓存未释放确认资源回收逻辑压测机本身成为瓶颈P2检查压测机CPU、内存、带宽必要时改用分布式压测或k6集群模式结语跑完这轮7×24小时压测我对国产算力集群的稳定性有了更真实的判断芯片算力是一回事集群工程化是另一回事。让人欣慰的是经过这轮长稳压测我们挖出了好几个单靠短时测试发现不了的问题——一个显存泄漏和两个通信链路劣化场景——修复之后集群的稳定性有了肉眼可见的提升。这里也分享两个压测实操中的小技巧都是踩过坑才换来的一是压测脚本里务必加入响应断言和状态码检查别只记录耗时否则错误请求也会被算进平均响应时间里数据偏差大得离谱二是长稳压测期间压测机和被压集群的时间同步一定要检查NTP偏差过大会导致日志时间线错乱故障复盘的时候时间对不上非常痛苦。希望这些经验对准备做国产算力集群稳定性测试的团队有帮助少踩几个坑多省几天时间。