未加星标

使用sysbench对MySQL压力测试

字体大小 | |
[数据库(mysql) 所属分类 数据库(mysql) | 发布者 店小二04 | 时间 2017 | 作者 红领巾 ] 0人收藏点击收藏

sysbench是一个模块化的、跨平台、多线程基准测试工具,主要用于评估测试各种不同系统参数下的数据库负载情况。关于这个项目的详细介绍请看: https://github.com/akopytov/sysbench 。

它主要包括以下几种方式的测试:

cpu性能 磁盘io性能 调度程序性能 内存分配及传输速度 POSIX线程性能 数据库性能(OLTP基准测试)

sysbench的数据库OLTP测试支持mysql、PostgreSQL、Oracle,目前主要用于linux操作系统,开源社区已经将sysbench移植到了windows,并支持SQL Server的基准测试。

废话不多说,开始。

1. sysbench安装 mysql版本: mysql-community-server-5.6.29 OS:CentOS 6.7 X86_64 sysbench 0.5相比0.4版本有一些变化,包括oltp测试结合了lua脚本,还多了一些隐藏选项,本文会涉及得到一部分。

目前许多仓库里已编译好的二进制sysbench还是0.4.x版本,不过现在主流也还是github上的0.5,可以从 这里 下载0.5版本的rpm包直接安装,不过我选择自己编译,因为只有这个办法是通用的。

// 先安装编译依赖环境 $ sudo yum install gcc gcc-c++ automake make libtool mysql-community-devel $ cd /tmp && git clone https://github.com/akopytov/sysbench.git $ cd /tmp/sysbench && ./autogen.sh $ ./configure --prefix=/usr/local/sysbench-0.5 $ ./make && sudo make install // 0.5版本需要oltp.lua测试脚本 // 如果是rpm包方式安装的,在 /usr/share/doc/sysbench/tests/db/ 下可找到 $ cd /usr/local/sysbench && sudo mkdir -p share/tests/db $ cp /tmp/sysbench/sysbench/tests/db/*.lua share/tests/db/ $ ./bin/sysbench --version sysbench 0.5

如果需要测试PostgreSQL、Oracle,则在configure时需要加上 with-oracle 或者 with-pgsql 参数

2. 使用sysbench对mysql压测 2.1 只读示例 ./bin/sysbench --test=./share/tests/db/oltp.lua \ --mysql-host=10.0.201.36 --mysql-port=8066 --mysql-user=ecuser --mysql-password=ecuser \ --mysql-db=dbtest1a --oltp-tables-count=10 --oltp-table-size=500000 \ --report-interval=10 --oltp-dist-type=uniform --rand-init=on --max-requests=0 \ --oltp-test-mode=nontrx --oltp-nontrx-mode=select \ --oltp-read-only=on --oltp-skip-trx=on \ --max-time=120 --num-threads=12 \ [prepare|run|cleanup]

注意最后一行,一项测试开始前需要用 prepare 来准备好表和数据, run 执行真正的压测, cleanup 用来清除数据和表。实际prepare的表结构:

mysql> desc dbtest1a.sbtest1; +-------+------------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------+------------------+------+-----+---------+----------------+ | id | int(10) unsigned | NO | PRI | NULL | auto_increment | | k | int(10) unsigned | NO | MUL | 0 || | c | char(120) | NO |||| | pad | char(60) | NO |||| +-------+------------------+------+-----+---------+----------------+ 4 rows in set (0.00 sec)

上面的测试命令代表的是:对mysql进行oltp基准测试,表数量10,每表行数约50w(几乎delete多少就会insert的多少),并且是非事务的只读测试,持续60s,并发线程数12。

需要说明的选项: mysql-db=dbtest1a :测试使用的目标数据库,这个库名要事先创建 --oltp-tables-count=10 :产生表的数量 --oltp-table-size=500000 :每个表产生的记录行数 --oltp-dist-type=uniform :指定随机取样类型,可选值有 uniform(均匀分布), Gaussian(高斯分布), special(空间分布)。默认是special --oltp-read-only=off :表示不止产生只读SQL,也就是使用oltp.lua时会采用读写混合模式。默认 off,如果设置为on,则不会产生update,delete,insert的sql。 --oltp-test-mode=nontrx :执行模式,这里是非事务式的。可选值有simple,complex,nontrx。默认是complex simple:简单查询,SELECT c FROM sbtest WHERE id=N complex (advanced transactional):事务模式在开始和结束事务之前加上begincommit, 一个事务里可以有多个语句,如点查询、范围查询、排序查询、更新、删除、插入等,并且为了不破坏测试表的数据,该模式下一条记录删除后会在同一个事务里添加一条相同的记录。 nontrx (non-transactional):与simple相似,但是可以进行update/insert等操作,所以如果做连续的对比压测,你可能需要重新cleanup,prepare。 --oltp-skip-trx=[on|off] :省略begin/commit语句。默认是off

--rand-init=on :是否随机初始化数据,如果不随机化那么初始好的数据每行内容除了主键不同外其他完全相同

--num-threads=12 : 并发线程数,可以理解为模拟的客户端并发连接数 --report-interval=10 :表示每10s输出一次测试进度报告 --max-requests=0 :压力测试产生请求的总数,如果以下面的 max-time 来记,这个值设为0 --max-time=120 :压力测试的持续时间,这里是2分钟。

注意,针对不同的选项取值就会有不同的子选项。比如 oltp-dist-type=special ,就有比如 oltp-dist-pct=1 、 oltp-dist-res=50 两个子选项,代表有50%的查询落在1%的行(即热点数据)上,另外50%均匀的(sample uniformly)落在另外99%的记录行上。

再比如 oltp-test-mode=nontrx 时, 就可以有 oltp-nontrx-mode ,可选值有select(默认), update_key, update_nokey, insert, delete,代表非事务式模式下使用的测试sql类型。

以上代表的是一个只读的例子,可以把 num-threads 依次递增(16,36,72,128,256,512),或者调整my.cnf参数,比较效果。另外需要注意的是,大部分mysql中间件对事务的处理,默认都是把sql发到主库执行,所以只读测试需要加上 oltp-skip-trx=on 来跳过测试中的显式事务。

ps1: 只读测试也可以使用 share/tests/db/select.lua 进行,但只是简单的point select。

ps2: 我在用sysbench压的时候,在mysql后端会话里有时看到大量的query cache lock,如果使用的是uniform取样,最好把查询缓存关掉。当然如果是做两组性能对比压测,因为都受这个因素影响,关心也不大。

2.2 混合读写

读写测试还是用oltp.lua,只需把 --oltp-read-only 等于 off 。

./bin/sysbench --test=./share/tests/db/oltp.lua --mysql-host=10.0.201.36 --mysql-port=8066 --mysql-user=ecuser --mysql-password=ecuser --mysql-db=dbtest1a --oltp-tables-count=10 --oltp-table-size=500000 --report-interval=10 --rand-init=on --max-requests=0 --oltp-test-mode=nontrx --oltp-nontrx-mode=select --oltp-read-only=off --max-time=120 --num-threads=128 prepare ./bin/sysbench --test=./share/tests/db/oltp.lua --mysql-host=10.0.201.36 --mysql-port=8066 --mysql-user=ecuser --mysql-password=ecuser --mysql-db=dbtest1a --oltp-tables-count=10 --oltp-table-size=500000 --report-interval=10 --rand-init=on --max-requests=0 --oltp-test-mode=nontrx --oltp-nontrx-mode=select --oltp-read-only=off --max-time=120 --num-threads=128 run ./bin/sysbench --test=./share/tests/db/oltp.lua --mysql-host=10.0.201.36 --mysql-port=8066 --mysql-user=ecuser --mysql-password=ecuser --mysql-db=dbtest1a --oltp-tables-count=10 --oltp-table-size=500000 --report-interval=10 --rand-init=on --max-requests=0 --oltp-test-mode=nontrx --oltp-nontrx-mode=select --oltp-read-only=off --max-time=120 --num-threads=128 cleanup

然而 oltp-test-mode=nontrx 一直没有跟着我预期的去走,在mysql general log里面看到的sql记录与 complex 模式相同。所以上面示例中的 --oltp-test-mode=nontrx --oltp-nontrx-mode=select 可以删掉。

update:

sysbench作者 akopytov 对我这个疑问有了回复: https://github.com/akopytov/sysbench/issues/34 ,原来sysbench 0.5版本去掉了这个选项,因为作者正在准备1.0版本,所以也就没有更新0.5版本的doc。网上的博客漫天飞,就没有一个提出来的,也是没谁了。

分析一下oltp.lua脚本内容,可以清楚单个事务各操作的默认比例:select:update_key:update_non_key:delete:insert = 14:1:1:1:1,可通过 oltp-point-selects 、 oltp-simple-ranges 、 oltp-sum-ranges 、 oltp-order-ranges 、 oltp-distinct-ranges , oltp-index-updates 、 oltp-non-index-updates 这些选项去调整读写权重。

同只读测试一样,在atlas,mycat这类中间件测试中如果不加 oltp-skip-trx=on ,那么所有查询都会发往主库,但如果在有写入的情况下使用 --oltp-skip-trx=on 跳过BEGIN和COMMIT,会出现问题:

ALERT: failed to execute MySQL query: INSERT INTO sbtest4 (id, k, c, pad) VALUES (48228, 47329, '82773802508-44916890724-85859319254-67627358653-96425730419-64102446666-75789993135-91202056934-68463872307-28147315305', '13146850449-23153169696-47584324044-14749610547-34267941374') :

ALERT: Error 1062 Duplicate entry ‘48228’ for key ‘PRIMARY’

FATAL: failed to execute function `event’: (null)

原因也很容易理解,每个线程将选择一个随机的表,不加事务的情况下高并发更新(插入)出现重复key的概率很大,但我们压测不在乎这些数据,所以需要跳过这个错误 --mysql-igno

本文数据库(mysql)相关术语:navicat for mysql mysql workbench mysql数据库 mysql 存储过程 mysql安装图解 mysql教程 mysql 管理工具

分页:12
转载请注明
本文标题:使用sysbench对MySQL压力测试
本站链接:http://www.codesec.net/view/522736.html
分享请点击:


1.凡CodeSecTeam转载的文章,均出自其它媒体或其他官网介绍,目的在于传递更多的信息,并不代表本站赞同其观点和其真实性负责;
2.转载的文章仅代表原创作者观点,与本站无关。其原创性以及文中陈述文字和内容未经本站证实,本站对该文以及其中全部或者部分内容、文字的真实性、完整性、及时性,不作出任何保证或承若;
3.如本站转载稿涉及版权等问题,请作者及时联系本站,我们会及时处理。
登录后可拥有收藏文章、关注作者等权限...
技术大类 技术大类 | 数据库(mysql) | 评论(0) | 阅读(67)