2、性能基准测试:如何设计合理的性能基准测试
性能基准测试,说白了就是给你的搜索引擎“体检”。
我见过太多团队,一上来就堆机器、调参数,结果连自己系统的瓶颈在哪都不知道。你想想看,没有基准测试,你拿什么衡量优化效果?靠感觉吗?
这一章,我就带你把这个基础打牢。
2.1 核心指标的定义
先搞清楚我们要测什么。搜索引擎的性能,主要看三个维度:QPS、延迟、召回率。这三个指标,缺一不可。
2.1.1 QPS(每秒查询数)
QPS 就是系统每秒能处理多少个查询请求。说白了,就是“吞吐量”。
我习惯这么算:QPS = 总查询数 / 测试时长(秒)。但要注意,这个值不是越高越好。你得看它是在什么延迟下达到的。
关键点:QPS 必须和延迟一起看。单独看 QPS 没有意义。
2.1.2 延迟(Latency)
延迟就是用户发出查询到收到结果的时间。通常用毫秒(ms)表示。
这里有个坑——平均延迟很容易骗人。我遇到过几次,平均延迟看着只有 50ms,但实际有 10% 的请求卡在了 500ms 以上。用户体验极差。
所以我更关注这几个分位值:
- P50(中位数):一半请求的延迟低于这个值。反映“典型”体验。
- P99(99分位):99% 的请求延迟低于这个值。反映“最差”体验。
- P999(99.9分位):千分之一的最慢请求。这往往是系统瓶颈所在。
我的习惯:线上系统,我一般盯着 P99 看。P50 再漂亮,P99 崩了,用户照样骂娘。
2.1.3 召回率(Recall)
召回率衡量的是“该搜到的结果,搜到了多少”。公式很简单:
召回率 = 系统返回的相关文档数 / 总相关文档数
但实际测量时,难点在于“总相关文档数”怎么确定。我常用的方法是:
- 准备一个标注好的测试集(比如 1000 条查询,每条标注了正确答案)。
- 用系统跑一遍,看返回的结果里包含了多少正确答案。
- 召回率 = 命中数 / 总标注数。
注意:召回率和 QPS、延迟往往是矛盾的。你优化了召回率,可能延迟就上去了。这就是所谓的“性能-质量权衡”。
2.2 测试场景设计
指标定义好了,接下来就是设计测试场景。我把它分成三类:
2.2.1 单机压测
先测单台机器的极限。目的是摸清单机瓶颈在哪——是 CPU 不够?内存不够?还是磁盘 IO 卡住了?
我一般这样操作:
- 用
wrk或ab工具,从低并发开始(比如 10 并发),逐步增加。 - 记录每个并发下的 QPS 和 P99 延迟。
- 直到延迟突然飙升,或者 QPS 不再增长——那就是极限了。
2.2.2 集群压测
单机测完了,再上集群。这里有个经验:集群的 QPS 不是单机 QPS 的简单相加。因为网络开销、数据分布不均都会影响。
我记得有一次,我们 10 台机器,单机 QPS 是 2000,按理说集群应该能到 20000。结果实际只有 12000。查了半天,发现是某台机器负载特别高——数据倾斜了。
2.2.3 混合场景压测
真实场景不是只有一种查询。你得模拟:
- 简单查询(比如按 ID 查)
- 复杂查询(比如多字段组合、模糊匹配)
- 写入操作(索引更新)
我习惯按 70% 查询、20% 简单查询、10% 写入的比例来混合。这样更贴近线上。
2.3 测量方法与工具
工具选对了,事半功倍。我常用的几款:
| 工具 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| wrk | HTTP 接口压测 | 轻量、支持 Lua 脚本 | 不支持分布式 |
| JMeter | 复杂场景模拟 | 图形化、插件丰富 | 资源消耗大 |
| Locust | Python 项目 | 代码可控、易扩展 | 性能一般 |
| 自研工具 | 定制化需求 | 完全可控 | 开发成本高 |
我个人偏爱 wrk。轻量、简单,配合 Lua 脚本能模拟大部分场景。比如这样:
wrk -t12 -c400 -d30s http://localhost:9200/_search
# -t12: 12个线程
# -c400: 400个并发连接
# -d30s: 持续30秒
2.4 避坑指南
做基准测试,坑不少。我踩过的几个,分享给你:
坑一:测试数据太干净
我曾经用纯英文、短文本做测试,结果上线后中文长文本一上来,延迟直接翻倍。因为分词器、索引结构对中文不友好。所以,测试数据一定要和线上一致。
坑二:忽略预热
搜索引擎有缓存、有 JIT 编译。刚启动时性能很差。我习惯先跑 5 分钟“热身”,等指标稳定了再记录数据。
坑三:只看平均值
前面说了,平均值会掩盖问题。一定要看 P99、P999。我见过一个系统,平均延迟 30ms,但 P99 是 2 秒——这谁敢上线?
2.5 一个完整的测试流程
最后,给你一个我常用的测试流程模板:
- 准备数据:从线上抽取 10% 的真实数据,脱敏后作为测试集。
- 预热系统:跑 5 分钟低并发查询,让缓存和 JIT 生效。
- 单机压测:从 10 并发开始,每次增加 10,直到延迟超过 200ms 或 QPS 不再增长。
- 集群压测:用同样的方法,测 3 台、5 台、10 台机器。
- 混合场景:按 70% 查询、20% 简单查询、10% 写入的比例,跑 30 分钟。
- 记录数据:记录每个场景下的 QPS、P50、P99、P999 延迟、召回率。
- 分析瓶颈:看哪个指标先到瓶颈——是 CPU 100%?还是内存不足?还是磁盘 IO 打满了?
我的建议:每次优化后,都跑一遍这个流程。对比前后数据,你才能知道优化到底有没有效果。别凭感觉,数据说话。
嗯,基准测试就讲这么多。下一章,我们聊聊索引层面的优化——那才是搜索引擎性能的核心。