掌握数据库的性能情况是非常必要的。本文介绍了MySQL基准测试的基本概念,以及使用sysbench对MySQL进行基准测试的详细方法,本文主要针对金山的单版RDS数据库测试。
数据库的基准测试是对数据库的性能指标进行定量的、可复现的、可对比的测试。
基准测试与压力测试
基准测试可以理解为针对系统的一种压力测试。但基准测试不关心业务逻辑,更加简单、直接、易于测试,数据可以由工具生成,不要求真实;而压力测试一般考虑业务逻辑(如购物车业务),要求真实的数据。
对于多数Web应用,整个系统的瓶颈在于数据库;原因很简单:Web应用中的其他因素,例如网络带宽、负载均衡节点、应用服务器(包括CPU、内存、硬盘灯、连接数等)、缓存,都很容易通过水平的扩展(俗称加机器)来实现性能的提高。而对于MySQL,由于数据一致性的要求,无法通过增加机器来分散向数据库写数据带来的压力;虽然可以通过前置缓存(Redis等)、读写分离、分库分表来减轻压力,但是与系统其它组件的水平扩展相比,受到了太多的限制。
而对数据库的基准测试的作用,就是分析在当前的配置下(包括硬件配置、OS、数据库设置等),数据库的性能表现,从而找出MySQL的性能阈值,并根据实际系统的要求调整配置。
常见的数据库指标包括:
TPS/QPS:衡量吞吐量。(TPS:每秒事务处理量(TransactionPerSecond)、每秒查询率QPS是对一个特定的查询服务器在规定时间内所处理流量多少的衡量标准)
响应时间:包括平均响应时间、最小响应时间、最大响应时间、时间百分比等,其中时间百分比参考意义较大,如前95%的请求的最大响应时间。。
并发量:同时处理的查询请求的数量。
对MySQL的基准测试,有如下两种思路:
(1)针对整个系统的基准测试:通过http请求进行测试,如通过浏览器、APP或postman等测试工具。该方案的优点是能够更好的针对整个系统,测试结果更加准确;缺点是设计复杂实现困难。
(2)只针对MySQL的基准测试:优点和缺点与针对整个系统的测试恰好相反。
在针对MySQL进行基准测试时,一般使用专门的工具进行,例如mysqlslap、sysbench等。其中,sysbench比mysqlslap更通用、更强大,且更适合Innodb(因为模拟了许多Innodb的IO特性),下面介绍使用sysbench进行基准测试的方法。
创建RDS实例并将云主机添加到RDS实例
在云主机终端上可以用命令行连接到RDS数据库,如下:
[root@vm192-168-80-2 sysbench-1.0]# mysql -h 192.168.89.18 -u admin -p
sysbench是跨平台的基准测试工具,支持多线程,支持多种数据库;主要包括以下几种测试:
cpu性能
磁盘io性能
调度程序性能
内存分配及传输速度
POSIX线程性能
数据库性能(OLTP基准测试)
本文主要介绍对数据库性能的测试。
本文使用的环境时CentOS 6.8;在其他Linux系统上的安装方法大同小异。MySQL版本是5.6。
下载解压
wget https://github.com/akopytov/sysbench/archive/1.0.zip -O "sysbench-1.0.zip"
unzip sysbench-1.0.zip
cd sysbench-1.0
安装依赖
yum install automake libtool –y
安装
./autogen.sh
./configure
make
make install
安装成功
sysbench --version
sysbench 1.0.9
执行sysbench –help,可以看到sysbench的详细使用方法。
sysbench的基本语法如下:
sysbench [options]… [testname] [command]
下面说明实际使用中,常用的参数和命令。
(1)command
command是sysbench要执行的命令,包括prepare、run和cleanup,顾名思义,prepare是为测试提前准备数据,run是执行正式的测试,cleanup是在测试完成后对数据库进行清理。
(2)testname
testname指定了要进行的测试,在老版本的sysbench中,可以通过–test参数指定测试的脚本;而在新版本中,–test参数已经声明为废弃,可以不使用–test,而是直接指定脚本。
例如,如下两种方法效果是一样的:
sysbench --test=./tests/include/oltp_legacy/oltp.lua
sysbench ./tests/include/oltp_legacy/oltp.lua
测试时使用的脚本为lua脚本,可以使用sysbench自带脚本,也可以自己开发。对于大多数应用,使用sysbench自带的脚本就足够了。不同版本的sysbench中,lua脚本的位置可能不同,可以自己在sysbench路径下使用find命令搜索oltp.lua。P.S.:大多数数据服务都是oltp类型的,如果你不了解什么是oltp,那么大概率你的数据服务就是oltp类型的。
(3)options
sysbench的参数有很多,其中比较常用的包括:
MySQL连接信息参数
--mysql-host:MySQL服务器主机名,默认localhost;如果在本机上使用localhost报错,提示无法连接MySQL服务器,改成本机的IP地址应该就可以了。
--mysql-port:MySQL服务器端口,默认3306
--mysql-user:用户名
--mysql-password:密码
MySQL执行参数
--oltp-test-mode:执行模式,包括simple、nontrx和complex,默认是complex。simple模式下只测试简单的查询;nontrx不仅测试查询,还测试插入更新等,但是不使用事务;complex模式下测试最全面,会测试增删改查,而且会使用事务。可以根据自己的需要选择测试模式。
--oltp-tables-count:测试的表数量,根据实际情况选择
--oltp-table-size:测试的表的大小,根据实际情况选择
--threads:客户端的并发连接数
--time:测试执行的时间,单位是秒,该值不要太短,可以选择120
--report-interval:生成报告的时间间隔,单位是秒,如10
在执行sysbench时,应该注意:
(1)尽量不要在MySQL服务器运行的机器上进行测试,一方面可能无法体现网络(哪怕是局域网)的影响,另一方面,sysbench的运行(尤其是设置的并发数较高时)会影响MySQL服务器的表现。
(2)可以逐步增加客户端的并发连接数(–thread参数),观察在连接数不同情况下,MySQL服务器的表现;如分别设置为10,20,50,100等。
(3)一般执行模式选择complex即可,如果需要特别测试服务器只读性能,或不使用事务时的性能,可以选择simple模式或nontrx模式。
(4)如果连续进行多次测试,注意确保之前测试的数据已经被清理干净。
下面是sysbench使用的一个例子:
(1)准备数据
sysbench ./tests/include/oltp_legacy/oltp.lua --mysql-host=192.168.89.18 --mysql-port=3306 --mysql-user=admin --mysql-password=Aa123456 --oltp-test-mode=complex --oltp-tables-count=10 --oltp-table-size=100000 --threads=10 --time=120 --report-interval=10 prepare
使用了10个表,每个表有10万条数据,客户端的并发线程数为10,执行时间为120秒,每10秒生成一次报告。
(2)执行测试
将测试结果导出到文件中,便于后续分析。
sysbench ./tests/include/oltp_legacy/oltp.lua --mysql-host=192.168.89.18 --mysql-port=3306 --mysql-user=admin --mysql-password=Aa123456 --oltp-test-mode=complex --oltp-tables-count=10 --oltp-table-size=100000 --threads=10 --time=120 --report-interval=10 run >> /root/test/mysysbench.log
(3)清理数据
执行完测试后,清理数据,否则后面的测试会受到影响。
[root@vm192-168-80-2 sysbench-1.0]# sysbench ./tests/include/oltp_legacy/oltp.lua --mysql-host=192.168.89.18 --mysql-port=3306 --mysql-user=admin --mysql-password=Aa123456 cleanup
sysbench 1.0.14 (using bundled LuaJIT 2.1.0-beta2)
Dropping table 'sbtest1'...
测试结束后,查看输出文件,如下所示:
sysbench 1.0.14 (using bundled LuaJIT 2.1.0-beta2)
Running the test with following options:
Number of threads: 10
Report intermediate results every 10 second(s)
Initializing random number generator from current time
Initializing worker threads...
--线程启动
Threads started!
-- 每10秒钟报告一次测试结果,tps、每秒读、每秒写、99%以上的响应时长统计
[ 10s ] thds: 10 tps: 956.45 qps: 19139.38 (r/w/o: 13399.56/3825.92/1913.91) lat (ms,95%): 29.72 err/s: 0.00 reconn/s: 0.00
[ 20s ] thds: 10 tps: 989.71 qps: 19804.24 (r/w/o: 13862.17/3962.55/1979.52) lat (ms,95%): 28.67 err/s: 0.10 reconn/s: 0.00
[ 30s ] thds: 10 tps: 995.44 qps: 19909.03 (r/w/o: 13936.11/3982.05/1990.87) lat (ms,95%): 27.66 err/s: 0.00 reconn/s: 0.00
[ 40s ] thds: 10 tps: 983.30 qps: 19660.90 (r/w/o: 13764.23/3930.08/1966.59) lat (ms,95%): 27.66 err/s: 0.00 reconn/s: 0.00
[ 50s ] thds: 10 tps: 994.20 qps: 19882.58 (r/w/o: 13918.26/3975.92/1988.41) lat (ms,95%): 29.19 err/s: 0.00 reconn/s: 0.00
[ 60s ] thds: 10 tps: 982.50 qps: 19648.18 (r/w/o: 13752.56/3930.82/1964.81) lat (ms,95%): 28.16 err/s: 0.00 reconn/s: 0.00
[ 70s ] thds: 10 tps: 981.10 qps: 19624.20 (r/w/o: 13737.80/3924.00/1962.40) lat (ms,95%): 29.19 err/s: 0.00 reconn/s: 0.00
[ 80s ] thds: 10 tps: 991.69 qps: 19837.87 (r/w/o: 13885.81/3968.67/1983.39) lat (ms,95%): 27.17 err/s: 0.00 reconn/s: 0.00
[ 90s ] thds: 10 tps: 1007.34 qps: 20142.36 (r/w/o: 14100.50/4027.27/2014.59) lat (ms,95%): 26.68 err/s: 0.00 reconn/s: 0.00
[ 100s ] thds: 10 tps: 1009.76 qps: 20195.17 (r/w/o: 14135.79/4039.75/2019.63) lat (ms,95%): 26.20 err/s: 0.00 reconn/s: 0.00
[ 110s ] thds: 10 tps: 1003.80 qps: 20077.42 (r/w/o: 14053.54/4016.28/2007.59) lat (ms,95%): 25.74 err/s: 0.00 reconn/s: 0.00
[ 120s ] thds: 10 tps: 984.30 qps: 19685.77 (r/w/o: 13781.75/3935.41/1968.61) lat (ms,95%): 28.67 err/s: 0.00 reconn/s: 0.00
SQL statistics:
queries performed:
read: 1663326 --读总数
write: 475233 -- 写总数
other: 237617 -- 其他操作总数(SELECT、INSERT、UPDATE、DELETE之外的操作,例如COMMIT等)
total: 2376176 -- 全部总数
transactions: 118808 (989.85 per sec.) -- 总事务数(每秒事务数)
queries: 2376176 (19797.13 per sec.)
ignored errors: 1 (0.01 per sec.) --总忽略错误总数(每秒忽略错误次数)
reconnects: 0 (0.00 per sec.) --重连总数(每秒重连次数)
General statistics: --常规统计
total time: 120.0244s --总耗时
total number of events: 118808 --共发生多少事务数
Latency (ms):
min: 6.08 --最小耗时
avg: 10.10 --平均耗时
max: 87.65 --最长耗时
95th percentile: 28.16 --超过95%平均耗时
sum: 1199522.76
Threads fairness: --并发统计
events (avg/stddev): 11880.8000/273.15 --总处理事件数/标准偏差
execution time (avg/stddev): 119.9523/0.00 --总执行时间/标准偏差
其中,对于我们比较重要的信息包括:
queries:查询总数及qps
transactions:事务总数及tps
Latency-95th percentile:前95%的请求的最大响应时间,本例中是28.16毫秒。
下面是使用sysbench的一些建议。
1、在开始测试之前,应该首先明确:应采用针对整个系统的基准测试,还是针对MySQL的基准测试,还是二者都需要。
2、如果需要针对MySQL的基准测试,那么还需要明确精度方面的要求:是否需要使用生产环境的真实数据,还是使用工具生成也可以;前者实施起来更加繁琐。如果要使用真实数据,尽量使用全部数据,而不是部分数据。
3、基准测试要进行多次才有意义。
4、测试时需要注意主从同步的状态。
5、测试必须模拟多线程的情况,单线程情况不但无法模拟真实的效率,也无法模拟阻塞甚至死锁情况
参考文献:https://www.cnblogs.com/kismetv/archive/2017/09/30/7615738.html