MySQL压力测试工具-sysbench使用与报告解读
什么是基准测试?
- 数据库的基准测试是对数据库的性能指标进行定量的、可复现的、可对比的测试。
- 基准测试与压力测试
- 基准测试可以理解为针对系统的一种压力测试。但基准测试不关心业务逻辑,更加简单、直接、易于测试,数据可以由工具生成,不要求真实;而压力测试一般考虑业务逻辑(如购物车业务),要求真实的数据。
基准测试的作用?
- 对于多数Web应用,整个系统的瓶颈在于数据库;原因很简单:Web应用中的其他因素,例如网络带宽、负载均衡节点、应用服务器(包括CPU、内存、硬盘灯、连接数等)、缓存,都很容易通过水平的扩展(俗称加机器)来实现性能的提高。而对于MySQL,由于数据一致性的要求,无法通过增加机器来分散向数据库写数据带来的压力;虽然可以通过前置缓存(Redis等)、读写分离、分库分表来减轻压力,但是与系统其它组件的水平扩展相比,受到了太多的限制。
- 而对数据库的基准测试的作用,就是分析在当前的配置下(包括硬件配置、OS、数据库设置等),数据库的性能表现,从而找出MySQL的性能阈值,并根据实际系统的要求调整配置。
基准测试的指标:
常见的数据库指标包括:
- TPS/QPS:衡量吞吐量。(TPS:每秒事务处理量(TransactionPerSecond)、每秒查询率QPS是对一个特定的查询服务器在规定时间内所处理流量多少的衡量标准)
- 响应时间:包括平均响应时间、最小响应时间、最大响应时间、时间百分比等,其中时间百分比参考意义较大,如前95%的请求的最大响应时间。。
- 并发量:同时处理的查询请求的数量。
基准测试的分类:
对MySQL的基准测试,有如下两种思路:
- 针对整个系统的基准测试:通过http请求进行测试,如通过浏览器、APP或postman等测试工具。该方案的优点是能够更好的针对整个系统,测试结果更加准确;缺点是设计复杂实现困难。
- 只针对MySQL的基准测试:优点和缺点与针对整个系统的测试恰好相反。
在针对MySQL进行基准测试时,一般使用专门的工具进行,例如mysqlslap、sysbench等。其中,sysbench比mysqlslap更通用、更强大,且更适合Innodb(因为模拟了许多Innodb的IO特性),下面介绍使用sysbench进行基准测试的方法。
sysbench简介
- sysbench是跨平台的基准测试工具,支持多线程,支持多种数据库;主要包括以下几种测试:
- cpu性能
- 磁盘io性能
- 调度程序性能
- 内存分配及传输速度
- POSIX线程性能
- 数据库性能(OLTP基准测试)
sysbench安装:
YUM安装:
[root@db ~]# yum -y install sysbench
编译安装:
[root@db ~]# yum -y install make automake libtool pkgconfig libaio-devel vim-common unzip mysql-devel
[root@db ~]# wget https://github.com/akopytov/sysbench/archive/master.zip
[root@db ~]# unzip master.zip
[root@db ~]# cd sysbench-master/
[root@db ~]# ./autogen.sh
[root@db ~]# ./configure --prefix=/usr/local/sysbench
[root@db ~]# make -j
[root@db ~]# make install
[root@db ~]# /usr/local/sysbench/bin/sysbench --version
sysbench 1.1.0
sysbench参数:
MySQL连接参数:
$ --mysql-host:MySQL服务器主机名,默认localhost;如果在本机上使用localhost报错,提示无法连接MySQL服务器,改成本机的IP地址应该就可以了。
$ --mysql-port:MySQL服务器端口,默认3306
$ --mysql-user:用户名
$ --mysql-password:密码
$ --mysql-db: 操作哪个库
MySQL执行参数:
$ --oltp-test-mode:执行模式,包括simple、nontrx和complex,默认是complex。simple模式下只测试简单的查询;nontrx不仅测试查询,还测试插入更新等,但是不使用事务;complex模式下测试最全面,会测试增删改查,而且会使用事务。可以根据自己的需要选择测试模式。
$ --oltp-tables-count:测试的表数量( 一个库下模拟多少张表 )
$ --oltp-table-size:测试的表的大小( 每张表中模拟多少行数据 )
$ --threads:客户端的并发连接数
$ --time:测试执行的时间,单位是秒,该值不要太短,可以选择120
$ --report-interval:生成报告的时间间隔,单位是秒,如10
sysbench使用示例:
模拟数据:
mysql> create database testdb;
Query OK, 1 row affected (0.05 sec)
[root@db ~]# sysbench /usr/share/sysbench/tests/include/oltp_legacy/oltp.lua \
--mysql-host=10.186.61.211 --mysql-port=3306 --mysql-user=root --mysql-password=123456 \
--mysql-db=testdb --oltp-table-size=200000 --oltp-tables-count=4 --threads=4 --events=0 \
--time=3600 --report-interval=3 prepare
sysbench 1.0.17 (using system LuaJIT 2.0.4)
Creating table 'sbtest1'...
Inserting 200000 records into 'sbtest1'
Creating secondary indexes on 'sbtest1'...
Creating table 'sbtest2'...
Inserting 200000 records into 'sbtest2'
Creating secondary indexes on 'sbtest2'...
Creating table 'sbtest3'...
Inserting 200000 records into 'sbtest3'
Creating secondary indexes on 'sbtest3'...
Creating table 'sbtest4'...
Inserting 200000 records into 'sbtest4'
Creating secondary indexes on 'sbtest4'...
压力测试报告:
[root@db ~]# sysbench /usr/share/sysbench/tests/include/oltp_legacy/oltp.lua \
--mysql-host=10.186.61.211 --mysql-port=3306 --mysql-user=root --mysql-password=123456 \
--mysql-db=testdb --oltp-table-size=200000 --oltp-tables-count=4 --threads=4 --events=0 \
--time=30 --report-interval=3 run
sysbench 1.0.17 (using system LuaJIT 2.0.4)
Running the test with following options:
Number of threads: 4
Report intermediate results every 3 second(s)
Initializing random number generator from current time
Initializing worker threads...
Threads started!
[ 3s ] thds: 4 tps: 63.60 qps: 1290.97 (r/w/o: 907.04/255.40/128.53) lat (ms,95%): 219.36 err/s: 0.00 reconn/s: 0.00
[ 6s ] thds: 4 tps: 92.37 qps: 1848.79 (r/w/o: 1291.55/372.49/184.75) lat (ms,95%): 116.80 err/s: 0.00 reconn/s: 0.00
[ 9s ] thds: 4 tps: 111.33 qps: 2224.96 (r/w/o: 1558.30/443.99/222.66) lat (ms,95%): 134.90 err/s: 0.00 reconn/s: 0.00
[ 12s ] thds: 4 tps: 72.66 qps: 1459.84 (r/w/o: 1021.22/293.30/145.32) lat (ms,95%): 219.36 err/s: 0.00 reconn/s: 0.00
[ 15s ] thds: 4 tps: 67.34 qps: 1346.82 (r/w/o: 942.78/269.36/134.68) lat (ms,95%): 253.35 err/s: 0.00 reconn/s: 0.00
[ 18s ] thds: 4 tps: 68.66 qps: 1373.28 (r/w/o: 961.30/274.66/137.33) lat (ms,95%): 244.38 err/s: 0.00 reconn/s: 0.00
[ 21s ] thds: 4 tps: 67.67 qps: 1353.41 (r/w/o: 947.39/270.68/135.34) lat (ms,95%): 231.53 err/s: 0.00 reconn/s: 0.00
[ 24s ] thds: 4 tps: 140.99 qps: 2810.15 (r/w/o: 1966.87/561.30/281.98) lat (ms,95%): 110.66 err/s: 0.00 reconn/s: 0.00
[ 27s ] thds: 4 tps: 111.67 qps: 2243.15 (r/w/o: 1570.44/449.36/223.35) lat (ms,95%): 176.73 err/s: 0.00 reconn/s: 0.00
[ 30s ] thds: 4 tps: 90.66 qps: 1808.22 (r/w/o: 1265.59/361.31/181.32) lat (ms,95%): 215.44 err/s: 0.00 reconn/s: 0.00
SQL statistics:
queries performed:
read: 37310 # 读总数
write: 10660 # 写总数
other: 5330 # 其他操作总数(SELECT、INSERT、UPDATE、DELETE之外的操作,例如COMMIT等)
total: 53300 # 全部总数
transactions: 2665 (88.42 per sec.) # 总事务数(每秒事务数)
queries: 53300 (1768.41 per sec.) # 总查询量(每秒查询数)
ignored errors: 0 (0.00 per sec.) # 总忽略错误总数(每秒忽略错误次数)
reconnects: 0 (0.00 per sec.) # 重连总数(每秒重连次数)
General statistics:
total time: 30.1386s # 总耗时
total number of events: 2665 # 共发生多少事务数
Latency (ms):
min: 5.50 # 最小耗时
avg: 45.19 # 平均耗时
max: 386.91 # 最长耗时
95th percentile: 207.82 # 超过95%平均耗时
sum: 120433.75
Threads fairness:
events (avg/stddev): 666.2500/16.07 # 总处理事件数/标准偏差
execution time (avg/stddev): 30.1084/0.04 # 总执行时间/标准偏差
清理数据:
[root@db ~]# sysbench /usr/share/sysbench/tests/include/oltp_legacy/oltp.lua \
--mysql-host=10.186.61.211 --mysql-port=3306 --mysql-user=root --mysql-password=123456 \
--mysql-db=testdb --oltp-table-size=200000 --oltp-tables-count=4 --threads=4 --events=0 \
--time=30 --report-interval=3 cleanup
sysbench 1.0.17 (using system LuaJIT 2.0.4)
Dropping table 'sbtest1'...
Dropping table 'sbtest2'...
Dropping table 'sbtest3'...
Dropping table 'sbtest4'...