2 MySQL 基准测试
2 MySQL 基准测试
1 概述
本章讨论 MySQL 和基于 MySQL 的应用的基准测试的重要性、策略和工具。最后特别讨论以下 sysbench,这是一款非常优秀的 MySQL 基准测试工具。
2 为什么需要基准测试
基准测试可以完成以下工作,或者更多。
- 验证基于系统的一些假设,确认这些假设是否符合实际情况。
- 重现系统中的某些异常行为,以解决这些异常。
- 测试系统当前的运行情况。了解当前系统的性能等。
- 模拟比当前系统更高的负载,以找出系统随着压力增加而可能遇到的扩展性瓶颈。
- 规划未来的业务增长。即测试后评估网络、硬件、以及其他相关的资源。
- 测试应用适应可变环境的能力。例如,发现系统在随机的并发峰值的性能表现,或者是不同配置的服务器之间的性能表现。
- 测试不同的硬件、软件和操作系统配置。
- 证明新采购的设备是否配置正确。
3 基准测试的策略
有两种主要的策略。
- 针对整个系统的整体测试。也称为集成式(full-stack)基准测试。
- 单独测试 MySQL。也称为单组件式(single-component)基准测试。
两种策略测试关注的点是不一样的。
3.1 测试何种指标
需要先明确测试的目标,测试目标决定了选择什么样的测试工具和技术,比如针对延迟(latency)和吞吐量(throughput)就需要采用不同的测试方法。
测试主要考虑以下指标
- 吞吐量。
- 响应时间或者延迟。
- 并发性。
- 可拓展性。
3.2 基准测试方法
一个好的基准测试需避免一些常见的错误。
- 使用真实数据的子集而不是全集。如需要处理几百 GB 的数据,但测试数据只有 1 GB。
- 使用错误的数据分布。
- 使用不真实的分布参数。
- 在多用户场景中,只做单用户的测试。
- 在单服务器上测试分布式应用。
- 与真实用户行为不匹配。
- 反复执行同一个查询。
- 没有检查错误。
- 忽略了系统预热的过程。
- 使用默认的服务器配置。
- 测试时间太短。
测试主要流程如下。
- 设计和规划基准测试。
- 基准测试应该运行多长时间。
- 获取系统性能和状态。需要记录的数据包括系统状态和性能指标,诸如 CPU 使用率、磁盘 I/O、网络流量统计、SHOW GLOBAL STATUS 计数器等,可以写脚本实现。
- 获得准确的测试结果。
- 运行基准测试并分析结果。最好是自动化测试。
- 将测试结果绘图展示。绘图能更加直观的观察到某些问题,典型的是周期性问题。可以使用 gnuplot 将文本第 5 步的文本数据绘制成图形。
示例测试脚本 mysqltest.sh
如下,将 /root/benchmarks/running
目录删除后就可以停止循环任务了。
#!/bin/sh
INTERVAL=5
PREFIX=$INTERVAL-sec-status
RUNFIFE=/root/benchmarks/running
mysql -proot123456 -e 'SHOW GLOBAL VARIABLES' >> mysql-variables
while test -e $RUNFILE;do
file=$(date +%F_%I)
sleep=$(date + %s.%N | awk "{print $INTERVAL - (\$1 % $INTERVAL)}")
sleep $sleep
ts="$(date + "TS %s.%N %F %T")"
loadavg="$(uptime)"
echo "$ts $loadavg" >> $PREFIX-${file}-status
mysql -proot123456 -e 'SHOW GLOBAL STATUS' >> $PREFIX-${file}-status &
echo "$ts $loadavg" >> $PREFIX-${file}-innodbstatus
mysql -proot123456 -e 'SHOW ENGINE INNODB STATUS\G' >> $PREFIX-${file}-innodbstatus &
echo "$ts $loadavg" >> $PREFIX-${file}-processlist
mysql -proot123456 -e 'SHOW FULL PROCESSLIST\G' >> $PREFIX-${file}-processlist &
echo $ts
done
echo Exiting because $RUNFIFE does not exist.
示例分析脚本为 analyze.sh
。将上面生成的文件使用命令 ./analyze.sh 5-sec-status-2022-04-02
分析,这块目前分析失败了,猜是因为版本问题,后面回头再整下。
#!/bin/sh
awk '
BEGIN {
printf "#ts date time load QPS"
fmt = " $.2f"
}
/^TS/ {
ts = substr($2, 1, index($2, ".") - 1);
loaad = NF - 2;
diff = ts - prev_ts;
prev_ts = ts;
printf "\n%s %s %s %s", ts, $3, $4, substr($load, 1, length($load)-1);
}
/Queries/ {
printf fmt, ($2-Queries)/diff
Queries=$2
}
' "$@"
4 基准测试工具
我们使用现有的工具可以解决大部分的问题。
4.1 集成式测试工具
简单的列举如下。
- ab。Apache HTTP 服务器基准测试工具。
- http_load。和 ab 类似,但比 ab 更灵活。
- JMeter。可以测试 Web 应用、FTP 服务器、JDBC 测试。
4.2 单组件式测试工具
简单的列举如下。
- mysqlslap。模拟服务器的负载,并输出计时信息。它包含在 MySQL 发行包中。支持自动生成查询 schema 的
SELECT
语句。 - MySQL Benchmark Suitte (sql-bench)。基准测试套件。它是单线程的,主要用于测试服务器执行查询的速度。这个套件的主要好处是包含了大量预定义的测试,其最大的缺点主要有:它是单用户的,测试的数据集很少且用户无法使用指定的数据,并且同一个测试多次运行的结果可能会相差很大。
- Super Smack。用于 MySQL 和 PostgreSQL 的基准测试工具,可以提供压力测试和负载生成,可以模拟多用户访问,可以加载测试数据到数据库,并支持使用随机数据填充测试表等。它是一个复杂而强大的工具。
- Database Test Suite。
- Percona's TPCC-MySQL Tool。
- sysbench。它是一款多线程系统压测工具。它可以根据影响数据库服务器性能的各种因素来评估系统的性能。例如,可以用来测试文件 I/O、操作系统调度器、内存分配和传输速度、POSIX 线程,以及数据库服务器等。sysbench 支持 Lua 脚本语言,Lua 对于各种测试场景的设置可以非常灵活。sysbench 是我们非常喜欢的一种全能测试工具,支持 MySQL、操作系统和硬件的硬件测试。
::: MySQL 提供了内置的 BENCHMARK() 函数,可以测试某些特定操作的执行速度。虽然用起来很方便,但不合适用来做真正的基准测试,因为很难理解真正要测试的是什么,而且测试的只是整个执行周期中的一部分环节。 :::
5 基准测试案例
演示上面提到的基准测试工具进行测试的真实案例,来帮助我们入门。
5.1 http_load
http_load 的安装如下。
$ wget http://www.acme.com/software/http_load/http_load-09Mar2016.tar.gz
$ tar zxvf http_load-09Mar2016.tar.gz
$ cd http_load-09Mar2016
# make install 时若出现 /usr/local/man/man1 目录不存在,则使用 mkdir -p /usr/local/man/man1 创建即可
$ make && make install
下面是简单的使用 http_load。
首先创建 urls.txt
文件,输入如下的 URL。
http://www.mysqlperformanceblog.com/
http://www.mysqlperformanceblog.com/page/2/
http://www.mysqlperformanceblog.com/mysql-patches/
http://www.mysqlperformanceblog.com/mysql-performance-presentations/
http://www.mysqlperformanceblog.com/2006/09/06/slow-query-log-analyzes-tools/
循环请求给定的 URL 列表。测试命令如下。
# 简单地输出统计信息
$ http_load -parallel 1 -seconds 10 urls.txt
22 fetches, 1 max parallel, 0 bytes, in 10.0008 seconds
0 mean bytes/connection
2.19983 fetches/sec, 0 bytes/sec
msecs/connect: 219.921 mean, 231.738 max, 212.422 min
msecs/first-response: 220.171 mean, 232.014 max, 212.775 min
HTTP response codes:
code 302 -- 22
# 尽可能快地循环请求给定的 URL 列表
$ http_load -parallel 5 -seconds 10 urls.txt
110 fetches, 5 max parallel, 0 bytes, in 10.0009 seconds
0 mean bytes/connection
10.999 fetches/sec, 0 bytes/sec
msecs/connect: 219.397 mean, 236.409 max, 209.913 min
msecs/first-response: 220.06 mean, 236.472 max, 211.1 min
HTTP response codes:
code 302 -- 110
# 根据预估的访问请求率(比如每秒 5 次)来做压力模拟测试
$ http_load -rate 5 -seconds 10 urls.txt
45 fetches, 5 max parallel, 0 bytes, in 10.0129 seconds
0 mean bytes/connection
4.49421 fetches/sec, 0 bytes/sec
msecs/connect: 262.107 mean, 527.036 max, 225.991 min
msecs/first-response: 252.711 mean, 529.103 max, 210.778 min
HTTP response codes:
code 302 -- 45
# 模拟更大的负载,可以将访问请求率提高到每秒 20 次请求。这样,连接和请求响应时间都会随着负载的提高而增加。
$ http_load -rate 20 -seconds 10 urls.txt
190 fetches, 11 max parallel, 0 bytes, in 10.0187 seconds
0 mean bytes/connection
18.9645 fetches/sec, 0 bytes/sec
msecs/connect: 246.765 mean, 273.503 max, 226.815 min
msecs/first-response: 231.528 mean, 257.34 max, 212.344 min
HTTP response codes:
code 302 -- 190
5.2 MySQL 基准测试套件
略。
5.3 sysbench
推荐。安装 yum install sysbench -y
。
- sysbench 的 CPU 基准测试。
# 查看 CPU 配置
$ cat /proc/cpuinfo
# 测试 CPU,通过时间可以对比 CPU 性能结果
$ sysbench --test=cpu --cpu-max-prime=20000 run
...
sysbench 1.0.17 (using system LuaJIT 2.0.4)
...
General statistics:
total time: 10.0005s
total number of events: 3980
...
- sysbench 的文件 I/O 基准测试。
# 创建一个数据集
$ sysbench fileio --file-total-size=1G prepare
# 运行,针对不同的 I/O 类型有不同的测试选项。seqwr:顺序写入;seqrewr:顺序重写;seqrd:顺序读取;rndrd:随机读取;rndwr:随机写入;rndrw:混合随机读/写。
$ sysbench fileio --file-total-size=1G --file-test-mode=rndrw --time=300 --max-requests=0 run
sysbench 1.0.17 (using system LuaJIT 2.0.4)
...
Threads started!
File operations:
reads/s: 994.61
writes/s: 663.07
fsyncs/s: 2121.94
...
General statistics:
total time: 300.0569s
total number of events: 1133978
...
Threads fairness:
events (avg/stddev): 1133978.0000/0.00
execution time (avg/stddev): 299.0384/0.00
# 清除生成的测试文件
$ sysbench fileio --file-total-size=1G cleanup
sysbench 的 OLTP 基准测试。 略。测试事务的。
sysbench 的其他特性。 和数据库没有关系的性能。
- 内存。测试内存的连续读写性能。
- 线程。测试线程调度器的性能。
- 互斥锁。测试互斥锁的性能。
- 顺序写。测试顺序写的性能。
完整的 sysbench 需查阅相关文档。
5.4 数据库测试套件中的 db2 TPC-C 测试
略。
5.5 Percona 的 TPCC-MySQL 测试工具
略,MySQL 性能测试推荐。
参考文献
- [高性能 MySQL]