4. 压测工具选型与配置:sysbench、JMeter、wrk2 的聚合查询场景配置方法

聚合查询压测对工具的要求与普通 OLTP 压测有显著差异:需要支持自定义 SQL、能够精确控制并发模型、必须能采集尾延迟(p99/p999)而非仅平均延迟。本章对三款主流压测工具在聚合查询场景下的选型依据、配置要点和参数陷阱进行系统对比。

4.1 工具选型对比矩阵

对比维度 sysbench JMeter wrk2
核心定位 数据库基准压测 通用协议压测平台 HTTP 延迟压测
聚合 SQL 支持 原生 Lua 脚本 + 自定义 SQL JDBC 请求 + 参数化查询 需配合后端应用层
并发模型 线程池 + 事件循环 线程组 + 虚拟用户 多线程 + 固定连接数
尾延迟采集 内置百分位统计 需插件或聚合报告 原生延迟分布直方图
聚合查询场景适配度 ★★★★★ ★★★★☆ ★★★☆☆
学习成本 低 中 低
选型建议: 聚合查询压测首选 sysbench,因其对数据库协议的原生支持和 Lua 脚本灵活性;JMeter 适合需要复杂断言和多协议混合的场景;wrk2 仅推荐在聚合查询通过 HTTP API 暴露时使用,且需额外处理连接池和超时。

4.2 sysbench 聚合查询配置

4.2.1 自定义 Lua 脚本结构

sysbench 通过 Lua 脚本定义压测逻辑,聚合查询场景需要重写 event() 函数。以下是一个针对 TPC-H 类聚合查询的脚本模板:

-- agg_query.lua
local stmt_defs = {
    stmt1 = [[
        SELECT /*+ PARALLEL(4) */
            c_custkey,
            COUNT(o_orderkey) as order_cnt,
            SUM(o_totalprice) as total_revenue
        FROM customer
        JOIN orders ON c_custkey = o_custkey
        WHERE o_orderdate BETWEEN '1994-01-01' AND '1994-12-31'
        GROUP BY c_custkey
        HAVING SUM(o_totalprice) > 100000
        ORDER BY total_revenue DESC
        LIMIT 100
    ]],
}

function thread_init()
    drv = sysbench.sql.driver()
    con = drv:connect()
    -- 预编译所有语句
    stmts = {}
    for name, sql in pairs(stmt_defs) do
        stmts[name] = con:prepare(sql)
    end
end

function event()
    local stmt = stmts["stmt1"]
    local rs = stmt:execute()
    rs:fetch_all()  -- 强制消费结果集
    rs:close()
end

function thread_done()
    for _, stmt in pairs(stmts) do
        stmt:close()
    end
    con:disconnect()
end

4.2.2 关键参数配置

参数 推荐值 说明
--threads 16~128 根据数据库 CPU 核数设定,聚合查询建议不超过 CPU 核数×2
--time 300 聚合查询预热时间长,建议至少 5 分钟
--report-interval 10 每 10 秒输出一次中间统计,便于观察尾延迟变化趋势
--percentile 99 默认只输出 95 分位,聚合查询必须设为 99 或 99.9
--histogram on 输出延迟直方图,用于分析尾延迟分布形态
--db-driver mysql / pgsql 根据目标数据库选择对应驱动
常见陷阱: sysbench 默认的 --report-interval=0 只在压测结束时输出一次统计,无法观察尾延迟在压测过程中的波动。聚合查询的尾延迟往往在压测中段开始劣化,必须开启间隔报告。

4.2.3 启动命令示例

sysbench \
  --db-driver=mysql \
  --mysql-host=192.168.1.100 \
  --mysql-port=3306 \
  --mysql-user=perf \
  --mysql-password=perf123 \
  --mysql-db=tpch_10g \
  --threads=64 \
  --time=300 \
  --report-interval=10 \
  --percentile=99 \
  --histogram=on \
  --rand-type=uniform \
  /path/to/agg_query.lua \
  run

4.3 JMeter 聚合查询配置

4.3.1 测试计划结构

JMeter 配置聚合查询压测的核心步骤:

  1. 添加 JDBC Connection Configuration:配置数据库连接 URL、驱动类、连接池参数
  2. 添加 JDBC Request:写入聚合 SQL,选择 Callable Statement 或 Select Statement
  3. 添加 Listener:使用 jp@gc - Response Times Over Time 和 jp@gc - Percentiles 插件采集尾延迟
  4. 配置线程组:设置目标并发数、Ramp-Up 时间、循环次数

4.3.2 关键配置参数

配置项 推荐值 说明
JDBC Connection Pool Max 等于线程组线程数 避免连接争用导致额外延迟
JDBC Request Timeout 60000 ms 聚合查询执行时间长,默认 30s 容易超时
Transaction Control 不对聚合查询使用事务 聚合查询通常为只读,事务会增加无谓开销
ResultSet Fetch Size 1000 聚合结果集可能较大,适当增大减少网络往返
JMeter 特有优势: 可以通过 __P() 函数实现参数化,例如将聚合查询中的日期范围、分组字段等作为变量,在压测过程中动态切换,模拟不同聚合维度的混合负载。

4.4 wrk2 聚合查询配置

4.4.1 适用场景限制

wrk2 是 HTTP 层压测工具,无法直接连接数据库。聚合查询场景下仅适用于以下架构:

  • 数据库通过 REST API 或 GraphQL 暴露聚合查询接口
  • 应用层封装了聚合查询逻辑,wrk2 压测 HTTP 端点
  • 需要测量从 HTTP 请求到聚合结果返回的端到端延迟

4.4.2 Lua 脚本配置

-- wrk2_agg.lua
wrk.method = "POST"
wrk.body = [[
    {
        "query": "SELECT c_custkey, COUNT(o_orderkey) as cnt
                  FROM customer JOIN orders ON ...
                  GROUP BY c_custkey LIMIT 100",
        "params": {}
    }
]]
wrk.headers["Content-Type"] = "application/json"

-- 自定义延迟分布采集
response = function(status, headers, body)
    if status ~= 200 then
        -- 记录错误,但不影响延迟统计
        wrk.status = status
    end
end

4.4.3 启动命令

wrk2 -t 16 -c 64 -d 300s -R 1000 \
  -s wrk2_agg.lua \
  --latency \
  --u_latency \
  http://api.example.com/aggregate
参数说明: -R 指定目标吞吐量(RPS),wrk2 的独特优势是可以在固定吞吐量下测量延迟,非常适合验证聚合查询在特定 QPS 下的尾延迟表现。--u_latency 输出微秒级延迟分布。

4.5 三工具聚合查询压测流程对比

三工具聚合查询压测流程对比 sysbench 流程 ① 编写 Lua 脚本(聚合 SQL) ② 配置线程数/时间/百分位 ③ 执行 run 命令 ④ 输出 p99/p999 + 直方图 JMeter 流程 ① 配置 JDBC Connection Pool ② 添加 JDBC Request + SQL ③ 添加 Percentiles 监听器 ④ 运行并查看聚合报告 wrk2 流程 ① 准备 HTTP API 端点 ② 编写 Lua 脚本(POST 体) ③ 设置 -R 目标吞吐量 ④ 输出延迟分布 + 尾延迟 输出对比:p99 延迟 / 吞吐量 / 错误率 / 延迟分布直方图 选型决策要点: • 数据库直连 + 聚合 SQL 复杂 → sysbench(原生支持,脚本灵活) • 需要多协议混合 + 图形化报告 → JMeter(插件生态丰富) • HTTP API 暴露 + 固定吞吐量压测 → wrk2(延迟精度高)

4.6 配置参数速查表

配置维度 sysbench 参数 JMeter 配置 wrk2 参数
并发控制 --threads=N 线程组线程数 -t N -c N
压测时长 --time=N 调度器持续时间 -d Ns
目标吞吐量 不直接支持 Constant Throughput Timer -R N
尾延迟分位 --percentile=99 jp@gc - Percentiles --latency
延迟分布 --histogram=on jp@gc - Response Times Distribution --u_latency
预热时间 需脚本内实现 Ramp-Up 时间 需脚本内实现
核心原则: 聚合查询压测的配置重点在于 尾延迟采集精度 和 并发模型与数据库资源的匹配。sysbench 的 --percentile=99 和 --histogram=on 是必选参数;JMeter 必须安装 JMeter Plugins Manager 并添加 3 Basic Graphs 和 5 Additional Graphs 插件集;wrk2 的 --u_latency 提供微秒级精度,对聚合查询这种毫秒级延迟场景尤为重要。