测试什么指标?
1:吞吐量
单位时间内的事务处理数,单位tps(每秒事务数)
2:响应时间
语句平均响应时间,一般截取某段时间内,95%范围内的平均时间
3:并发性
线程同时执行
4:可扩展性
资源增加,性能也能正比增加
Sysbench 的编译
下载:http://bazaar.launchpad.net/~sysbench-developers/sysbench/0.5/files
解压:
yum install m4 autoconf automake libtool
chmod +x autogen.sh
./autogen.sh
./configure --prefix=/usr/local/sysbench --with-mysql-includes=/opt/mysql3306/include --with-mysql-libs=/opt/mysql3306/lib
make && make install
注: 出现如下错误, 则yum 安装automake,libtoolize
automake 1.10.x (aclocal) wasn't found,
exiting
libtoolize 1.4+ wasn't found, exiting
出现如下问题, 则说明需要安装mysql-devel, 即mysql 的头文件
drv_mysql.c: 在函数‘mysql_drv_done ’中:
drv_mysql.c:851: 警告:隐式声明函数‘mysql_library_end ’
--对于InnoDB存储引擎的数据库来说,我们可能更关心的是磁盘和OLTP的性能,因此主要是fileio和oltp这两个项目的测试,
fileio性能测试
sysbench --test=fileio help
--file-num 生成测试文件的数量,默认是128
--file-block-size 测试期间文件块的大小,如果你想磁盘针对InnoDB存储引擎进行测试, 可以将其设置为16384,即InnoDB存储引擎的大小,默认是16384
--file-total-size 每个文件的大小,默认是2GB
--file-test-mode 文件测试模式,包含seqwr(顺序写)、seqrewr(顺序读写)、seqrd(顺序读)、rndrd(随即读)、rndwr(随机写)、rndrw(随机读写)
--file-io-mode 文件操作模式,同步还是异步,默认是同步
--file-fsync-all 每执行完一次写操作,就执行一次fsync,默认是off
sysbench的fileio测试需要经过prepare、run、clean三个阶段,prepare是准备阶段,生成我们需要的测试文件,run是实际测试阶段,cleanup是清理测试产生的文件,
例1:
--prepare
sysbench --test=fileio --file-num=16 --file-total-size=2G prepare 生成16个测试文件,总大小为2G
sysbench --test=fileio --file-total-size=2G --file-test-mode=rndrd --max-time=300 --max-requests=1000000000 --num-threads=16 --init-rng=on --file-num=16 --file-extra-flags=direct --file-fsync-freq=0 --file-block-size=16384 run
例2:
sysbench --test=fileio
--file-total-size=20G prepare
sysbench --test=fileio
--file-total-size=20G --file-test-mode=rndrw run
sysbench --test=fileio
--file-total-size=20G cleanup
seqwr:顺序写入
seqrewq:顺序重写
seqrd:顺序读取
rndrd:随机读取
rndwr:随机写入
rndrw:混合随机读写
Sysbench 测试事务性能
#sysbench
--test=/path/to/sysbench-source/tests/db/oltp.lua
--mysql-table-engine=innodb \
--mysql-user=root --db-driver=mysql
--mysql-db=test \
--oltp-table-size=3000
--mysql-socket=/var/lib/mysql/mysql.sock
prepare
sysbench --test=/path/to/sysbench-source/tests/db/oltp.lua
--mysql-table-engine=innodb --mysql-user=root --db-driver=mysql --mysql-db=test
--oltp-table-size=3000 --mysql-socket=/var/lib/mysql/mysql.sock run
测试顺序读
sysbench --test=fileio
--file-total-size=10G --file-test-mode=seqrd run
Read 156.25Mb Written 0b
Total transferred 156.25Mb (201.09Mb/sec)
测试随机读
./bin/sysbench --test=fileio
--file-total-size=10G --file-test-mode=rndrd run
Read 156.25Mb Written 0b
Total transferred 156.25Mb (5.5698Mb/sec )
mysqlslap测试
mysqlslap --options
--concurrency代表并发数量,多个可以用逗号隔开,concurrency=10,50,100,
并发连接线程数分别是10、50、100个并发。
--engines代表要测试的引擎,可以有多个,用分隔符隔开。
--iterations代表要运行这些测试多少次。
--auto-generate-sql
代表用系统自己生成的SQL脚本来测试。
--auto-generate-sql-load-type
代表要测试的是读还是写还是两者混合的(read,write,update,mixed)
--number-of-queries
代表总共要运行多少次查询。每个客户运行的查询数量可以用查询总数/并发数来计算。
--debug-info
代表要额外输出CPU以及内存的相关信息。
mysqlslap
-h 192.168.1.201 -uroot
--auto-generate-sql --concurrency 20 --iterations 1
--create-schema=big_data --query='select * from dict limit 1'
mysqlslap --defaults-file=/usr/local/mysql/my.cnf --concurrency=4000 --iterations=1 --number-int-cols=4 --number-char-cols=35 --auto-generate-sql --auto-generate-sql-add-autoincrement --auto-generate-sql-load-type=mixed --engine=myisam,innodb --number-of-queries=200 --debug-info -uroot -p123456 -S/tmp/mysql.sock
mysqlslap: Error when connecting to server: 2001 Can't create UNIX socket (24)
Benchmark
Running for engine innodb
Average number of seconds to run all queries:
0.133 seconds
Minimum number of seconds to run all queries: 0.133 seconds
Maximum number of seconds to run all queries: 0.133 seconds
Number of clients running queries:
200
Average number of queries per client: 1
对于INNODB引擎,200个客户端同时运行这些SQL语句平均要花0.133 秒。
tpcc工具安装
http://bazaar.launchpad.net/~percona-dev/perconatools/tpcc-mysql/files
#cd src
#make
创建数据库/表
# mysql -h 192.168.1.201 -uroot -p
-e 'create database tpcc1000'
# mysql -h 192.168.1.201 -uroot -p
tpcc1000 < create_table.sql
# mysql -h 192.168.1.201 -uroot -p
tpcc1000 < add_fkey_idx.sql
tpcc_load装载数据
命令格式:
tpcc_load [server] [DB] [user]
[pass] [warehouse]
./tpcc_load 192.168.2.201 tpcc5
root "" 5
tpcc5库下创建5个仓库(仓库越多数据量越大)
注:普通机器约需要10分钟的时间
tpcc模拟订单事务
格式:
tpcc_start -h server_host -P port
-d database_name
-u mysql_user -p mysql_password
-w warehouses -c connections -r warmup_time -l
running_time
-w 仓库 -c 连接数 -r预热时间 -l 测试时间
# ./tpcc_start -h 192.168.1.201 -d
tpcc1000 -u root -p '' -w 5 -c 5 -r 30 -l 30
5线程测试5个仓库,30秒预热,30秒测试
观察mysql
status的周期变化
测试场景:
总数据3W以上,50个并发,每秒请求500-1000次
请求结果缓存与memcache,生命周期为5分钟,
观察mysql连接数,每秒请求数的周期变化
mysql status观察脚本
#!/bin/bash
while true
do
mysqladmin -h192.168.1.201 -uroot
ext |awk ' /Queries/ {q=$4}
/Threads_connected/{tc=$4}
/Threads_running/{tr=$4}
END{printf "%3d %s
%s\n",q,tc,tr}
' >> num.txt
sleep 1
done
awk 计算每秒查询数
awk
'{q=$1-last;last=$1}{printf("%d\t%d\t%d\n",q,$2,$3)}' num.txt >
num2.txt
观察mysql进程状态
mysql -h 192.168.1.201 -u root -e
'show processlist\G'|grep State:|sort|uniq
-c|sort -rn
5
State: Sending data
2
State: statistics
2
State: NULL
1
State: Updating
1
State: update
converting HEAP to MyISAM
查询结果太大时,把结果放在磁盘
create tmp table 创建临时表(如group时储存中间结果)
Copying to tmp table on disk 把内存临时表复制到磁盘
locked 被其他查询锁住
logging slow query 记录慢查询
注:把临时表内存变小,重现前
值得注意的mysql进程状态
converting HEAP to MyISAM
查询结果太大时,把结果放在磁盘
create tmp table 创建临时表(如group时储存中间结果)
Copying to tmp table on disk 把内存临时表复制到磁盘
locked 被其他查询锁住
logging slow query 记录慢查询
注:把临时表内存变小,重现前
什么情况下产生临时表?
1: group by 的列和order by 的列不同时,
2表边查时,取A表的内容,group/order by另外表的列
2: distinct 和 order by 一起使用时
3: 开启了 SQL_SMALL_RESULT 选项
什么情况下临时表写到磁盘上?
答:
1:取出的列含有text/blob类型时
---内存表储存不了text/blob类型
2:在group by
或distinct的列中存在>512字节的string列
3:select
中含有>512字节的string列,同时又使用了union或union all语句
如果服务器频繁出现converting HEAP to MyISAM
说明:
1: sql有问题,取出的结果或中间结果过大,内存临时表放不下
2: 服务器配置的临时表内存参数过小.
tmp_table_size
max_heap_table_size
vi mystatus. sh
#! / bin/ bash
while true
do
mysqladmin - S / tmp/ mysql. sock - uroot - p123456 ext | awk ' /Queries/ {q=$4}
/Threads_connected/{tc=$4}
/Threads_running/{tr=$4}
END{printf "%3d %s %s\n",q,tc,tr}
' > > num. txt
sleep 1
done
vi mystatus2. sh
#! / bin / bash
while true
do
mysql -S / tmp/ mysql. sock -u root -p123456 -e 'show processlist\G' | grep State:| sort| uniq -c| sort -rn
sleep 1
done
通常,我们会出于以下几个目的对MySQL进行压力测试:
1、确认新的MySQL版本性能相比之前差异多大,比如从5.6变成5.7,或者从官方版本改成Percona分支版本;
2、确认新的服务器性能是否更高,能高多少,比如CPU升级了、阵列卡cache加大了、从机械盘换成SSD盘了;
3、确认一些新的参数调整后,对性能影响多少,比如 innodb_flush_log_at_trx_commit、sync_binlog 等参数;
4、确认即将上线的新业务对MySQL负载影响多少,是否能承载得住,是否需要对服务器进行扩容或升级配置;
针对上面这几种压测的目的,相应的测试方法也有所不同。
先说第四种,需要和线上业务结合起来,这时候就需要自行开发测试工具,或者利用 tcpcopy 将线上实际用户请求导向测试环境,进行仿真模拟测试。
对于前三种,我们通常采用基准测试就可以。比较常用的MySQL基准压力测试工具有 tpcc-mysql 、sysbench 、mysqlslap 等几个。
关于压力测试工具的使用,可以查看我之前在ORACLE技术嘉年华上的分享:MySQL压力测试经验 ,在这里不再细说。
基于促进同行间的交流,统一MySQL压测标准,并且可以相互分享、对比、借鉴测试结果的目的。因此老叶特别发起MySQL压力测试基准值倡议。建议大家采用以下几种压力测试基准值。
倡议:MySQL压力测试建议基准值(2015试行版)
也可以查看本文附件excel文档:压力测试基准建议及数据采集模板 ,里面已附带了压力测试相关的数据采集点建议,压测结果整理及自动生成对比图表。欢迎各位同行拍砖提出不同的见解和补充意见,先谢过大家。
关于压力测试的其他几个方面:
1、如何避免压测时受到缓存的影响
【老叶建议】有2点建议
a、填充测试数据比物理内存还要大,至少超过innodb_buffer_pool_size 值,不能将数据全部装载到内存中,除非你的本意就想测试全内存状态下的MySQL性能。
b、每轮测试完成后,都重启mysqld实例,并且用下面的方法删除系统cache,释放swap(如果用到了swap的话),甚至可以重启整个OS。
[root@imysql.com]# sync -- 将脏数据刷新到磁盘
[root@imysql.com]# echo 3 > /proc/sys/vm/drop_caches -- 清除OS Cache
[root@imysql.com]# swapoff -a && swapon -a
2、如何尽可能体现线上业务真实特点
【老叶建议】有2点建议
a、其实上面已经说过了,就是自行开发测试工具或者利用 tcpcopy (或类似交换机的mirror功能) 将线上实际用户请求导向测试环境,进行仿真模拟测试。
b、利用 http_load 或 siege 工具模拟真实的用户请求URL进行压力测试,这方面我不是太专业,可以请教企业内部的压力测试同事。
3、压测结果如何解读
【老叶建议】压测结果除了tps/TpmC指标外,还应该关注压测期间的系统负载数据,尤其是 iops、iowait、svctm、%util、每秒I/O字节数(I/O吞吐)、事务响应时间 (tpcc-mysql/sysbench 打印的测试记录中均有)。另外,如果I/O设备能提供设备级 IOPS、读写延时 数据的话,也应该一并关注。
假如两次测试的tps/TpmC结果一样的话,那么谁的 事务响应时间、iowait、svctm、%util、读写延时 更低,就表示那个测试模式有更高的性能提升空间。
4、如何加快tpcc_load加载数据的效率
【老叶建议】tpcc_load其实是可以并行加载的,一方面是可以区分 ITEMS、WAREHOUSE、CUSTOMER、ORDERS 四个维度的数据并行加载。
另外,比如最终想加载1000个 warehouse的话,也可以分开成1000个并发并行加载的。看下 tpcc_load 工具的参数就知道了:
usage: tpcc_load [server] [DB] [user] [pass] [warehouse]
OR
tpcc_load [server] [DB] [user] [pass] [warehouse] [part] [min_wh] [max_wh]
* [part]: 1=ITEMS 2=WAREHOUSE 3=CUSTOMER 4=ORDERS
本来想自己写个并行加载脚本的,后来发现万能的github上已经有人做好了,我就直接拿来用了,这是项目链接 tpcc_load_parallel.sh ,加载效率至少提升10倍以上。