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)

召回率衡量的是“该搜到的结果,搜到了多少”。公式很简单:

召回率 = 系统返回的相关文档数 / 总相关文档数

但实际测量时,难点在于“总相关文档数”怎么确定。我常用的方法是:

  1. 准备一个标注好的测试集(比如 1000 条查询,每条标注了正确答案)。
  2. 用系统跑一遍,看返回的结果里包含了多少正确答案。
  3. 召回率 = 命中数 / 总标注数。

注意:召回率和 QPS、延迟往往是矛盾的。你优化了召回率,可能延迟就上去了。这就是所谓的“性能-质量权衡”。

2.2 测试场景设计

指标定义好了,接下来就是设计测试场景。我把它分成三类:

2.2.1 单机压测

先测单台机器的极限。目的是摸清单机瓶颈在哪——是 CPU 不够?内存不够?还是磁盘 IO 卡住了?

我一般这样操作:

  • wrkab 工具,从低并发开始(比如 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 一个完整的测试流程

最后,给你一个我常用的测试流程模板:

  1. 准备数据:从线上抽取 10% 的真实数据,脱敏后作为测试集。
  2. 预热系统:跑 5 分钟低并发查询,让缓存和 JIT 生效。
  3. 单机压测:从 10 并发开始,每次增加 10,直到延迟超过 200ms 或 QPS 不再增长。
  4. 集群压测:用同样的方法,测 3 台、5 台、10 台机器。
  5. 混合场景:按 70% 查询、20% 简单查询、10% 写入的比例,跑 30 分钟。
  6. 记录数据:记录每个场景下的 QPS、P50、P99、P999 延迟、召回率。
  7. 分析瓶颈:看哪个指标先到瓶颈——是 CPU 100%?还是内存不足?还是磁盘 IO 打满了?

我的建议:每次优化后,都跑一遍这个流程。对比前后数据,你才能知道优化到底有没有效果。别凭感觉,数据说话。

嗯,基准测试就讲这么多。下一章,我们聊聊索引层面的优化——那才是搜索引擎性能的核心。