当前位置 : 首页 » 文章分类 :  开发  »  sysbench-数据库基准测试工具

sysbench-数据库基准测试工具

sysbench 是一个脚本化的基准准测试工具,基于 LuaJIT 开发,通常用于对数据库做基准测试(benchmarking), 但其实 sysbench 还可以对 CPU, I/O, 内存,线程做 benchmarking.

akopytov / sysbench
https://github.com/akopytov/sysbench


离线编译安装sysbench 1.0.20

Building and Installing From Source
https://github.com/akopytov/sysbench#building-and-installing-from-source

环境:CentOS Linux release 7.3.1611 (Core)

1、根据文档说明,机器上需提前安装

yum -y install make automake libtool pkgconfig libaio-devel
# For MySQL support, replace with mysql-devel on RHEL/CentOS 5
yum -y install mariadb-devel openssl-devel
# For PostgreSQL support
yum -y install postgresql-devel

我所用的是离线环境,而且刚重装了系统,为了安装这些依赖,挨个从 https://centos.pkgs.org/7/centos-x86_64/ 搜索下载 rpm 包,上传到服务器并安装,还得根据安装提示再一层一层的安装缺失的依赖,费了大劲了。前后总共下载安装了四五十个 rpm 包,刚开始真的又乱又烦,后来熟练后速度还挺快,pkgs.org 这个网站非常好,上面会列出每个包的依赖和被谁引用,很方便。

2、在 release 页面下载最新版源码包
https://github.com/akopytov/sysbench/releases
解压后进入目录,根据文档说明编译安装:

./autogen.sh
# Add --with-pgsql to build with PostgreSQL support
./configure
make -j
make install

3、sysbench --version 查看版本号

# sysbench --version
sysbench 1.0.20

sysbench 使用

基本语法如下:
sysbench [options]... [testname] [command]

testname 测试名

testname 测试名可以来自以下几个地方:

1、内置的测试名,比如 fileio, cpu
sysbench 已内置了下列基准测试:
fileio 文件 I/O 基准测试
cpu cpu 基准测试
memory 内存基准测试
threads 线程调度基准测试
mutex 互斥锁基准测试

2、内置的 lua 脚本,例如 oltp_read_write.lua
不同版本 sysbench 的内置 lua 脚本目录可能不同,我这里是编译源码包安装的 sysbench-1.0.20, 内置脚本在 /usr/local/share/sysbench 目录。
这些脚本也可以在源码包的 sysbench-1.0.20/src/lua 目录下找到,包括:oltp_delete.lua, oltp_insert.lua, oltp_point_select.lua, oltp_read_only.lua, oltp_read_write.lua, oltp_update_index.lua, oltp_update_non_index.lua, oltp_write_only.lua

此外,还有些老版本的脚本在 /usr/local/share/sysbench/tests/include/oltp_legacy 目录下,
这些脚本可以在源码包的 sysbench-1.0.20/tests/include/oltp_legacy 目录下,包括 oltp.lua

3、指向自定义 lua 脚本的路径

command 测试命令

command 表示一个可选的子命令,内置基准测试可用的 command 包括:
prepare 准备测试数据,比如数据库基准测试中灌入测试数据,文件系统基准测试中创建测试文件。
run 运行真正的测试
cleanup 清除测试数据
help 显示帮助。可用于查看某个具体的 testname 的帮助信息,例如 sysbench oltp_write_only help

options 选项

options 是零个或多个 -- 开头的选项列表。
可以 sysbench --help 查看可用的选项及说明。

通用命令行选项

--threads=N 工作线程数,默认值 1
--time=N 总共执行时间(秒),设为 0 表示不限制,默认值 10
--report-interval=N 周期汇报的时间间隔(秒),设为 0 表示禁用周期回报,默认值 0. 注意:周期汇报的统计数据是时间段内的,不是累加的。
--debug[=on|off] 打印debug信息,默认 off
--verbosity=N 日志级别,5 - debug, 0 - only critical messages, 默认值 3
--percentile=N 执行时间的统计百分位,默认值 95
--histogram[=on|off] 在报告中输出时延直方图,默认 off

通用伪随机数选项

--rand-type=STRING 随机数分布方式,可选值有 uniform, gaussian, special, pareto, zipfian, 默认值 special

通用数据库选项

--db-driver=STRING 数据库驱动,默认值 MySQL. sysbench –help 可查看内置的驱动,默认 MySQL 驱动是内置的。

MySQL 相关选项

--mysql-host=[LIST,...] MySQL 服务器主机名,默认 localhost
--mysql-port=[LIST,...] MySQL 服务器端口,默认 3306
--mysql-socket=[LIST,...] 指定连接的 MySQL socket
--mysql-user=STRING MySQL 用户名,默认 sbtest
--mysql-password=STRING MySQL 密码,默认为空
--mysql-db=STRING MySQL 数据库,默认 sbtest
--mysql-ignore-errors=[LIST,...] 忽略哪些 MySQL 错误码,设为 all 表示忽略 [1213,1020,1205]

oltp_common 选项

sysbench oltp_read_write helpsysbench oltp_common help 查看 oltp_common 选项

--tables=N 表个数,默认值 1
--table_size=N 每个表的行数,默认值 10000

--skip_trx[=on|off] 不显式开启事务,所有 sql 都使用 AUTOCOMMIT 提交,默认 off, 即默认都显式开启事务。
--auto_inc[=on|off] 使用自增列作为主键,设为 off 后会使用生成的 id 作为主键,默认 on
--create_secondary[=on|off] 是否再创建一个二级索引,默认 on
--point_selects=N 每个事务的点查询语句个数,默认 10

--range_selects[=on|off] 是否启用范围 select 语句,默认 on
--range_size=N 范围查询的 id 范围,默认 100

--index_updates=N 每个事务的索引更新语句个数,默认 1
--non_index_updates=N 每个事务的非索引更新语句个数,默认 1


用sysbench对MySQL5.7做基准测试

硬件环境

物理机
Intel(R) Xeon(R) Gold 6271C CPU @ 2.60GHz 96 核
内存 792 GB
1TB NVME 固态硬盘
CentOS Linux release 7.6.1810 (Core)


Linux系统参数

1、增大用户打开文件数限制,否则超过 1024 线程后报错:error 2004: Can’t create TCP/IP socket (24)

vi /etc/security/limits.conf

* hard nofile 65536
* soft nofile 65536

2、增大用户最大现场/进程数限制

vi /etc/security/limits.d/20-nproc.conf

*          soft    nproc     40960
*          hard    nproc     40960

MySQL 版本及参数配置

MySQL 裸机部署,单机单实例,datadir 在SSD固态硬盘上
MySQL 版本

mysql> status;
--------------
mysql  Ver 14.14 Distrib 5.7.34, for Linux (x86_64) using  EditLine wrapper

1、最大连接数 20000

max_connections=20000

2、InnoDB buffer 50G

innodb_buffer_pool_size=50G

3、最大预编译语句个数 50000

max_prepared_stmt_count = 50000

sysbench版本与部署

sysbench 发压机和 MySQL 在同台服务器上。
sysbench 版本号:

# sysbench --version
sysbench 1.0.20

准备表结构

1、创建数据库
create database sbtest;

2、创建测试表并准备数据

sysbench --db-driver=mysql --mysql-host=127.0.0.1 --mysql-port=3306 --mysql-user=root --mysql-password=123456 --mysql-db=sbtest oltp_common prepare --tables=1 --table-size=100000000

这个命令会根据 –tables=N 创建 N 个表,表名依次为 sbtest1, sbtest2, … 每个表中插入 –table-size 条数据。
如果想创建一个空表,可以将 –table-size 设为 0

自动创建的表结构如下,手动创建也可以。

CREATE TABLE `sbtest1` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `k` int(11) NOT NULL DEFAULT '0',
  `c` char(120) NOT NULL DEFAULT '',
  `pad` char(60) NOT NULL DEFAULT '',
  PRIMARY KEY (`id`),
  KEY `k_1` (`k`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1

oltp_write_only 写入(增删改)测试

查看 https://github.com/akopytov/sysbench/blob/master/src/lua/oltp_write_only.lua 源码,看到里面有三个方法调用:

prepare_index_updates()
prepare_non_index_updates()
prepare_delete_inserts()

具体实现在 https://github.com/akopytov/sysbench/blob/master/src/lua/oltp_common.lua 中,最终会有转换为:更新索引、更新非索引、删除、插入四种操作。

不要用 oltp_write_only 向已有的表中灌数据,因为里面有删和改,比较慢,直接用 oltp_insert 灌数据更快。

sysbench --threads=150 --time=30 --report-interval=1 --rand-type=uniform --db-driver=mysql --mysql-host=127.0.0.1 --mysql-port=3306 --mysql-user=root --mysql-password=123456 --mysql-db=sbtest oltp_write_only run --tables=1 --table-size=10000000

周期报告:线程数、tps(每秒事务数)、qps(每秒查询数)、每秒的读/写/其它次数、延迟、每秒错误数、每秒重连次数


问题

error 2004: Can’t create TCP/IP socket (24)

sysbench 压测时超过 1024 线程后报错如下:

# sysbench --threads=1500 --time=30 --report-interval=1 --rand-type=uniform --db-driver=mysql --mysql-host=127.0.0.1 --mysql-port=3306 --mysql-user=root --mysql-password=Baidu@123 --mysql-db=sbtest oltp_write_only run --tables=1 --table-size=10000000
sysbench 1.0.20 (using bundled LuaJIT 2.1.0-beta2)

Running the test with following options:
Number of threads: 1500
Report intermediate results every 1 second(s)
Initializing random number generator from current time


Initializing worker threads...

FATAL: unable to connect to MySQL server on host '127.0.0.1', port 3306, aborting...
FATAL: error 2004: Can't create TCP/IP socket (24)
FATAL: `thread_init' function failed: /usr/local/share/sysbench/oltp_common.lua:349: connection creation failed
FATAL: /usr/local/share/sysbench/oltp_write_only.lua:22: module 'oltp_common' not found:
    no field package.preload['oltp_common']
    no file './oltp_common.lua'
    no file './oltp_common/init.lua'
    no file './src/lua/oltp_common.lua'
    no file '/root/.luarocks/share/lua/5.1/oltp_common.lua'
    no file '/root/.luarocks/share/lua/5.1/oltp_common/init.lua'
    no file '/root/.luarocks/share/lua/oltp_common.lua'
    no file '/root/.luarocks/share/lua/oltp_common/init.lua'
    no file '/usr/local/share/lua/5.1/oltp_common.lua'
    no file '/usr/share/lua/5.1/oltp_common.lua'
    no file '/usr/local/share/sysbench/oltp_common.lua'
    no file './oltp_common.so'
    no file '/root/.luarocks/lib/lua/5.1/oltp_common.so'
    no file '/root/.luarocks/lib/lua/oltp_common.so'
    no file '/usr/local/lib/lua/5.1/oltp_common.so'
    no file '/usr/lib/lua/5.1/oltp_common.so'
    no file '/usr/local/lib/sysbench'
FATAL: Cannot find benchmark 'oltp_write_only': no such built-in test, file or module
(last message repeated 3 times)
FATAL: unable to connect to MySQL server on host '127.0.0.1', port 3306, aborting...
FATAL: error 2004: Can't create TCP/IP socket (24)
FATAL: `thread_init' function failed: /usr/local/share/sysbench/oltp_common.lua:349: connection creation failed
FATAL: Cannot find benchmark 'oltp_write_only': no such built-in test, file or module
FATAL: Cannot find benchmark 'oltp_write_only': no such built-in test, file or module
(last message repeated 1 times)
FATAL: unable to connect to MySQL server on host '127.0.0.1', port 3306, aborting...
FATAL: error 2004: Can't create TCP/IP socket (24)
FATAL: `thread_init' function failed: /usr/local/share/sysbench/oltp_common.lua:349: connection creation failed
FATAL: Cannot find benchmark 'oltp_write_only': no such built-in test, file or module
FATAL: /usr/local/share/sysbench/oltp_write_only.lua:22: module 'oltp_common' not found:
    no field package.preload['oltp_common']
    no file './oltp_common.lua'
    no file './oltp_common/init.lua'
    no file './src/lua/oltp_common.lua'
    no file '/root/.luarocks/share/lua/5.1/oltp_common.lua'
    no file '/root/.luarocks/share/lua/5.1/oltp_common/init.lua'
    no file '/root/.luarocks/share/lua/oltp_common.lua'
    no file '/root/.luarocks/share/lua/oltp_common/init.lua'
    no file '/usr/local/share/lua/5.1/oltp_common.lua'
    no file '/usr/share/lua/5.1/oltp_common.lua'
    no file '/usr/local/share/sysbench/oltp_common.lua'
    no file './oltp_common.so'
    no file '/root/.luarocks/lib/lua/5.1/oltp_common.so'
    no file '/root/.luarocks/lib/lua/oltp_common.so'
    no file '/usr/local/lib/lua/5.1/oltp_common.so'
    no file '/usr/lib/lua/5.1/oltp_common.so'
    no file '/usr/local/lib/sysbench'
FATAL: Cannot find benchmark 'oltp_write_only': no such built-in test, file or module
(last message repeated 465 times)
FATAL: Thread initialization failed!

原因:
Linux 默认用户的打开文件数限制为 1024, ulimit -a 可以看到

open files                      (-n) 1024

解决:
修改打开文件数限制为 65536, 保存后重新登录
vi /etc/security/limits.conf

* hard nofile 65536
* soft nofile 65536

Can’t create a new thread (errno 11)

sysbench 压测时报错

FATAL: mysql_stmt_execute() returned error 2012 (target: commerce.0.master: vttablet: rpc error: code = Unknown desc = immediate error from server errorCode=1135 errorMsg=Can't create a new thread (errno 11); if you are not out of available memory, you can consult the manual for a possible OS-dependent bug (errno 2012) (sqlstate HY000) (CallerID: userData1): Sql: "begin", BindVars: {}) for query 'UPDATE sbtest1 SET k=k+1 WHERE id=?'
FATAL: `thread_run' function failed: /usr/local/share/sysbench/oltp_common.lua:458: SQL error, errno = 2012, state = 'HY000': target: commerce.0.master: vttablet: rpc error: code = Unknown desc = immediate error from server errorCode=1135 errorMsg=Can't create a new thread (errno 11); if you are not out of available memory, you can consult the manual for a possible OS-dependent bug (errno 2012) (sqlstate HY000) (CallerID: userData1): Sql: "begin", BindVars: {}

原因:
达到 mysql 用户最大进程/线程数限制

mysql 用户下 ulimit -a 看到最大进程数为 4096

max user processes              (-u) 4096

解决:
1、CentOS 5 及之前版本:
vi /etc/security/limits.conf
添加:

* hard nproc 65536
* soft nproc 65536

2、CentOS 6 及之后版本中,修改 /etc/security/limits.conf 并不会生效,因为被 /etc/security/limits.d/20-nproc.conf 中下面的配置覆盖了

*          soft    nproc     4096
root       soft    nproc     unlimited

应该将上述配置添加到 /etc/security/limits.d/20-nproc.conf

Can’t create a new thread (errno 11)
https://sites.google.com/site/sysknife8/database/cantcreateanewthreaderrno11

Can’t Create Thread: Errno 11 (A Tale of Two Ulimits)
https://www.percona.com/blog/2013/02/04/cant_create_thread_errno_11/


Can’t create more than max_prepared_stmt_count statements (current value: 16382)

sysbench 使用 4096 线程压测时,MySQL 报错:

FATAL: mysql_stmt_prepare() failed
FATAL: MySQL error: 1461 "Can't create more than max_prepared_stmt_count statements (current value: 16382)"
FATAL: `thread_init' function failed: /usr/local/share/sysbench/oltp_common.lua:275: SQL API error

原因:
超过了 MySQL 最大预编译语句个数配置 max_prepared_stmt_count, 默认值是 16382

解决:

set global max_prepared_stmt_count=500000;

或者 my.cnf 中配置:

max_prepared_stmt_count = 500000

基准测试与压力测试

数据库的基准测试是对数据库的性能指标进行定量的、可复现的、可对比的测试。

基准测试可以理解为针对系统的一种压力测试。但基准测试不关心业务逻辑,更加简单、直接、易于测试,数据可以由工具生成,不要求真实;而压力测试一般考虑业务逻辑,要求真实的业务数据。


【MySQL】【压测】使用sysbench对MySQL进行压力测试(最后有用 gnuplot 进行绘图不错)
https://blog.51cto.com/l0vesql/2072412

sysbench在美团点评中的应用
https://tech.meituan.com/2017/07/14/sysbench-meituan.html

上一篇 etcd

下一篇 Spring-Event

阅读
评论
3.1k
阅读预计15分钟
创建日期 2021-06-22
修改日期 2021-07-23
类别

页面信息

location:
protocol:
host:
hostname:
origin:
pathname:
href:
document:
referrer:
navigator:
platform:
userAgent:

评论