3. 压测工具选型:JMeter、sysbench、ClickHouse Benchmark 与自研脚本的优劣对比

做压测这么多年,我见过太多团队一上来就问“哪个工具最好”。其实没有最好的工具,只有最合适的场景。今天咱们就把市面上主流的几款压测工具掰开揉碎,看看它们各自擅长什么、短板在哪。

核心观点:工具选型不是技术选美,而是匹配你的测试目标。OLAP 压测关注的是吞吐、并发、查询延迟分布,和传统 Web 压测有本质区别。

3.1 Apache JMeter:全能型选手,但有点重

JMeter 是我最早接触的压测工具。说实话,它什么都能干——HTTP、JDBC、甚至自定义协议。但用在 OLAP 场景下,有几个地方得特别小心。

优势

  • 生态丰富:插件市场里能找到 ClickHouse JDBC 驱动、可视化报告生成器
  • 图形化界面:配置线程组、监听器、断言都很直观,适合快速验证
  • 分布式压测:支持 Master-Slave 模式,可以模拟多客户端并发

痛点

  • 资源开销大:每个线程都是一个 Java 线程,压 500 并发时 JMeter 自己先吃 2GB 内存。我在一次压测中遇到过 JMeter 进程 OOM,结果被测系统没事,压测工具先挂了
  • 结果聚合延迟:实时聚合器在高并发下会丢数据,尤其是 99 分位延迟统计经常不准
  • OLAP 协议支持弱:ClickHouse 的 Native 协议(TCP)需要自己写 Sampler,HTTP 接口倒是能用,但性能比 Native 差 30% 左右

我的建议:如果团队里测试人员习惯用 JMeter,可以保留它做功能验证和冒烟测试。但做 OLAP 的极限压测,我一般不推荐 JMeter 作为主力工具。

3.2 sysbench:轻量级基准测试,但场景有限

sysbench 是数据库圈的老牌工具。它最初是为 MySQL 设计的,后来社区扩展了 PostgreSQL、甚至 ClickHouse 的支持。但你要清楚——它擅长的是微基准测试,不是业务级压测。

适用场景

  • 硬件摸底:测试 CPU 算力、内存带宽、磁盘 IOPS
  • 简单 SQL 压测:比如固定模式的 SELECT COUNT(*)、INSERT 批量写入
  • 对比测试:同一台机器上换不同配置,看 sysbench 分数变化

局限性

  • 查询模式固定:sysbench 的 ClickHouse 支持只覆盖了最简单的聚合查询,复杂 JOIN、窗口函数、物化视图都测不了
  • 无业务语义:它不知道什么是“用户点击流分析”,什么是“实时报表”。说白了,它只测数据库的裸性能
  • 结果粒度粗:只输出平均延迟和 QPS,没有 P99/P999 分布,没有慢查询明细

避坑指南:我曾经用 sysbench 测出一台机器能跑 10 万 QPS,结果上线后真实业务连 2 万都扛不住。原因很简单——sysbench 的查询太简单了,缓存命中率 99%,真实查询全是随机扫描。sysbench 的数据只能做参考,不能替代业务压测。

3.3 ClickHouse Benchmark:官方工具,专为 OLAP 而生

这是 ClickHouse 官方提供的压测工具,全名叫 clickhouse-benchmark。它直接通过 Native 协议连接,不走 HTTP 转换,性能损耗最小。

核心能力

  • 多查询并发:可以指定并发数,每个连接独立发送查询
  • 实时统计:压测过程中实时输出 QPS、延迟分布、错误数
  • 查询文件驱动:把 SQL 写进文件,工具自动循环执行

典型用法

# 单条查询压测
clickhouse-benchmark --host=localhost --port=9000 \
  --query="SELECT count(*) FROM hits" \
  --concurrency=16 --iterations=1000

# 从文件读取查询集
clickhouse-benchmark --host=localhost \
  --queries-file=./queries.sql \
  --concurrency=32 --timelimit=60

优缺点分析

维度 评价
性能 极高,Native 协议无额外开销
易用性 中等,命令行参数多,学习曲线平缓
扩展性 差,不支持自定义协议、不支持分布式协调
报告能力 基础,只有终端输出,无图表
适用场景 单机/集群的 SQL 性能摸底、回归测试

我的习惯:每次 ClickHouse 版本升级后,我都会用 clickhouse-benchmark 跑一遍核心查询集,对比前后 QPS 和延迟变化。它最适合做性能回归,不适合做复杂业务场景模拟。

3.4 自研压测脚本:灵活但代价高

当上面这些工具都满足不了需求时,就得自己动手了。我在几个大项目中都走过这条路,说说真实感受。

什么时候必须自研?

  • 混合负载:同时压测写入和查询,模拟真实业务节奏
  • 自定义数据生成:需要按特定分布(Zipf、正态)生成测试数据
  • 复杂断言:比如校验查询结果是否一致、数据是否完整
  • 集成 CI/CD:需要把压测结果自动推送到监控系统或告警平台

一个简单的 Python 压测框架示例

import clickhouse_driver
import time
import threading
from statistics import quantiles

client = clickhouse_driver.Client(host='localhost')

def worker(queries, results):
    latencies = []
    for sql in queries:
        start = time.perf_counter()
        client.execute(sql)
        latencies.append(time.perf_counter() - start)
    results.extend(latencies)

# 启动 16 个线程并发
threads = []
all_results = []
for _ in range(16):
    t = threading.Thread(target=worker, args=(query_list, all_results))
    threads.append(t)
    t.start()

for t in threads:
    t.join()

# 计算 P50, P99, P999
p50, p99, p999 = quantiles(all_results, n=1000)[500], \
                 quantiles(all_results, n=100)[99], \
                 quantiles(all_results, n=1000)[999]
print(f"P50: {p50*1000:.2f}ms, P99: {p99*1000:.2f}ms, P999: {p999*1000:.2f}ms")

自研的代价

  • 开发成本:一个可用的压测框架至少 2-3 周,加上数据生成、结果分析、报告输出,轻松一个月
  • 维护成本:ClickHouse 版本升级可能破坏驱动兼容性,需要持续跟进
  • 结果可信度:自己写的统计逻辑可能有 bug,比如忘记处理超时、忘记排除预热数据

我曾经踩过的坑:自研脚本里用了 Python 的 time.sleep() 来控制请求间隔,结果因为 GIL 的存在,实际并发数比预期少了 30%。后来改用 asyncio 才解决。自研脚本的每一个细节都可能成为性能瓶颈,调试起来非常痛苦。

3.5 工具选型决策矩阵

我把四个工具的核心差异整理成一张表,方便你快速决策。

评估维度 JMeter sysbench clickhouse-benchmark 自研脚本
OLAP 协议支持 弱(需插件) 弱(仅基础 SQL) 强(Native 原生) 完全可控
并发模型 线程池 线程/进程 协程 自定义
延迟分布统计 基础 无 P50/P90/P99 完全自定义
学习成本 低 低 中 高
维护成本 低 低 低 高
推荐场景 功能验证、冒烟 硬件摸底 性能回归、基线 复杂业务模拟

3.6 我的选型建议

说了这么多,给个实际可操作的方案。

  1. 日常回归测试:用 clickhouse-benchmark,简单直接,结果稳定
  2. 硬件选型/配置对比:用 sysbench,快速出数据,排除网络干扰
  3. 团队协作/非技术人员参与:用 JMeter,图形界面降低沟通成本
  4. 线上流量模拟/复杂场景:自研脚本,但要做好投入 1 个月人力的准备

我的经验:大多数团队其实不需要自研。先用 clickhouse-benchmark 跑出基线,再用 JMeter 补几个业务场景,基本能覆盖 80% 的压测需求。剩下 20% 的复杂场景,等真正遇到瓶颈时再自研也不迟。

压测工具选型决策流程 压测需求确认 场景类型? 回归测试 clickhouse-benchmark 硬件摸底 sysbench 团队协作/冒烟 JMeter 复杂业务模拟 自研脚本 建议:先用 clickhouse-benchmark 跑基线,再用 JMeter 补业务场景,最后考虑自研