MySQL基准测试
为什么需要benchmark
- 验证基于系统的假设,确认是否符合实际情况
- 重现系统中的某些异常行为,以解决它们
- 测试系统当前的运行情况,如果不清楚当前性能,就无法确认优化效果
- 模拟比当前系统更高的负载,用于找出可能遇到的拓展性瓶颈
- 规划业务增长,评估项目在未来负载下需要什么样的硬件、多大容量的网络及其他资源
- 测试应用适应可变环境的能力,如系统在随机的并发峰值下的性能表现
- 测试不同硬件、软件和操作系统配置
- 证明新采购的设备是否配置正确
策略
一是针对整个系统的整体测试,另外是单独测试MySQL,也称为集成式和单组件式基准测试
测试什么指标
- 吞吐量:单位时间内事务处理数,常用单位每秒事务数TPS、每分钟事务数TPM
- 响应时间或延迟:任务所需整体时间,单位可以是分钟、秒、毫秒、微秒
- 并发性:任意时间有多少同时发生的并发请求,一个Web站点可以同时有5w个用户访问,但可能只有20个并发请求到数据库,因此要关注正在工作的并发操作,检查数据库的Treads_running状态值
- 可拓展性:给系统增加一倍的资源,就能获得总共两倍的吞吐量
方法
常见错误:
- 使用真实数据的子集而不是全集
- 使用错误的数据分布
- 使用不真实的分布参数
- 在多用户场景中只做单用户的测试
- 在单服务器上测试分布式应用
- 与真实用户行为不匹配
- 反复执行同一个查询
- 没有检查错误
- 忽视系统预热过程
- 使用默认的服务器配置
- 测试时间太短
设计和规划基准测试
提出问题并明确目标,决定是标准测试还是专用测试
对连接使用独立线程重现,多次测试,详细记录
基准测试运行时间
应该运行足够长时间
获取系统性能和状态
记录系统状态、性能指标、CPU使用率、磁盘IO、网络流量统计等
#! /bin/shINTERVAL=5
PREFIX=$INTERVAL-sec-status
RUNFILE=/home/benchmarks/running
mysql -e 'SHOW GLOBAL VARIABLES' >> mysql-variables
while test -e $RUNFILE; dofile=$(date +%F_%I)sleep=$(date +%s.%N | awk "{print $INTERVAL - (\$1 % $INTERVAL)}")sleep $sleepts="$(date +"TS %s.%N %F %T")"loadavg="$(uptime)"echo "$ts $loadavg" >> $PREFIX-${file}-statusmysql -e 'SHOW GLOBAL VARIABLES' >> $PREFIX-${file}-status &echo "$ts $loadavg" >> $PREFIX-${file}-innodbstatusmysql -e 'SHOW ENGINE INNODB STATUS\G' >> $PREFIX-${file}-innodbstatus &echo "$ts $loadavg" >> $PREFIX-${file}-processlistmysql -e 'SHOW FULL PROCESSLIST\G' >> $PREFIX-${file}-processlist & echo $ts
done
echo Exiting because $RUNFILE does not exist.
- 每5秒执行一次收集的动作
- 每个文件名包含该轮测试开始的日期和小时
- 每次抓取数据都会记录当前时间戳
- 不会处理或过滤数据,保留元数据
- 如果需要在测试完成后脚本自动退出,只需删除/home/benchmarks/running文件即可
获得准确的测试结果
外部影响很多,尽可能降低这种影响,同时修改参数也尽量一点一点修改
运行基准测试并分析结果
自动化脚本测试是比较好的方式,结果最好用图表的格式绘制出来,这样可以直观看到很多光看数据无法被发现的问题
基准测试工具
集成式测试工具
ab
针对Web应用服务,结果转换成每秒能满足多少请求,只能针对单个URL进行尽可能快的压力测试
http_load
与ab类似,也被设计为对Web服务器进行测试,比ab更加灵活,通过一个输入文件提供多个URL,在这些URL中随机测试
JMeter
Java应用程序,可以加载其它应用并测试其性能,虽然设计用来测试Web应用,但也可用于测试FTP服务器,或JDBC数据库查询测试,比ab和http_load复杂得多,拥有绘图接口
单组件式测试工具
mysqlsalp
可模拟服务器的负载并输出即时信息
MySQL benchmark suite(sql-bench)
单线程的,主要用于测试服务器执行查询的速度,结果显示哪种类型的操作在服务器上执行得更快,包含了大量预定义的测试,也可用于高层次测试,缺点是单用户模式,数据集很小且无法使用指定的数据,无法测试多CPU能力,还需要Perl和BDB的支持
Super Smack
用于MySQL和PostgreSQL的肌醇测试工具,可提供压力测试和负载生成,可模拟多用户访问,可加载测试数据到数据库,支持使用随机数据填充测试表
sysbench
多线程系统压测工具,可用来测试文件IO、操作系统调度器、内存分配和传输速度、POSIX线程以及数据库服务器,支持Lua脚本语言
MySQL内置的BENCHMARK()函数
测试某些特定操作的执行速度,参数是需要执行的次数和表达式,返回值永远是0,但可通过返回时间判断执行的时间,不适合用来做真正的测试
案例
http_load
http_load -parallel 1 -seconds 10 [filename] # 单用户
http_load -parallel 5 -seconds 10 [filename] # 5个并发用户
http_load -rate 5 -seconds 10 [filename] # 每秒5次请求
sysbench
CPU基准测试
sysbench --test=cpu --cpu-max-prime=20000 run
文件IO基准测试
# 准备阶段
sysbench --test=fileio --file-total-size=150G prepare
# 运行阶段
sysbench --test=fileio --file-total-size=150G --file-test-mode=[seqwr/seqrewr/seqrd/rndrd/rndwr/rdnrw] \
--init-rng=on --max-time=300 --max-requests=0 run
# 清楚测试文件
sysbench --test=fileio --file-total-size=150G cleanup
OLTP基准测试
# 生成百万行记录的表
sysbench --test=oltp --oltp-table-size=1000000 --mysql-db=test/
--mysql-user=root prepare
# 测试(8个并发线程,只读模式,测试60秒)
sysbench --test=oltp --oltp-table-size=1000000 --mysql-db=test --mysql-user=root \
--max-time=60 --oltp-read-only=on --max-requests=0 --num-threads=8 run
其他特性
内存连续读写/线程调度器/互斥锁/顺序写性能