mysql性能测试。
一、mysqlslap
mysqlslap是mysql自带的性能测试工具。
mysqlslap -a -c 100 -uroot -p123456 --auto-generate-sql-load-type=read --number-char-cols=10 --number-int-cols=10 --number-of-queries=10000 -e innodb
解析:
-a 自动生成测试表和数据。
-c 并发数。这里是100个并发。
--auto-generate-sql-load-type=read :测试类型,测试read
number-char-cols: 测试表有多少个char列。这里是10个。
number-int-cols: 测试表有多少个int列。这里是10个。
number-of-queries:总测试次数有多少。这里是1万。
e:指定存储引擎。这里是innodb。
测试结果:
Benchmark
Running for engine innodb
Average number of seconds to run all queries: 5.703 seconds
Minimum number of seconds to run all queries: 5.703 seconds
Maximum number of seconds to run all queries: 5.703 seconds
Number of clients running queries: 100
Average number of queries per client: 100
运行所有查询的平均秒数:5.7秒。100个线程,每个线程执行了100个查询,也就是说,每个线程5.7秒执行完了100个查询,大概一个查询,0.05秒,50ms。
修改成10万个查询。每个线程执行1000个查询,花了56秒,也就是一个查询,0.056秒,56毫秒。
mysqlslap -a -c 100 -uroot -p123456 --auto-generate-sql-load-type=read --number-char-cols=10 --number-int-cols=10 --number-of-queries=100000 -e innodb
mysqlslap: [Warning] Using a password on the command line interface can be insecure.
Benchmark
Running for engine innodb
Average number of seconds to run all queries: 56.204 seconds
Minimum number of seconds to run all queries: 56.204 seconds
Maximum number of seconds to run all queries: 56.204 seconds
Number of clients running queries: 100
Average number of queries per client: 1000
缺点:mysqlslap无法指定测试数据多少行,也无法自定数据,自定义查询,无法看出qps,tps,反正功能比较少。
二、sysbench。
地址:https://github.com/akopytov/sysbench/
换一个工具。
安装之后,查询一下测试lua脚本在哪。
[root@localhost ~]# find / -name "oltp.lua"
/usr/share/sysbench/tests/include/oltp_legacy/oltp.lua
创建测试数据库: sbtest
sysbench ./tests/include/oltp_legacy/oltp.lua --mysql-host=192.168.220.1 --mysql-port=3306 --mysql-user=root --mysql-password=123456 --oltp-test-mode=complex --oltp-tables-count=10 --oltp-table-size=100000 --threads=100 --time=120 --report-interval=10 prepare
解释:oltp-test-mode:指定测试类型
simple:简单查询,SELECT c FROM sbtest WHERE id=N
complex (advanced transactional):事务模式在开始和结束事务之前加上begin和commit, 一个事务里可以有多个语句,如点查询、范围查询、排序查询、更新、删除、插入等,并且为了不破坏测试表的数据,该模式下一条记录删除后会在同一个事务里添加一条相同的记录。
nontrx (non-transactional):与simple相似,但是可以进行update/insert等操作,所以如果做连续的对比压测,你可能需要重新cleanup,prepare。
oltp-tables-count:测试表的数量。这里是10张表。
oltp-table-size:表的数据量,这里是10万。
threads:线程数。
time: 要测试多长时间。
report-interval:生成报告间隔。这里是10秒打印一次测试报告。
prepare:准备数据。还可以是run测试。cleanup删除测试数据。
lua脚本命令都可以在lua脚本中看到,后面会看到。
测试结果:并发数100,表数据量10万。
qps:3千多。tps:165。错误数:0.14个每秒。
平均每个请求延迟588ms。
[root@localhost sysbench]# sysbench ./tests/include/oltp_legacy/oltp.lua --mysql-host=192.168.220.1 --mysql-port=3306 --mysql-user=root --mysql-password=123456 --oltp-test-mode=complex --oltp-tables-count=10 --oltp-table-size=100000 --threads=100 --time=20 --report-interval=10 run
sysbench 1.0.17 (using bundled LuaJIT 2.1.0-beta2)
Running the test with following options:
Number of threads: 100
Report intermediate results every 10 second(s)
Initializing random number generator from current time
Initializing worker threads...
Threads started!
# tps 事务数166,qps:每秒查询数。r/w/o读写。
[ 10s ] thds: 100 tps: 166.77 qps: 3521.93 (r/w/o: 2473.20/705.19/343.54) lat (ms,95%): 1678.14 err/s: 0.00 reconn/s: 0.00
[ 20s ] thds: 100 tps: 171.30 qps: 3411.51 (r/w/o: 2390.71/677.90/342.90) lat (ms,95%): 1149.76 err/s: 0.30 reconn/s: 0.00
SQL statistics:
queries performed:
read: 48776 #总共执行了48776次读
write: 13927 #总共执行了多少次写。
other: 6965 #总共执行了多少次其他。
total: 69668 # 总数
transactions: 3481 (165.12 per sec.) #总共的事务数,每秒的事务数
queries: 69668 (3304.68 per sec.)#总共的查询数,每秒的查询数
ignored errors: 3 (0.14 per sec.)#每秒的错误数
reconnects: 0 (0.00 per sec.)#重连数
General statistics:
total time: 21.0802s
total number of events: 3481
Latency (ms):
min: 45.49
avg: 588.77 #平均延迟588ms。
max: 4052.56
95th percentile: 1453.01
sum: 2049514.27
Threads fairness:
events (avg/stddev): 34.8100/3.72
execution time (avg/stddev): 20.4951/0.19
可以看到,对于事务操作,10万条记录的qps,有3500。延迟大概580ms。
改成--oltp-test-mode=simple或者nontrx ,qps差不多。
把数据量调小,改成1000,发现,qps,达到了1万多。延迟也变成了200多ms,但是,产生了很多错误请求,每秒高达80多个错误请求。
测试结果:并发数100,表数据量1000。
qps:1万多。tps:400多。错误数:80个每秒。
平均每个请求延迟239ms。*
[root@localhost sysbench]# sysbench ./tests/include/oltp_legacy/oltp.lua --mysql-host=192.168.220.1 --mysql-port=3306 --mysql-user=root --mysql-password=123456 --oltp-test-mode=nontrx --oltp-tables-count=10 --oltp-table-size=1000 --threads=100 --time=20 --report-interval=10 run
sysbench 1.0.17 (using bundled LuaJIT 2.1.0-beta2)
Running the test with following options:
Number of threads: 100
Report intermediate results every 10 second(s)
Initializing random number generator from current time
Initializing worker threads...
Threads started!
[ 10s ] thds: 100 tps: 511.47 qps: 11749.58 (r/w/o: 8479.05/2150.68/1119.86) lat (ms,95%): 467.30 err/s: 87.74 reconn/s: 0.00
[ 20s ] thds: 100 tps: 317.98 qps: 7537.50 (r/w/o: 5488.20/1340.63/708.67) lat (ms,95%): 682.06 err/s: 71.91 reconn/s: 0.00
SQL statistics:
queries performed:
read: 140294
write: 35369
other: 18420
total: 194083
transactions: 8399 (414.79 per sec.)
queries: 194083 (9584.91 per sec.)
ignored errors: 1622 (80.10 per sec.)
reconnects: 0 (0.00 per sec.)
General statistics:
total time: 20.2475s
total number of events: 8399
Latency (ms):
min: 40.91
avg: 239.95
max: 1929.24
95th percentile: 580.02
sum: 2015359.53
Threads fairness:
events (avg/stddev): 83.9900/4.82
execution time (avg/stddev): 20.1536/0.04
如果再把并发调小,调到10个,则延迟会小很多。但是qps变低了。并发小了,压不出极限性能,所以qps变低了。错误数也几乎没有了,没秒1个。
测试结果:并发数10,表数据量1000。
qps:2400。tps:120多。错误数:1.79个每秒。
平均每个请求延迟82ms。*
[root@localhost sysbench]# sysbench ./tests/include/oltp_legacy/oltp.lua --mysql-host=192.168.220.1 --mysql-port=3306 --mysql-user=root --mysql-password=123456 --oltp-test-mode=nontrx --oltp-tables-count=10 --oltp-table-size=1000 --threads=10 --time=60 --report-interval=10 run
sysbench 1.0.17 (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!
[ 10s ] thds: 10 tps: 127.57 qps: 2579.15 (r/w/o: 1808.35/513.87/256.94) lat (ms,95%): 134.90 err/s: 1.20 reconn/s: 0.00
[ 20s ] thds: 10 tps: 124.60 qps: 2531.68 (r/w/o: 1779.28/500.90/251.50) lat (ms,95%): 150.29 err/s: 1.90 reconn/s: 0.00
[ 30s ] thds: 10 tps: 127.90 qps: 2583.54 (r/w/o: 1812.06/513.49/257.99) lat (ms,95%): 139.85 err/s: 2.20 reconn/s: 0.00
[ 40s ] thds: 10 tps: 108.91 qps: 2216.08 (r/w/o: 1556.60/440.06/219.43) lat (ms,95%): 150.29 err/s: 1.60 reconn/s: 0.00
[ 50s ] thds: 10 tps: 120.89 qps: 2451.17 (r/w/o: 1721.84/485.45/243.88) lat (ms,95%): 142.39 err/s: 2.30 reconn/s: 0.00
[ 60s ] thds: 10 tps: 115.60 qps: 2339.68 (r/w/o: 1642.26/464.52/232.91) lat (ms,95%): 142.39 err/s: 1.50 reconn/s: 0.00
SQL statistics:
queries performed:
read: 103208
write: 29184
other: 14637
total: 147029
transactions: 7265 (120.92 per sec.)
queries: 147029 (2447.10 per sec.)
ignored errors: 107 (1.78 per sec.)
reconnects: 0 (0.00 per sec.)
General statistics:
total time: 60.0817s
total number of events: 7265
Latency (ms):
min: 41.22
avg: 82.68
max: 583.64
95th percentile: 142.39
sum: 600686.62
Threads fairness:
events (avg/stddev): 726.5000/2.66
execution time (avg/stddev): 60.0687/0.01
如果把并发调到200,则错误数会很高,每秒514个。qps也会很高,1万多。
测试结果:并发数200,表数据量1000。
qps:1万多。tps:417多。错误数:189个每秒。
平均每个请求延迟477ms。*
[root@localhost sysbench]# sysbench ./tests/include/oltp_legacy/oltp.lua --mysql-host=192.168.220.1 --mysql-port=3306 --mysql-user=root --mysql-password=123456 --oltp-test-mode=nontrx --oltp-tables-count=10 --oltp-table-size=1000 --threads=200 --time=60 --report-interval=10 run
sysbench 1.0.17 (using bundled LuaJIT 2.1.0-beta2)
Running the test with following options:
Number of threads: 200
Report intermediate results every 10 second(s)
Initializing random number generator from current time
Initializing worker threads...
Threads started!
[ 10s ] thds: 200 tps: 406.93 qps: 11775.91 (r/w/o: 8863.28/1870.00/1042.63) lat (ms,95%): 1109.09 err/s: 208.77 reconn/s: 0.00
[ 20s ] thds: 200 tps: 437.39 qps: 11706.16 (r/w/o: 8757.82/1886.11/1062.22) lat (ms,95%): 1089.30 err/s: 187.45 reconn/s: 0.00
[ 30s ] thds: 200 tps: 451.55 qps: 12028.42 (r/w/o: 8935.25/2002.64/1090.53) lat (ms,95%): 1069.86 err/s: 187.42 reconn/s: 0.00
[ 40s ] thds: 200 tps: 432.88 qps: 11980.04 (r/w/o: 8955.50/1949.89/1074.64) lat (ms,95%): 1129.24 err/s: 208.89 reconn/s: 0.00
[ 50s ] thds: 200 tps: 398.80 qps: 10743.70 (r/w/o: 8018.98/1753.32/971.41) lat (ms,95%): 1427.08 err/s: 173.80 reconn/s: 0.00
[ 60s ] thds: 200 tps: 374.29 qps: 10119.01 (r/w/o: 7560.54/1643.13/915.34) lat (ms,95%): 1352.03 err/s: 166.75 reconn/s: 0.00
SQL statistics:
queries performed:
read: 512988
write: 111853
other: 61863
total: 686704
transactions: 25221 (417.61 per sec.)
queries: 686704 (11370.38 per sec.)
ignored errors: 11421 (189.11 per sec.)
reconnects: 0 (0.00 per sec.)
General statistics:
total time: 60.3928s
total number of events: 25221
Latency (ms):
min: 52.53
avg: 477.59
max: 3634.85
95th percentile: 1213.57
sum: 12045304.61
Threads fairness:
events (avg/stddev): 126.1050/7.83
execution time (avg/stddev): 60.2265/0.09
说明:
1、要压出mysql的极致性能,应该先排出网络因素,直接先在本地测试。以上都是本地测试的。后面会看到,网络带宽对qps有很大的影响。
2、qps和执行语句有关。比如select qps会很高,update delete qps会低很多。而上面使用的测试lua脚本是sysbench自带的,里面执行了很多种sql语句,详情看下一篇文章。如果我们要测真正的业务的qps,应该使用业务语句,来进行测试,这样更加贴近业务实际。
3、有些压测工具,可能压不出mysql的极限性能,这也是需要考虑的。
总结一下
1、并发越高,错误请求会越大。
2、极限qps:大概在2千到1万之间,并发越大,qps越大。
3、并发越大,延迟越大,数据量越大,延迟越大。
4、延迟在80ms到600ms之间,随着并发和数据量变化。
5、mysql连接数,通常不需要那么多,通过后面压测可以看到。因为应用服务器,很多情况几乎使用不到那么多连接。
原因:
1)正常情况下,mysql的吞吐量不会大到需要200个连接以上的并发执行,除非mysql机器很牛,吞吐量很高。
2)应用服务器,正常情况下,也不会把mysql的极限性能使用到,一般应用服务器的qps是没有mysql高的,除非,很多台应用服务器一起连接mysql。
所以,控制在mysql连接数在200,极限qps应该是1万多,延迟大概400ms(延迟感觉不太准确,还是mysqlslap 测得50ms准确一点)。