大家好,我是 @search_engineer,今天分享搜索系统性能压测的实战经验。
为什么要做压测?
在生产环境上线前,必须通过压测了解系统的:
- 容量上限:系统能支撑多大的 QPS
- 性能瓶颈:CPU、内存、磁盘、网络哪个先成为瓶颈
- 稳定性:长时间运行是否会出现内存泄漏、连接池耗尽等问题
- 降级策略:超过容量后如何优雅降级
压测工具选择
1. Elasticsearch 官方工具 - Rally
# 安装 Rally
pip install esrally
# 执行压测
esrally race --track=geonames --target-hosts=localhost:9200
特点:
- 官方维护,数据真实
- 内置多种测试场景(geonames、nyc_taxis、http_logs 等)
- 自动生成性能报告
2. Apache JMeter
适合场景:
- 需要自定义查询场景
- 需要模拟真实用户行为
- 需要复杂的断言验证
3. 自研压测工具
使用 Python + 多线程/协程:
import asyncio
import aiohttp
import time
async def search_query(session, url, query):
async with session.post(url, json=query) as resp:
return await resp.json()
async def benchmark():
url = "http://localhost:9200/my_index/_search"
query = {"query": {"match": {"title": "测试"}}}
async with aiohttp.ClientSession() as session:
tasks = [search_query(session, url, query) for _ in range(1000)]
start = time.time()
results = await asyncio.gather(*tasks)
print(f"QPS: {1000 / (time.time() - start)}")
asyncio.run(benchmark())
压测指标定义
查询性能指标
| 指标 | 说明 | 建议阈值 |
|---|---|---|
| QPS | 每秒查询数 | 根据业务需求 |
| P50 延迟 | 50% 请求延迟 | < 50ms |
| P99 延迟 | 99% 请求延迟 | < 200ms |
| 错误率 | 失败请求占比 | < 0.1% |
系统资源指标
| 指标 | 说明 | 建议阈值 |
|---|---|---|
| CPU 使用率 | 平均/峰值 | < 70% |
| 内存使用率 | JVM Heap | < 75% |
| 磁盘 IO | 读写 IOPS | < 80% 容量 |
| 网络带宽 | 入/出流量 | < 70% 带宽 |
压测步骤
Step 1:基线测试
# 单线程测试,获取基础性能
curl -X POST "localhost:9200/my_index/_search" -H 'Content-Type: application/json' -d'
{
"query": {"match_all": {}},
"size": 10
}'
记录:
- 单次查询延迟
- 系统资源基线
Step 2:梯度加压
逐步增加并发数:
- 10 并发 → 50 并发 → 100 并发 → 200 并发
- 每个梯度运行 5 分钟
- 记录 QPS 和延迟变化
Step 3:饱和测试
持续加压直到:
- QPS 不再增加
- 延迟开始指数上升
- 错误率超过阈值
记录饱和点,作为容量上限的 70% 使用。
Step 4:稳定性测试
在 80% 饱和压力下,持续运行 24 小时:
- 监控内存泄漏
- 监控连接池耗尽
- 监控磁盘空间增长
压测报告模板
# 搜索系统压测报告
## 测试环境
- ES 版本:8.11.0
- 节点数:3 数据节点 + 1 协调节点
- 配置:16C64G,SSD
- 数据量:1 亿文档,500GB
## 测试结果
### 查询性能
| 并发数 | QPS | P50 | P99 | 错误率 |
|--------|-----|-----|-----|--------|
| 10 | 500 | 20ms| 50ms| 0% |
| 50 | 2000| 25ms| 80ms| 0% |
| 100 | 3500| 28ms| 150ms| 0.01% |
| 200 | 4000| 50ms| 500ms| 0.5% |
### 容量评估
- 建议生产环境 QPS:2800(70% 饱和点)
- 扩容触发点:QPS > 2500
## 优化建议
1. 增加协调节点,降低数据节点查询压力
2. 热点数据增加副本,提升查询并发
3. 大聚合查询走独立路由,避免影响实时查询
常见问题
Q: 压测数据从哪里来?
A: 三种方式:
- 生产数据脱敏(最真实)
- 使用 Rally 官方数据集
- 程序生成模拟数据
Q: 压测会影响生产环境吗?
A: 必须隔离:
- 使用独立压测集群
- 网络隔离,避免流量影响生产
- 数据独立,避免污染生产数据
Q: 如何模拟真实查询?
A: 从生产日志提取:
- 收集 1 天生产查询日志
- 分析查询类型分布
- 按分布比例构造压测用例
总结
压测是保障搜索系统稳定运行的必要手段:
- 上线前必须压测
- 定期(每季度)复测
- 重大变更后重新压测
- 建立容量基线,指导扩容
参考资源
讨论
你在压测过程中遇到过哪些坑?欢迎在评论区分享!
本文由 @search_engineer 原创发布,转载请注明出处。
[尊重社区原创,转载请保留或注明出处]
本文地址:http://elasticsearch.cn/article/15677
本文地址:http://elasticsearch.cn/article/15677