使用go对mysql压力测试

  • 时间:
  • 浏览:920
  • 来源:成都艾邦软件开发

1.背景

​出自percona公司是一款多线程系统压测工具可以根据影响数据库服务器性能的各种因素来评估系统的性能。例如可以用来测试文件IO操作系统调度器内存分配和传输速度POSIX线程以及数据库服务器等。sysbench支持Lua脚本语言Lua对各种测试场景的设置可以非常灵活。sysbench支持MySQL操作系统和硬件的测试。

2.安装与使用

安装

curl -s https://packagecloud.io/install/repositories/akopytov/sysbench/script.rpm.sh | sudo bash
sudo yum -y install sysbench

使用

​ 数据准备

#!/bin/sh
export LD_LIBRARY_PATH/usr/local/mysql/lib/

. ~/.bash_profile

# 需要启用DEBUG模式时将下面三行注释去掉即可
#set -u
#set -x
#set -e

BASEDIR/data/sysbench#创建sysbench文件目录
if [ ! -d $BASEDIR ]
then
  mkdir $BASEDIR -p
fi
cd $BASEDIR#进入sysbench文件目录

# 记录所有错误及标准输出到 sysbench.log 中
#exec 31 42 1 sysbench_prepare.log 21

DBIP192.168.1.109
DBPORT3109
DBUSERproxysql
DBPASSWD123456
NOWdate %Y%m%d%H%M
DBNAMEsysbench
TBLCNT10#表数量
WARMUP300#预热时间秒
DURING1800#持续时间秒
ROWS10000000#每个表中插入1KW行数据
MAXREQ1000000#最大请求数为100W

#当达到持续时间或者最大请求数时这一轮的测试就会停止

#创建sysbench专用的数据库
echo now create db
mysql -h$DBIP -P$DBPORT -u$DBUSER -p$DBPASSWD -e create database sysbench
echo create ok
## 数据准备
echo now prepare data
 sysbench /usr/share/sysbench/oltp_read_only.lua #必须附加lua脚本才可以初始化数据
 --mysql-host$DBIP
 --mysql-port$DBPORT
 --mysql-user$DBUSER
 --mysql-password$DBPASSWD
 --mysql-db$DBNAME
 --db-drivermysql
 --tables10
 --table-size$ROWS
 --time$DURING prepare

压测开始

#!/bin/bash
##
##
## 叶金荣, 知数堂培训联合创始人, 资深MySQL专家, MySQL布道师, Oracle MySQL ACE
##
## 几个注意事项
## 1、运行sysbench的客户机和MySQL DB服务器尽量不要在同一台主机上也包括一台宿主机上启动两个虚机的情形
## 2、测试表的数量不宜太少至少要求20个表以上
## 3、每个表的数据量不宜太少通常至少要求1千万以上当然了也要根据DB服务器的配置适当调整
## 4、每次进行基准压测的时长不宜过短通常要求持续15分钟以上
## 5、每轮测试完毕后中间至少暂停5分钟或者确认系统负载完全恢复空跑状态为止
## 6、测试DB服务器要是专用的不能和其他业务混跑否则测试结果就不靠谱了
## 7、其余未尽事宜后续再行补充。
##
## created by yejinrongzhishutang.com
## 2017/6/3
##
## sysbench项目地址 /akopytov/sysbench
##
####################### 2018/02/23  张锐志 ####################################
###叶老师原脚本仅适用于sysbench 0.5版本sysbench升级到1.0后无法使用现修改部分语法。

export LD_LIBRARY_PATH/usr/local/mysql/lib/

. ~/.bash_profile

# 需要启用DEBUG模式时将下面三行注释去掉即可
#set -u
#set -x
#set -e

BASEDIR/data/sysbench
if [ ! -d $BASEDIR ]
then
  mkdir $BASEDIR -p
fi
cd $BASEDIR
#清理之前的遗留记录
rm -rf $BASEDIR/logs*
# 记录所有错误及标准输出到 sysbench.log 中
exec 31 42 1 sysbench.log 21

#时间单位秒
DBIP192.168.1.109
DBPORT3109
DBUSERproxysql
DBPASSWD123456
NOWdate %Y%m%d%H%M
DBNAMEsysbench
REPORT_INTERVAL1
TBLCNT10#表数量
WARMUP300#预热时间秒
DURING1800#持续时间秒
ROWS10000000#每个表中插入1KW行数据
MAXREQ1000000#最大请求数为100W

#当达到持续时间或者最大请求数时这一轮的测试就会停止

# 并发压测的线程数根据机器配置实际情况进行调整
THERAD_NUMBER8 64 128

#初始次数
round0
# 一般至少跑3轮测试我正常都会跑10轮以上
while [ $round -lt 4 ]
do
#每回合日志位置
rounddir$BASEDIR/logs-round${round}
mkdir -p ${rounddir}

for thread in echo ${THERAD_NUMBER}
do
#常用可选项
#oltp_read_only#只读
#oltp_read_write#读写兼有
#oltp_update_non_index#无主键更新情形
sysbench /usr/share/sysbench/oltp_read_only.lua
  --mysql-host$DBIP
  --mysql-port$DBPORT
  --mysql-user$DBUSER
  --mysql-password$DBPASSWD
  --mysql-db$DBNAME
  --db-drivermysql
  --tables$TBLCNT
  --table-size$ROWS
  --report-interval$REPORT_INTERVAL
  --threads${thread}
  --rand-typeuniform #数据随机类型uniform均匀的
  --time$DURING run ${rounddir}/sysbench_${thread}.log

sleep 300#不同的线程数压测之间停顿5分钟
done

roundexpr $round 1
sleep 300#每轮压测之间停顿5分钟
done


​ 运行完毕后在预设的数据目录下可以找到sysbench输出的日志。

3.结果分析与绘图

​可以直接阅读sysbench日志给出的总结也可以对其中个别项的数据进行绘图观察趋势。

SQL statistics:
queries performed:
read:142870
write:0
other:20410
total:163280
transactions:10205  (5.66 per sec.)
queries:163280 (90.53 per sec.)
ignored errors:0(0.00 per sec.)
reconnects:0(0.00 per sec.)

General statistics:
total time:1803.6625s
total number of events:10205

Latency (ms):
min:3113.18
avg:11303.55
max:24222.47
95th percentile:16819.24
sum:115352747.29

Threads fairness:
events (avg/stddev):159.4531/1.51
execution time (avg/stddev):  1802.3867/1.03
#我使用的是硬件资源十分有限的虚拟机压测结果有点扎心。

​安装gnuplot进行绘图gnuplot需要图形环境可以选择在windows上安装也可以在施压客户机上安装图形界面。这里选择在linux施压客户机上安装图形界面。

dnf -y install xfce-desktop #安装图形界面

yum -y install gnuplot #安装gnuplot

gnuplot  #进入gnuplot终端

gnuplotplot output/sysbench_8.log using  9 w lines title QPS
#using 5 表示使用第5列数据作图
#with lines 定义图中的趋势使用线来表示
#title QPS 定义线的名称
#使用,逗号分割进行多列数据的绘制

图形如下只读压测QPS图形

通过其他脚本观察sysbench压测过程中的系统信息和数据库信息来源于《高可用 MySQL》

#!/bin/sh
#开始前获取全局配置参数
#每五秒获取一次cpu load,MySQL全局信息InnoDB引擎相关信息线程信息
INTERVAL5
PREFIX$INTERVAL-sec-status
RUNFILE/root/running
mysql -e show global variablesmysql-variables

#通过检测 /root/running文件是否存在作为是否进行获取信息的依据可以在压测结束时删除此文件停止收集
while  test -e $RUNFILE; do
file$(date %F_%H)
sleep$(date %s.%N |awk {print $INTERVAL -($1 % $INTERVAL)})
sleep $sleep
ts$(date TS %s.%N %F %T)
loadavg$(uptime)#通过uptime命令获取cpu load
echo $ts $loadavg $PREFIX-${file}-status
mysql -e show global status $PREFIX-${file}-status   #获取MySQL全局信息
echo $ts $loadavg $PREFIX-${file}-innodbstatus
mysql -e show engine innodb statusG $PREFIX-${file}-innodbstatus #获取引擎信息
echo $ts $loadavg $PREFIX-${file}-processlist
mysql -e show full processlistG $PREFIX-${file}-processlist   #获取线程信息
echo $ts
done
echo Exiting because $RUNFILE not exist   

对上一步收集到的全局信息进行分析。

#!/bin/sh
awk
BEGIN{
printf #ts date time load QPS;
fmt %.2f;
}
/^TS/ { # The timestamp lines begin with TS.
ts substr($2, 1, index($2,.) - 1);
load NF -  2;
diff ts -prev_ts;
prev_ts ts;
printf %s %s %s %s,ts,$3,$4,substr($load, 1, length($load)-1);
}
/Queries/ {
printf fmt, ($2-Queries)/diff;
Queries$2
}
$

运行方式sh hi_anaylyze.sh 5-sec-status-2018-02-22_14_status gt;gt;4plot.log 将分析后的结果记入4plot.log中

同样使用gnupot进行绘图分析

gunplotplot 4plot using 5 with lines title QPS, 4 with lines title load
#using 5 表示使用第5列数据作图
#with lines 定义图中的趋势使用线来表示
#title QPS 定义线的名称
#使用,逗号分割进行多列数据的绘制

gnuplot绘图示例

​ 两个图形的数据来源不同仅作为示例使用。

本文永久更新链接地址/Linux/2018-02/151053.htm

压力测试步骤

准备测试代码

package mainimport fmtfunc main() {\tfmt.Println(GetFibonacci(6))\tsum : GetNum(10)\tfmt.Println(sum)\tgetRecursion : GetRecursion(10)\tfmt.Println(getRecursion)\tfbNum : GetFbNum(10)\tfmt.Println(fbNum)}/**递归就是自己调自己递归一定要有终止条件否则就会无限循环*/func GetFibonacci(n int) int {\t// 如果是第0项或者第2项直接返回1\tif n  0 || n  1 {\t\treturn 1\t} else {\t\treturn GetFibonacci(n-1)  GetFibonacci(n-2)\t}}/**使用非递归实现斐波那契数列*/func GetFbNum(n int) int {\ta : 1\tb : 1\tc : a  b\tfor i : 1; i  n; i {\t\ta  b\t\tb  c\t\tc  a  b\t}\treturn a}/**使用循环来实现自然数之和*/func GetNum(n int) (sum int) {\tfor i : 1; i  n; i {\t\tsum  i\t}\treturn}/**使用递归来实现自然数求和*/func GetRecursion(n int) (sum int) {\tif n  1 {\t\treturn 1\t} else {\t\treturn n  GetRecursion(n-1)\t}}

创建测试文件

package mainimport testing/**测试递归求斐波那契数列*/func BenchmarkGetFibonacci(b *testing.B) {\tb.ReportAllocs()\tfor i : 0; i  b.N; i {\t\tGetFibonacci(10)\t}}func BenchmarkGetFbNum(b *testing.B) {\tb.ReportAllocs()\tfor i : 0; i  b.N; i {\t\tGetFbNum(10)\t}}

目录存放

执行测试

测试结果显示

数据解释

BenchmarkGetFibonacci 测试的方法名
3835340执行的次数
312 ns/op每次执行时间
后两列代表分配的内存大小和次数48 B/op 1 allocs/op

博主微信欢迎交流

关注博主即可阅读全文