应用的性能很多时候都取决于数据库的性能,数据库的基准测试可以让我们知道数据库的性能怎样,瓶颈在哪。
基准测试的策略
基准测试有两种主要的策略:一种是集成式测试(针对整个系统的整体测试),另一种是单组件式测试(Mysql测试等组件测试)。在本文中主要介绍Mysql的基准测试,后续我会写一篇针对集成式的测试和这篇进行对应。
测试何种指标
在开始测试前,我们需要先清楚测试的目标是什么?测试目标决定了选择什么样的测试工具和技术,以获得精确而有意义的测试结果。
下面介绍几种测试指标:
吞吐量
吞吐量指的是单位时间内的事务处理数,测试单位是每秒事务数(TPS)或者每分钟事务数(TPM)。如果我们的应用是OLTP(在线事务处理)的应用,那么通过这个指标我们可以知道数据库能支持的业务量是多少。
响应时间或延迟
响应时间或延迟是执行某个任务的整体时间,单位一般是ms。通过这个时间我们可以知道某个任务的执行时间长短,然后有针对性的进行一些优化。
并发性
对于Mysql基准测试来说,并发性是指同时工作的线程数或者连接数。当并发性增加时,需要测试吞吐量是否下降,响应时间是否变长。并发性的测量不同于响应时间和吞吐量,他不像是一个结果,而更像是一个配置属性,通过并发性基准测试,可以知道系统在不同的并发性下的性能。
可扩展性
很多时候我们都会以为增加一倍的硬件配置,就能增加一倍的性能,但很多时候性能并不是1+1=2这样简单。所以我们需要通过可扩展性的测试,来清楚当我们扩展设备配置时,性能的提升是怎样,来支撑业务量的变化。
搭建测试环境
在《Mysql高性能》这本书上有介绍一些测试工具,下面我会根据书上的介绍进行测试,在正式测试前需要先配置测试环境,所以我在阿里云上弄了两台机器,下面两个机器的配置信息。
硬件配置
主机1:
主机2:
主机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信息
cat /proc/cpuinfo
主机1:
主机2:
通过上面的图片对比,可以知道主机2的cpu核数比主机1多,所以处理速度应该比主机1快,我们可以通过测试来验证这一点。
开始测试
我们采用的cpu测试实验为测试计算素数直到某个最大值所需要的时间。
sysbench --test=cpu --cpu-max-prime=20000 run
测试结果
主机1:
主机2:
结论
- 主机2比主机1的cpu处理速度快
- 虽然cpu核数多一倍,但是处理速度并没有快一倍
第二点和书上的结果不一致,虽然只有cpu核数不一样,但是因为我买的是云主机,很多时候性能还依赖于他的宿主机和厂商对于他的配置信息。后面的测试会更加说明这点。
I/O基准测试
文件I/O(fileio)可以测试系统在不同的I/O负载下的性能。对于sysbench,它的fileio测试可以很好的模拟InnoDB的特性。
准备测试数据
下面的文件在当前目录下生成10G的文件,可以根据自己的机器的硬盘大小进行调整。
sysbench --test=fileio --file-total-size=10G prepare
开始测试
sysbench --test=fileio --file-total-size=10G --file-test-mode=rndrw --init-rng=on --max-time=300 --max-requests=0 run
测试结果
主机1:
主机2:
结论
- 主机1处理速度为21.27Mb/sec
- 主机2处理速度为6.1823Mb/sec
通过这个fileio测试,可以知道主机1的io性能比主机2快了三倍多,虽然看起来主机2的配置还比主机1更好。
清理文件
sysbench --test=fileio --file-total-size=10G cleanup
OLTP基准测试
sysbench的OLTP基准测试可以模拟简单的OLTP系统的工作负载
初始化环境
- 打开mysql服务
- 进入mysql中,然后创建test数据库
准备表数据
下面的语句会在test数据库中创建一张100W行的表用于后面的测试
sysbench --test=oltp --oltp-table-size=1000000 --mysql-db=test --mysql-user=root prepare
开始测试
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
测试结果
主机1:
主机2:
结论
- 一分钟内,主机1的总事务数为86W
- 一份钟内, 主机2的总事务数为251W
在这次的测试实例中,主机2的总事务数比主机多了3倍。
清理数据
sysbench --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
初始化数据
mkdir /var/lib/mysql-files/w5
./src/datagen -w 5 -d /var/lib/mysql-files/w5
修改scripts/mysql/mysql_load_db.sh
command_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
导入数据
sh 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
开始测试
cd ../../
./scripts/run_mysql.sh -c 10 -w 5 -t 300 -d dbt2w5 -u root -s /var/lib/mysql/mysql.sock --zero-delay
测试结果
主机1:
主机2:
结论
- 主机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
开始测试
./tpcc_start -h127.0.0.1 -dtpcc5 -w5 -c10 -r10 -l300
测试结果
主机1:
主机2:
结论
- 主机1的预热在10内就已经加载好了,并且每10S的处理的事务数为800多
- 主机2的预热在60S后才加载好,并且每10S的处理的事务数为200多
在tpcc的oltp测试中,主机1的处理速度依旧爆掉了主机2。
结尾
本来我购买主机2的原因是希望他的性能可以是主机2的两倍,但是根据多次的测试结果来看,主机2的fileio性能和复杂的oltp性能确实比不上主机1.这个测试结果算是意外之喜,因为他恰恰体现了基准测试的重要性,如果我们通过配置来进行估算性能,那么现实可能会给你一巴掌。