问题

用 mysqlslap 压测 SQL 的结果,好像比用 sysbench 压测 SQL 的结果更平稳,为什么?

实验

随便找个数据库,

我们用以下 SQL 进行压测:

select sleep(@val := coalesce(@val, 0) + 1) from dual;

在同一个数据库连接中,这个 SQL 每运行一次,sleep 的时间都会加一秒。第一次是 sleep(1),第二次是 sleep(2),…

我们先用 mysqlslap 进行压测:

查看结果:

解读一下 mysqlslap 的结果:

  • 每轮 SQL 平均运行 15s

  • 一轮 SQL 平均运行 5 个 SQL

  • 推导出每个 SQL 平均运行 3s

需要注意:结果中有个 Max 和 Min,经常发现大家将 Max 除以每轮 SQL 的个数,得出 SQL 延迟的最大时间,这个计算是错误的。

Max 和 Min 指的是如果 mysqlslap 进行多轮测试(iterations > 1),每轮运行时间的最大值和最小值。与单个 SQL 的延迟无关。

在本例中,如果我们将 –iterations 改成 3,得到的 Max/Avg/Min 都是 15s 左右,但我们知道这些 SQL 的延迟分别是 1s,2s,…,5s,通过 Max/Avg/Min 无法计算得到单个 SQL 延迟的最大值/最小值。

再用 sysbench 测一次:

写一个 LUA 脚本(不会写的同学,可以直接复制 sysbench 自带的脚本 bulk_insert.lua,拿过来改一改):

然后运行 sysbench 压测:

查看结果,会发现 95% 分位数偏离平均值比较远,意味着同一个 SQL 的延迟变化较大。

通过以上简单实验,我们发现:

  • sysbench 可以反映出单个 SQL 或者局部 SQL 延迟异常的情况

  • mysqlslap 的测量对象是一个轮次,不能反映单个 SQL 的延迟情况。如果用简单的除法估算 SQL 延迟,SQL 延迟的波动会比实际情况平稳得多。

也就是说 mysqlslap 比 sysbench 的压测结果更平稳的原因,是大家对 mysqlslap 的结果进行处理时进行了错误的计算,导致波动被消除。

小贴士

本例中,我们特意使用了同一个 SQL。如果业务压力来自于不同的 SQL,可以使用 ps_statement_avg_latency_histogram 获取不同 SQL 间的延迟差异图。

关于 MySQL 的技术内容,你们还有什么想知道的吗?赶紧留言告诉小编吧!