第二章:MySQL基准测试

1.为什么要进行基准测试

​ 基准测试是唯一方便有效的可以观察系统在不同压力下的行为,评估系统的容量的方法

​ 在新系统正式上线到生产环境之前,进行基准测试是个好习惯。切勿相信云RDS提供商或者主机提供商的所为多快多稳定的说法。

​ 基准测试并不是基于真实压力的测试,其压力通常较为单调简单。基准测试在实际情况下通常会要求快速完成,压测实施者往往会施以实际中远远不能达到的且单调请求的压力,虽然有益于测量系统最大性能容量,但往往会使系统或者压测软件崩溃,得不到真正符合实际的数值

​ 真实测试是不可预期且变化多端的,有时情况会复杂且难以解释。

​ 当压测发现新系统可以支持原系统40倍的TPS时,不能简单的就认为新系统可以支持40倍的业务增长。因为系统是个复合的系统,除了单个业务的TPS还要考虑该业务与其他业务或者系统交互之间的交互,甚至网络和磁盘的因素都要考虑到其中。

​ 结论:我们只能进行大概的测试,得出系统的大致余量,基准测试要尽量简单直接,结果之间要容易相互比较,成本低且易于执行。可以使用控制变量法。

2.基准测试的策略

​ 集成式测试:测试整个系统,发现各部分之间缓存带来的影响。整体应用的集成式测试更能揭示应用的真是表现。一般测试组的同事会偏向于使用此策略。

​ 单组件测试:只关注MySQL的性能,进行比较不同的数据库或者查询的性能,针对应用中某个具体问题进行测试,通过一个短期的单组件基准测试,做快速的周期循环,检测某些调整后的效果。

测试目标

​ 有的放矢,测试之前一定要明确测试目的与目标。测试目标决定了选择什么样的测试工具和技术。

​ 吞吐量:单位时间事务处理数,指标为TPS(每秒事务数)。

​ 响应时间:任务所需的整体时间,通常为平均响应时间,最小/最大响应时间。但最大响应时间往往被百分比响应时间代替,例如,若95%的响应时间都是5毫秒,则表示任务在95%的时间段内都可以在5毫秒之内完成。

​ 并发性:Web服务器的并发性是指在任意时间有多少同时发生的并发请求,其高并发一般会导致数据库的高并发。但一个Web站点“同时有5W个用户”访问,却可能只有10-15个并发请求到MySQL数据库。并发性基准测试需要关注的是正在工作中的并发操作,或者同时工作中的线程或者连接数,当并发性增加时,需要关注并测量吞吐量是否随之下降,响应时间变长。并发性测试通常是为了测试在不同并发下的性能。

​ 可扩展性:可以理解为,给系统增加一倍的工作,在理想情况下就能获得两倍的结果,即吞吐量增加一倍。或者说给系统增加一倍的资源就能获得两倍的吞吐量。可扩展性指标可以帮助发现应用性能的平静。

​ 总结:确定测试对象为对于用户来说最重要的指标,然后收集应用方的需求,例如:什么样的响应时间是可以接受的,期待多少的并发性等等,最后基于这些需求进行设计基准测试。

测试方法

​ 测试时应避免如下的常见错误:

​ 使用部分的真实数据进行测试和扩展性有关的项目。

​ 错误的数据分布

​ 测试数据相对生产数据而言分布不均匀

​ 在多用户的场景中,却只测试单用户的情景。

​ 在单台服务器上测试分布式应用

​ 测试脚本或者软件模拟的用户行为不真实,不现实

​ 短时间内反复执行同一个查询,会因为查询缓存的存在导致结果不准确

​ 在一轮结果异常的测试结束后不分析异常的原因就直接进入下一轮

​ 不进行预热就直接进行测试

​ 未使用合理的数据库参数

​ 测试时间太短

设计和规划基准测试

​ 第一步先提出问题并明确目标,然后觉得采用标准的基准测试还是设计特定情景的测试

​ 基准测试软件:TPCH,即席查询和决策支持型应用的基准测试。即OLAP

​ TPCC,订单型业务交易系统应用的基准测试。即OLTP

​ LinkBench,人际关系型应用的基准测试。等等

​ 特定情境测试:首先获得生产数据集的快照

​ 然后只针对数据进行查询。

​ 提前做好测试规划:应包括准备测试数据,系统配置的步骤,设计预热方案,测量并分析测试结果

基准测试应运行足够长的时间

​ 大部分系统都会有一些应对突发情况的余量,能够收集性能尖峰,将一些工作延迟到高峰期之后执行,但当对机器加压足够长的时间后,这些余量会被消耗殆尽,系统的短期高峰也就无法维持原来的高性能。至少应当让测试一直运行到确认系统已经稳定运行之后。其中,系统看起来稳定的时间至少大于等于系统预热所需要的时间。

​ 如果没有时间去完成准确完整的基准测试,那么已经花费的所有时间都是一种浪费。

获取系统性能和状态

​ 执行基准测试时,需要尽可能多的收集被测试系统的信息,最好为测试建立一个专用的目录,每次执行一轮测试都创建对应的独立子目录,将测试结果,配置文件,测试指标,脚本和其他相关说明都保存在其中。

​ 需要着重考虑的系统状态和指标:CPU使用率,磁盘IO,网络流量统计,数据库status杂项等。

​ 下面给出一个数据收集脚本范例:

#!/bin/sh

INTERVAL=5
PREFIX=$INTERVAL-sec-status
RUNFILE=/root/running
mysql -e 'show global variables'>>mysql-variables
while  test -e $RUNFILE; do
        file=$(date +%F_%H)
        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 -e "show global status" >> $PREFIX-${file}-status &
        echo "$ts $loadavg">> $PREFIX-${file}-innodbstatus
        mysql -e "show engine innodb status\G" >> $PREFIX-${file}-innodbstatus &
        echo "$ts $loadavg">> $PREFIX-${file}-processlist
        mysql -e "show full processlist\G" >>$PREFIX-${file}-processlist &
        echo $ts
done
echo Exiting because $RUNFILE not exist

获取准确的测试结果

​ 第一步:审查如下项目

​ 是否选择了正确的基准测试类型?

​ 是否为问题收集了相关的线上数据?

​ 是否采用了正确的测试标准?

​ 第二步:确认测试结果是否有可重复性。每次重新测试之前都要确保系统的状态是一致的,甚至每次测试之前都重启系统。还要确保每次预热的时间足够长。

​ 如果预热测试用的是随机查询,那么测试结果可能就不是可重复的。如果测试的过程中会修改数据或者DDL,那么每次测试之前,需要利用快照还原数据。

​ 可以利用控制变量法,每次测试中,修改的参数应该尽量少。一般情况下,都是通过迭代逐步地修改基准测试的参数。

​ 如果在测试中出现异常结果,不要轻易当作垃圾结果直接丢弃,应当认真研究并找到产生这种结果的原因。如果对测试结果不了解,就不要轻易公布。

运行测试并分析结果

​ 基准测试通常需要运行多次,具体运行多少次要看对结果的计分方式,以及测试结果的重要程度。若需要提高测试的准确度就需要多运行几次。一般在测试的实践中,可以取最好的结果值,或者所有结果的平均值,抑或是从五个测试结果里去最好三个值的平均值。只要测试的结果能满足目前的需求,简单地运行几轮测试,看看结果的变化就可以了。若结果变动很大,可以再多运行几次,或者运行更长的时间,以求获得更确定的结果。

​ 在运行完测试,获得测试结果后,要把测试结果的数字,通过分析变成知识或者经验,并回答在设计测试时提出的问题或者目标。可以通过编写脚本来抽象分析测试结果中的数据。这里给出一个针对前面采集脚本的一个分析脚本。

#!/bin/sh
awk '
        BEGIN{
                printf "#ts date time load QPS";
                fmt = " %.2f";
                }
                /^TS/ { # The timestamp lines begin with TS.
                        ts = substr($2, 1, index($2,".") - 1);
                        load = 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
                }
                ' "$@"

​ 运行方式:sh hi_anaylyze.sh 5-sec-status-2018-02-22_14_status >>4plot.log (将分析后的结果记入4plot.log中)

绘图

​ 绘图有很多种方式,EXCEL,rrdtools,gnuplot都可以。

​ 这里介绍gnuplot的绘图方式。

gunplot>plot '4plot' using 5 with lines title 'QPS', 4 with lines title 'load'

​ 解析:using 5 表示使用第5列数据作图

​ with lines 定义图中的趋势使用线来表示

​ title 'QPS' 定义线的名称

​ 使用,(逗号)分割,进行多列数据的绘制

​ 如图:gnuplot绘图示例

测试工具

​ 常用集成式测试工具:

​ ab

​ http_load

​ Jmeter

​ 常用单组件测试工具:

​ mysqlslap:包含在MySQL的安装包中

​ sql-bench:包含在MySQL的安装包中(5.6及以前)

​ TPCC,percona`s TPCC:针对订单交易型

​ sysbench:全能的多线程系统压测工具,可以配合Lua脚本进行多样化的系统软硬件测试。

3.压力测试测试实操