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 3>&1 4>&2 1>> sysbench_prepare.log 2>&1
- DBIP=192.168.1.109
- DBPORT=3109
- DBUSER='proxysql'
- DBPASSWD='123456'
- NOW=`date +'%Y%m%d%H%M'`
- DBNAME="sysbench"
- TBLCNT=10 #表数量
- WARMUP=300 #预热时间 (秒)
- DURING=1800 #持续时间 (秒)
- ROWS=10000000 #每个表中插入 1KW 行数据
- MAXREQ=1000000 #最大请求数为 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-driver=mysql \
- --tables=10 \
- --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 yejinrong@zhishutang.com
- ## 2017/6/3
- ##
- ## sysbench 项目地址: https://github.com/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 3>&1 4>&2 1>> sysbench.log 2>&1
- # 时间单位秒
- DBIP=192.168.1.109
- DBPORT=3109
- DBUSER='proxysql'
- DBPASSWD='123456'
- NOW=`date +'%Y%m%d%H%M'`
- DBNAME="sysbench"
- REPORT_INTERVAL=1
- TBLCNT=10 #表数量
- WARMUP=300 #预热时间 (秒)
- DURING=1800 #持续时间 (秒)
- ROWS=10000000 #每个表中插入 1KW 行数据
- MAXREQ=1000000 #最大请求数为 100W
- # 当达到持续时间或者最大请求数时, 这一轮的测试就会停止
- # 并发压测的线程数, 根据机器配置实际情况进行调整
- THERAD_NUMBER="8 64 128"
- # 初始次数
- round=0
- # 一般至少跑 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-driver=mysql \
- --tables=$TBLCNT \
- --table-size=$ROWS \
- --report-interval=$REPORT_INTERVAL \
- --threads=${thread} \
- --rand-type=uniform \ #数据随机类型: uniform, 均匀的
- --time=$DURING run >> ${rounddir}/sysbench_${thread}.log
- sleep 300 #不同的线程数压测之间停顿 5 分钟
- done
- round=`expr $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 终端
- gnuplot>plot '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 引擎相关信息, 线程信息
- INTERVAL=5
- PREFIX=$INTERVAL-sec-status
- RUNFILE=/root/running
- mysql -e 'show global variables'>>mysql-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 status\G" >> $PREFIX-${file}-innodbstatus & #获取引擎信息
- echo "$ts $loadavg">> $PREFIX-${file}-processlist
- mysql -e "show full processlist\G" >>$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 "\n%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 >>4plot.log (将分析后的结果记入 4plot.log 中)
同样使用 gnupot 进行绘图分析:
- gunplot>plot '4plot' using 5 with lines title 'QPS', 4 with lines title 'load'
- #using 5 表示使用第 5 列数据作图
- #with lines 定义图中的趋势使用线来表示
- #title 'QPS' 定义线的名称
- #使用,(逗号) 分割, 进行多列数据的绘制
gnuplot 绘图示例
(两个图形的数据来源不同, 仅作为示例使用)
来源: http://www.linuxidc.com/Linux/2018-02/151053.htm