应用的性能很多时候都取决于数据库的性能,数据库的基准测试可以让我们知道数据库的性能怎样,瓶颈在哪。

基准测试的策略

基准测试有两种主要的策略:一种是集成式测试(针对整个系统的整体测试),另一种是单组件式测试(Mysql测试等组件测试)。在本文中主要介绍Mysql的基准测试,后续我会写一篇针对集成式的测试和这篇进行对应。

测试何种指标

在开始测试前,我们需要先清楚测试的目标是什么?测试目标决定了选择什么样的测试工具和技术,以获得精确而有意义的测试结果。

下面介绍几种测试指标:

吞吐量

吞吐量指的是单位时间内的事务处理数,测试单位是每秒事务数(TPS)或者每分钟事务数(TPM)。如果我们的应用是OLTP(在线事务处理)的应用,那么通过这个指标我们可以知道数据库能支持的业务量是多少。

响应时间或延迟

响应时间或延迟是执行某个任务的整体时间,单位一般是ms。通过这个时间我们可以知道某个任务的执行时间长短,然后有针对性的进行一些优化。

并发性

对于Mysql基准测试来说,并发性是指同时工作的线程数或者连接数。当并发性增加时,需要测试吞吐量是否下降,响应时间是否变长。并发性的测量不同于响应时间和吞吐量,他不像是一个结果,而更像是一个配置属性,通过并发性基准测试,可以知道系统在不同的并发性下的性能。

可扩展性

很多时候我们都会以为增加一倍的硬件配置,就能增加一倍的性能,但很多时候性能并不是1+1=2这样简单。所以我们需要通过可扩展性的测试,来清楚当我们扩展设备配置时,性能的提升是怎样,来支撑业务量的变化。

搭建测试环境

在《Mysql高性能》这本书上有介绍一些测试工具,下面我会根据书上的介绍进行测试,在正式测试前需要先配置测试环境,所以我在阿里云上弄了两台机器,下面两个机器的配置信息。

硬件配置

主机1:

mysql吞吐量每秒 mysql吞吐量测试_mysql吞吐量每秒

主机2:

mysql吞吐量每秒 mysql吞吐量测试_mysql_02

主机1是我半年前就已经买的,用于部署我自己的博客,主机2是为了这次测试特意购买的,从硬件配置上,两者的差距只是cpu的核数,一个为1核,一个为2核。

系统版本

主机1:CentOS 7.4 64位

主机2:CentOS 7.6 64位

mysql-server版本

主机1: 5.6.45

主机2: 5.6.45

安装mysql-server

#安装mysql客户端

yum install mysql;

#安装mysql服务端

wget http://repo.mysql.com/mysql-community-release-el7-5.noarch.rpm

sudo rpm -ivh mysql-community-release-el7-5.noarch.rpm

yum install mysql-server

#启动mysql服务端

service mysqld start

#关闭mysql服务端

service mysqld stop

#查看mysql状态

service mysqld status

Mysql基准套件-sysbench

sysbench可以用来测试Mysql的性能,例如cpu、io等

安装sysbench

wget https://downloads.mysql.com/source/sysbench-0.4.12.14.tar.gz

tar -xzvf sysbench-0.4.12.14.tar.gz

yum install automake

yum install libtool

yum install -y mysql-devel

cd sysbench-0.4.12.14

#修改configure.ac文件,将AC_LIB_PREFIX函数注释掉

./autogen.sh

./configure --prefix=/usr/sysbench/ --with-mysql-includes=/usr/include/mysql/ --with-mysql-libs=/usr/lib64/ --with-mysql

#通过ldconfig --print-cache | grep 'mysql',找到libmysqlclient位置然后进行修改

ln -s /usr/lib64/mysql/libmysqlclient.so.18 /usr/lib64/libmysqlclient.so

#开始编译

make & make install

#配置path路径

export PATH=$PATH:/usr/sysbench/bin

cpu基准测试

我们先对比下两台机器的cpu信息

1cat /proc/cpuinfo

主机1:

mysql吞吐量每秒 mysql吞吐量测试_dbt2 mysql_03

主机2:

mysql吞吐量每秒 mysql吞吐量测试_sql_04

通过上面的图片对比,可以知道主机2的cpu核数比主机1多,所以处理速度应该比主机1快,我们可以通过测试来验证这一点。

开始测试

我们采用的cpu测试实验为测试计算素数直到某个最大值所需要的时间。

1sysbench --test=cpu --cpu-max-prime=20000 run

测试结果

主机1:

mysql吞吐量每秒 mysql吞吐量测试_dbt2 mysql_05

主机2:

mysql吞吐量每秒 mysql吞吐量测试_基准测试_06

结论主机2比主机1的cpu处理速度快

虽然cpu核数多一倍,但是处理速度并没有快一倍

第二点和书上的结果不一致,虽然只有cpu核数不一样,但是因为我买的是云主机,很多时候性能还依赖于他的宿主机和厂商对于他的配置信息。后面的测试会更加说明这点。

I/O基准测试

文件I/O(fileio)可以测试系统在不同的I/O负载下的性能。对于sysbench,它的fileio测试可以很好的模拟InnoDB的特性。

准备测试数据

下面的文件在当前目录下生成10G的文件,可以根据自己的机器的硬盘大小进行调整。

1sysbench --test=fileio --file-total-size=10G prepare

开始测试1sysbench --test=fileio --file-total-size=10G --file-test-mode=rndrw --init-rng=on --max-time=300 --max-requests=0 run

测试结果

主机1:

mysql吞吐量每秒 mysql吞吐量测试_mysql_07

主机2:

mysql吞吐量每秒 mysql吞吐量测试_基准测试_08

结论主机1处理速度为21.27Mb/sec

主机2处理速度为6.1823Mb/sec

通过这个fileio测试,可以知道主机1的io性能比主机2快了三倍多,虽然看起来主机2的配置还比主机1更好。

清理文件1sysbench --test=fileio --file-total-size=10G cleanup

OLTP基准测试

sysbench的OLTP基准测试可以模拟简单的OLTP系统的工作负载

初始化环境打开mysql服务

进入mysql中,然后创建test数据库

准备表数据

下面的语句会在test数据库中创建一张100W行的表用于后面的测试

1sysbench --test=oltp --oltp-table-size=1000000 --mysql-db=test --mysql-user=root prepare

开始测试1sysbench --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

测试结果

主机1:

mysql吞吐量每秒 mysql吞吐量测试_基准测试_09

主机2:

mysql吞吐量每秒 mysql吞吐量测试_mysql吞吐量每秒_10

结论一分钟内,主机1的总事务数为86W

一份钟内, 主机2的总事务数为251W

在这次的测试实例中,主机2的总事务数比主机多了3倍。

清理数据1sysbench --test=oltp --oltp-table-size=1000000 --mysql-db=test --mysql-user=root cleanup

Mysql基准套件-dbt2

dbt2是一款免费的TPC-C测试工具,用于模拟复杂的OLTP系统。

安装dbt2

wget https://downloads.mysql.com/source/dbt2-0.37.50.15.tar.gz

tar -xzvf dbt2-0.37.50.15.tar.gz

cd dbt2-0.37.50.15

./configure --with-mysql

make

初始化数据1

2mkdir /var/lib/mysql-files/w5

./src/datagen -w 5 -d /var/lib/mysql-files/w5

修改scripts/mysql/mysql_load_db.sh1

2command_exec "$MYSQL $DB_NAME -e \"LOAD DATA $LOCAL INFILE \\\"$DB_PATH/$FN.data\\\"\

INTO TABLE $TABLE FIELDS TERMINATED BY '\t' ${COLUMN_NAMES} \""

修改为

command_exec "$MYSQL $DB_NAME -e \"LOAD DATA $LOCAL INFILE \\\"$DB_PATH/$FN.data\\\" IGNORE\

INTO TABLE $TABLE FIELDS TERMINATED BY '\t' ${COLUMN_NAMES} \""

如果不修改的话,会报这个错误

ERROR 1292 (22007) at line 1: Incorrect datetime value: ” for column ‘ol_delivery_d’ at row 20083

ERROR: rc=1

SCRIPT INTERRUPTED

导入数据1

2

3sh scripts/mysql/mysql_load_db.sh --database dbt2w5 --path /var/lib/mysql-files/w5 --socket /var/lib/mysql/mysql.sock --mysql-path /usr/bin/mysql

cd scripts/mysql

./mysql_load_sp.sh --database dbt2w5 --client-path /usr/bin

开始测试1

2cd ../../

./scripts/run_mysql.sh -c 10 -w 5 -t 300 -d dbt2w5 -u root -s /var/lib/mysql/mysql.sock --zero-delay

测试结果

主机1:

mysql吞吐量每秒 mysql吞吐量测试_mysql_11

主机2:

mysql吞吐量每秒 mysql吞吐量测试_mysql_12

结论主机1的每分钟事务数为4783.55

主机2的每分钟事务数为658

在复杂的OLTP测试中,主机1的处理速度又一次爆了主机2

Percona的tpcc-mysql测试工具

为了满足大型基准测试的需求,《高性能Mysql》的作者开发了tpcc-mysql。

安装tpcc-mysql

git clone https://github.com/Percona-Lab/tpcc-mysql.git

cd tpcc-mysql/src

make

初始化测试数据

为了更快的得出结果,我把测试数据的仓库数量改为5.

cd ..

mysqladmin create tpcc5

mysql tpcc5 < create_table.sql

mysql tpcc5 < add_fkey_idx.sql

./tpcc_load -h127.0.0.1 -d tpcc5 -u root -p "" -w 5

开始测试1./tpcc_start -h127.0.0.1 -dtpcc5 -w5 -c10 -r10 -l300

测试结果

主机1:

mysql吞吐量每秒 mysql吞吐量测试_dbt2 mysql_13

主机2:

mysql吞吐量每秒 mysql吞吐量测试_mysql吞吐量每秒_14

结论主机1的预热在10内就已经加载好了,并且每10S的处理的事务数为800多

主机2的预热在60S后才加载好,并且每10S的处理的事务数为200多

在tpcc的oltp测试中,主机1的处理速度依旧爆掉了主机2。

结尾

本来我购买主机2的原因是希望他的性能可以是主机2的两倍,但是根据多次的测试结果来看,主机2的fileio性能和复杂的oltp性能确实比不上主机1.这个测试结果算是意外之喜,因为他恰恰体现了基准测试的重要性,如果我们通过配置来进行估算性能,那么现实可能会给你一巴掌。