DB性能测试-常用3套件-手把手一步一步跑sysbench

Abstract

把过去的写的一篇笔记分享一下, 数据库最常用的测试三套件, sysbench -- oltp 测试, tpch -- olap 测试, tpcc -- 事务性能测试。 本文手把手 一步一步 run sysbench

整个过程, 分为 * 介绍 * 准备工作 * 编译 * 测试 * 疑难杂症

介绍

下面引用老外的一段话来介绍一下sysbench

1
2
3
4
5
6
7
8
9
10
sysbench is a scriptable multi-threaded benchmark tool based on LuaJIT. It is most frequently used for database benchmarks, but can also be used to create arbitrarily complex workloads that do not involve a database server.

sysbench comes with the following bundled benchmarks:

* oltp_*.lua: a collection of OLTP-like database benchmarks
* fileio: a filesystem-level benchmark
* cpu: a simple CPU benchmark
* memory: a memory access benchmark
* threads: a thread-based scheduler benchmark
* mutex: a POSIX mutex benchmark
今天我们最主要使用的oltp 系列测试

准备工作

安装相应的包

1
2
3
yum -y install gcc gcc-c++ autoconf automake make libtool bzr mysql-devel git mysql
yum -y install make automake libtool pkgconfig libaio-devel
yum -y install openssl-devel

执行如下命令配置Sysbench client,使内核可以使用所有的CPU核处理数据包(默认设置为使用2个核),同时减少CPU核之间的上下文切换。

1
2
3
4
sudo sh -c 'for x in /sys/class/net/eth0/queues/rx-*; do echo ffffffff>$x/rps_cpus; done'
sudo sh -c "echo 32768 > /proc/sys/net/core/rps_sock_flow_entries"
sudo sh -c "echo 4096 > /sys/class/net/eth0/queues/rx-0/rps_flow_cnt"
sudo sh -c "echo 4096 > /sys/class/net/eth0/queues/rx-1/rps_flow_cnt"
备注: 说明 ffffffff表示使用32个核。请根据实际配置修改,例如ECS为8核,则输入ff。

编译

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
git clone https://github.com/akopytov/sysbench.git
##从Git中下载sysbench

cd sysbench
##打开sysbench目录

git checkout 1.0.18
##切换到sysbench 1.0.18版本, 也可以不用切换到1.0.18 版本上,直接使用master

./autogen.sh
##运行autogen.sh

./configure --prefix=/usr --mandir=/usr/share/man

make
##编译

make install

测试

sysbench 的测试 通常类似这样, 分为3个阶段, 一个prepare, 一个run, 一个cleanup

1
2
3
4
5
6
7
8
sysbench --db-driver=mysql --mysql-host=XXX --mysql-port=XXX --mysql-user=XXX --mysql-password=XXX --mysql-db=sbtest --table_size=25000 --tables=250 --events=0 --time=600  oltp_write_only prepare
##准备数据

sysbench --db-driver=mysql --mysql-host=XXX --mysql-port=XXX --mysql-user=XXX --mysql-password=XXX --mysql-db=sbtest --table_size=25000 --tables=250 --events=0 --time=600 --threads=XXX --percentile=95 --report-interval=1 oltp_write_only run
##运行workload

sysbench --db-driver=mysql --mysql-host=XXX --mysql-port=XXX --mysql-user=XXX --mysql-password=XXX --mysql-db=sbtest --table_size=25000 --tables=250 --events=0 --time=600 --threads=XXX --percentile=95 oltp_write_only cleanup
##清理
命令解释
1
2
3
4
5
6
7
8
9
10
11
12
13
--mysql-host       IP
--mysql-port 端口号
--mysql-db 希望链接的数据库
--mysql-user 用户名
--mysql-password 密码
--table_size 每张表初始化的数据数量
--tables 初始化表的数量
--threads 启动的线程
--time 运行时间设为0表示不限制时间
--report-interval 运行期间日志,单位为秒
--events 最大请求数量,定义数量后可以不需要--time选项
--rand-type 访问数据时使用的随机生成函数 可以选择"special", "uniform", "gaussian", "pareto", 默认special, 早期时uniform
--skip_trx=on 在只读测试中可以选择打开或关闭事务, 默认是打开

作者写了一个自动测试的脚本, 读者可以从https://github.com/longdafeng/test/tree/master/shell/sysbench 将脚本下载下来 记得将 脚本放到 sysbench 源码目录下src/lua 下面

1
2
3
4
5
6
cd sysbench
cd src/lua
wget https://raw.githubusercontent.com/longdafeng/test/master/shell/sysbench/start-sysbench.sh
wget https://raw.githubusercontent.com/longdafeng/test/master/shell/sysbench/start.sh
nohup ./start.sh hostxxx portxxx userxxx passwordxxx dbxxx > run.log 2>&1 &
tail -f run.log

其中hostxxx, portxxx, userxxx, passwordxxx, dbxxx 修改为真实mysql的参数 这个脚本, 是设置不同大表大小, 设置不同随机参数, 设置不同的线程数, 设置是否打开或关闭事务, 依次运行oltp_read_only, oltp_write_only, oltp_read_write 3个集成测试, 在src/lua 目录下, 还有很多单项测试, 比如insert, point_select, update_index, update_non_index, select_random_points, select_random_ranges 分别是针对不同的场景的测试

1
2
3
[root@kudu lua]# ls *.lua
bulk_insert.lua oltp_common.lua oltp_insert.lua oltp_read_only.lua oltp_update_index.lua oltp_write_only.lua select_random_points.lua
empty-test.lua oltp_delete.lua oltp_point_select.lua oltp_read_write.lua oltp_update_non_index.lua prime-test.lua select_random_ranges.lua

疑难杂症

性能差

sysbench 是对cpu/memory/网络非常敏感的测试, 经常遇到 很多客户在测试的过程中,发现性能和预期的差距比较大, 深究后,发现, sysbench的肉机(客户端) 和目标测试数据不在同一个局域网或者一个vpc 内(云上客户), 对于很多云数据库, 肉机和目标mysql 必须在同一个region, 并且是在同一个vpc, 并且在链接字符串的时候,必须使用私有的链接地址,不能使用公网的链接地址, 公网的链接地址会经过很多跳。

假设语句是: sysbench oltp_read_write.lua --mysql-host=127.0.0.1 --mysql-port=3306 --mysql-db=sbtest --mysql-user=root --mysql-password=123456 --table_size=200000000 --tables=1 --threads=500 --events=500000 --report-interval=10 --time=0

no such built-in test, file or module

如果执行的时候提示FATAL: Cannot find benchmark 'oltp_read_write.lua': no such built-in test, file or module

切换到sysbench的源码目录(sysbench.tar.gz解压路径) find ./ -name oltp_read_write.lua ./src/lua/oltp_read_write.lua 接着切换到src/lua 目录再执行语句

“Can not connect to MySQL server. Too many connections”

#如果执行的时候命令行提示“Can not connect to MySQL server. Too many connections”-mysql 1040错误: shell>mysql -uroot -p**** mysql>show variables like 'max_connections';(查看当前的最大连接数) mysql>set global max_connections=1000;(设置最大连接数为1000,可以再次查看是否设置成功) mysql>show variables like 'max_connections';(查看当前的最大连接数) mysql>exit

sysbench 无法运行

1
ldd /usr/bin/sysbench
正常情况下, sysbench 依赖的所有library 应该都可以resolve 掉, 如果有的时候,没有找到依赖的library, 最常见的是没有找到mysql的library 需要安装
1
yum -y install mysql-devel mysql
然后再重新编译sysben的源码

如果问题依旧存在 可以尝试, 手动创建连接

1
2
3
4
5
6
去根目录找一下:
find / -name "*mysqlclient_r*"
/usr/lib64/mysql/libmysqlclient_r.so.18
/usr/lib64/mysql/libmysqlclient_r.so.18.1.0
库文件是有的,不过带个数字后缀,给库文件建立软链接:
ln -s /usr/lib64/mysql/libmysqlclient_r.so.18 /usr/lib64/mysql/libmysqlclient_r.so

如果问题还是不能解决, 最后的办法就是从github 上下载mysql的源码, 先对mysql 源码进行编译,安装,然后再重新编译sysbench

# --with-mysql-includes选项指定mysql的include文件夹,里面是一些.h的头文件,比如mysql.h,未安装mysql-community-devel-version是没有include文件夹的
# with-mysql-libs选项指定mysql的一些lib,里面是一些.a文件和.so文件,比如libmysqlclient.a,libmysqlclient.so
# 比如./configure --prefix=/usr   --with-mysql-includes=/usr/include/mysql --with-mysql-libs=/usr/lib64/mysql