Linux 中有很多压测工具,不同的场景会各有优劣,例如磁盘压测工具 fio 。
Sysbench 算是一个比较通用的压测或者基准测试工具,这是一个开源、模块化、跨平台的多线程性能测试工具,可以用来进行 CPU、内存、IO、线程、数据库的性能测试,其中数据库支持 MySQL、Oracle 和 PostgreSQL 。
这里简单介绍其使用方法。
简介
sysbench 用于基准测试,包括了:CPU 性能、磁盘 IO 性能、调度程序性能、内存分配及传输速度、POSIX 线程性能、数据库性能(OLTP基准测试,支持 MySQL、PostgreSQL、Oracle)等。
所谓的基准测试,主要是对测试对象,进行定量、可复现、可对比的测试,不关心业务逻辑,相比来说更加简单、直接、易于测试,数据可以由工具生成,不要求真实。
另外一种是压力测试,此时一般需要考虑具体的业务逻辑,需要确保压测模型尽量服务期望场景,所以一般是真实数据。
安装
在 CentOS 中,对应的 RPM 包仓库在 EPEL 中,可以通过如下命令安装。
# yum --enablerepo=epel install sysbench
建议使用上述的二进制安装方式,源码安装要复杂一些,最新的是在 github 上维护的 akopytov/sysbench,下载源码可以通过如下方式编译。
$ ./autogen.sh && ./configure && make && cd sysbench
$ ./sysbench --help // 查看帮助
$ ./sysbench --test=cpu help // 查看标准测试的帮助
在执行 ./configure
时,如果通过 mysql_config
无法找到库、头文件目录等,可以通过 --with-mysql-includes=...
、--with-mysql-libs=...
进行配置。
如果想要支持 pgsql 和 Oracle,在配置时需要添加 --with-pgsql
或者 --with-oracle
选项,否则默认只支持 MySQL,相关的驱动源码保存在 sysbench/drivers
目录下。
常用命令
基本的使用方式如下。
$ sysbench [common-options] --test=name [test-options] command
其中 --test
指定测试工具,command 包括了 prepare
、run
、cleanup
、help
,prepare 用于准备数据,常用于 fileio
、oltp
测试,其它用于运行、清理、查看帮助。
对于具体的参数可以通过 sysbench --help
查看,包括了常用的参数、内置的压测引擎等。
相关的子类压测,同样有帮助文档,例如 sysbench --test=cpu help
查看与 CPU 压测相关的一些帮助文档。
通用参数
--num-threads=N 创建测试线程的数目,默认为 1;
--max-requests=N 总请求数,与--max-time选择一个设置即可,默认值为 10000;
--max-time=N 总执行时间,单位为秒,默认值为0,也就是不限制;
--forced-shutdown=STRING 当超过--max-time后强制中断,默认为off;
--thread-stack-size=SIZE 每个线程的stack大小,默认为64K;
系统基准测试
介绍一些常见的基准测试,关于 OLTP 单独再述。
CPU 基准测试
使用 64 位整数,测试计算质数直到某个最大值所需要的时间。
$ sysbench --test=cpu --cpu-max-prime=2000 run
$ sysbench --num-threads=3 --test=cpu --cpu-max-prime=2000000 run
线程基准测试
测试线程调度器的性能,对于高负载情况下测试线程调度器的行为非常有用。
$ ./sysbench --test=threads help
$ ./sysbench --test=threads --num-threads=500 --thread-yields=100 --thread-locks=4 run
内存基准测试
用于测试内存的连续读写性能。
$ ./sysbench --test=memory help
$ ./sysbench --test=memory --memory-block-size=8k --memory-total-size=1G run
互斥锁基准测试
互斥锁用于在多线程编程中,防止两个线程同时对同一公共资源,如全局变量,进行读写的机制来保证共享数据操作的完整性。测试互斥锁的性能,方式是模拟所有线程在同一时刻并发运行,并都短暂请求互斥锁。
$ ./sysbench --test=mutex help
$ ./sysbench --test=mutex --num-threads=100 --mutex-num=1000 \
--mutex-locks=100000 --mutex-loops=10000 run
文件 IO 基准测试
测试包括了 prepare、run、cleanup,主要用于准备测试需要文件,运行测试,清理。注意,生成的数据文件至少要比内存大,否则操作系统可能会缓存大部分的数据,导致测试结果无法体现 IO 密集型的工作负载。
OLTP
之前的版本 oltp 是内建的版本,现在采用的是 lua 脚本实现,保存在 tests/db
目录下,通过这种方式,使得需要定制个性化测试时不用再重新编译。
在此只针对 MySQL,进行测试;该驱动保存在源码的 drivers/mysql
目录下,关于驱动相关的参数,例如 mysql-host
、mysql-socket
等,可以查看源码。如果不指定则默认使用 sbtest
数据库,此时需要手动创建该数据库。
编译完成之后,直接到源码的的 sysbench 目录下执行如下命令即可。
$ ./sysbench --mysql-host=127.1 --mysql-port=3306 --mysql-user=root \
--mysql-password=new-password --mysql-table-engine=innodb \
--test=tests/db/oltp.lua --oltp_tables_count=1 --oltp-table-size=1000 prepare
$ ./sysbench --mysql-host=127.1 --mysql-port=3306 --mysql-user=root \
--mysql-password=new-password --mysql-table-engine=innodb \
--num-threads=16 --test=tests/db/oltp.lua --oltp_tables_count=1 --oltp-table-size=1000 run
$ ./sysbench --mysql-host=127.1 --mysql-port=3306 --mysql-user=root \
--mysql-password=new-password --mysql-table-engine=innodb \
--test=tests/db/oltp.lua --oltp_tables_count=1 --oltp-table-size=1000 cleanup
如上的命令,prepare 只需要执行一次,然后可以执行多次 run 即可。其它一些常见的参数可以参考:
--num-threads=1 线程数
--report-interval=5 每隔5秒打印一次统计结果
对于 MyISAM 的测试可以直接将上述的存储引擎更换为 myisam 即可,命令详见如下。
$ ./sysbench --mysql-host=127.1 --mysql-port=3306 --mysql-user=root \
--mysql-password=new-password --mysql-table-engine=myisam \
--test=tests/db/oltp.lua --oltp_tables_count=1 --oltp-table-size=1000 prepare
$ ./sysbench --mysql-host=127.1 --mysql-port=3306 --mysql-user=root \
--mysql-password=new-password --mysql-table-engine=myisam \
--num-threads=16 --test=tests/db/oltp.lua --oltp_tables_count=1 --oltp-table-size=1000 run
$ ./sysbench --mysql-host=127.1 --mysql-port=3306 --mysql-user=root \
--mysql-password=new-password --mysql-table-engine=myisam \
--test=tests/db/oltp.lua --oltp_tables_count=1 --oltp-table-size=1000 cleanup
源码相关
相关驱动文件保存在 sysbench/drivers
目录,测试相关模块在 sysbench/tests
目录下,下面看下与 DB 相关的脚本。
tests/db
首先看下 common.lua
这个文件,该文件用于读取参数、执行 prepare、执行 cleanup;其中后两者分别对应了相应的函数,prepare 会调用 create_insert 创建表并插入数据;而清除则是简单删除掉之前创建的表。
接下来看看 oltp.lua
文件,主要有两个函数:A) thread_init()
会调用 set_vars()
设置与 oltp 相关的参数,初始化每个线程相关的参数;B) event()
函数用于处理每次调用,包括了事务执行包含了那些语句,及其次数等。
其中一个比较简单的示例可以参考 oltp_simple.lua
文件。