百分百源码网-让建站变得如此简单! 登录 注册 签到领金币!

主页 | 如何升级VIP | TAG标签

当前位置: 主页>网站教程>数据库> mysql性能测试工具mysqlslap的使用
分享文章到:

mysql性能测试工具mysqlslap的使用

发布时间:01/15 来源: 浏览: 关键词:
mysqlslap是mysql的一个压力测试工具了,我们可以利用mysqlslap来测试你配置服务器的一个压力了,具体的来给各位简单介绍一下吧。

特别关注下mysqlslap的假并发现象,因为压力上不去浪费了一些时间。
主要就是–concurrency 参数所指的并发是线程并发,在开头再??乱槐椤?/p>

1.mysql性能测试工具

mysql的性能测试工具常用的有四种:The MySQL Benchmark Suite、MySQL super-smack、MyBench和自带的Mysqlslap. 除了第一个为MySQL性能测试工具,其他三个都为压力测试工具

(1)The MySQL Benchmark Suite : 基于Perl语言和其中的两个模块:DBI和Benchmark,因为不支持多CPU而且不是压力工具,抛弃该软件

(2)MySQL super-smack 业界口碑较好,安装出了压缩包编译安装外,还需要yacc以及lex支持,安装报错找不到 lex和yacc啊啥的。 linux下使用flex及bison代替,可以用apt-get install bison flex 或类似的命令安装,问题是还要找能连接外网的机器,能连接外网的机器不一定支持压力,放弃该软件

(3)MyBench

也是个perl模块,虽然安装方便,但是测试数据的使用比较麻烦,drop it.

(4) Mysqlslap

最终选用了mysqlslap。 安装成本小:原因是mysql5.1.4 版本自带,安装mysql后就可以使用,不需要额外的配置。 场景部署多:带有多个参数选项,测试数据的使用也方便。通过模拟多个并发客户端并发访问MySQL来执行压力测试, 结果分析全:同时提供了较详细的SQL执行数据性能报告,并且能很好的对比多个存储引擎(MyISAM,InnoDB等)在相同环境下的相同并发压力下的性能差别。

mysqlslap的官方网站: http://dev.mysql.com/doc/refman/5.6/en/mysqlslap.html

2.mysqlslap的安装

1) 查看当前的mysql版本

./bin/mysql -V

2)如果版本低于5.1.4 请安装mysql高版本

安装过程中首先要关闭现在的客户端。用netstat -pan|grep mysql查看当前mysql 的端口是否在运行。 为避免端口冲突,安装前最好将mysql的进程关闭

3.mysqlslap的使用

(1) 使用步骤

看下官网对于使用步骤的解释:

Create schema, table, and optionally any stored programs or data to use for the test. This stage uses a single client connection.

Run the load test. This stage can use many client connections.

Clean up (disconnect, drop table if specified). This stage uses a single client connection

mysqlslap的使用步骤主要是: 1. 创建schema、准备测试语句 (在MySQL中,schema就是database); 2. 运行负载测试,可以使用多个并发客户端连接;(编写脚本,可用多进程并发) 3. 测试环境清理 ,关闭进程,清理数据等。

(2) 参数说明
以下是mysqlslap的参数含义

view plaincopy to clipboardprint?
./bin/mysqlslap --help 可以看到帮助的参数解释,下面介绍一些比较常用的 
 
--no-defaults 表示不使用默认参数文件中的设置. 
--debug-info, -T 打印内存和CPU的信息; 
--auto-generate-sql, <span style="color: purple;">-a</span> 自动生成测试表和数据; 
--auto-generate-sql-load-type=type 测试语句的类型. 取值包括read, key, write, update和mixed(默认); 
--number-char-cols=N, <span style="color: purple;">-x</span>  
N 自动生成的测试表中包含多少个字符类型的列, 默认1; 
--number-int-cols=N, -y N 自动生成的测试表中包含多少个数字类型的列, 默认1; 
--number-of-queries=N 总的测试查询次数(并发客户端数×每客户端查询次数); 
--query=name,<span style="color: purple;">-q</span> 使用自定义脚本执行测试, 例如可以调用自定义的一个存储过程或者sql语句来执行测试. 
--create-schema 测试的schema, MySQL 中schema也就是database; 
--commint=N 多少条DML后提交一次; 
--compress, -C 如果服务器和客户端支持都压缩, 则压缩信息传递; 
--concurrency=N, <span style="color: purple;">-c</span> N 并发量, 也就是模拟多少个客户端同时执行select. 可指定多个值, 以逗号或者--delimiter参数指定的值做为分隔符; 
--engine=engine_name, <span style="color: purple;">-e</span> engine_name 创建测试表所使用的存储引擎, 可指定多个; 
--iterations=N, <span style="color: purple;">-i</span> N 测试执行的迭代次数; 
--detach=N 执行N条语句后断开重连; 
--only-print 只打印测试语句而不实际执行; 
 
连接参数: 

<span style="color: purple;">-u</span>, --user=name User <span style="color: #a52a2a;">for</span> login <span style="color: #a52a2a;">if</span> not current user. 
<span style="color: purple;">-p</span>, --password=name Password to use when connecting to server. 如果密码没有给,会通过tty终端请求。 
<span style="color: purple;">-h</span>, --host=name Connect to host. 
-P, --port= Port number to use <span style="color: #a52a2a;">for</span> connection. 

需要说明的是 –concurrency 在实际测试调参中发现,该参数是个假并发参数。 并非是多个客户端并发,而是一个客户端进程中指定使用多个线程的参数。 增加该值并不能使压力上去,也许你发现了。增加线程数,有时候反而会使落到每一台mysql机器上的压力降下来。

实际测试中如果要压力上去,需要启动多个mysqlslap进程进行测试。

(3) 实例说明
在测试前用脚本批量处理了数据,生成不带cache的select语句

view plaincopy to clipboardprint?
<pre>select SQL_NO_CACHE url_key, value from structqa where url_key <span style="color: #a52a2a;">in</span> (5793176823383938934,1549359593866465909,46398175249572291 39,6858231871203830826);</pre> 

<pre>DB加缓存和不加缓存的压力大概是1.5倍。</pre> 

<pre>通过监控图可以看出单进程+cache 和 单进程不加cache的对比:图中是四台机器的曲线拟合,考虑到dbproxy分片的压力不均</pre> 
<pre><a href="/wp-content/uploads/2013/06/mysql+cache.png"></a> 
<pre><a href="/wp-content/uploads/2013/06/mysql+cache.png"><img title="mysql+cache" src="/wp-content/uploads/2013/06/mysql+cache-300x160.png" alt="" width="300" height="160"></a>     <a style="font-size: 1.5em;" href="/wp-content/uploads/2013/06/mysql-cache1.png"><img title="mysql-cache" src="/wp-content/uploads/2013/06/mysql-cache1-300x141.png" alt="" width="300" height="141"></a></pre> 
</pre> 

使用时候启动单个进程的语句如下:

<pre>/home/iknow/local/mysql/bin/mysqlslap  -u***** -p***** -h***.***.***.*** -P3300 --create-schema=**** --query=select_ddbs.sql --concurrency=2 --number-of-queries=6000000 --iterations=2000 --debug-info --engine=innodb ;</pre> 
参数说明: –create-schema 指明要测试的数据库,否则会报错 ./bin/mysqlslap: Error when connecting to server: 1045 Auth failed, check your username, password or db

–query 生成的sql语句的文件 –concurrency 使用两个线程处理 –number-of-queries 本次压力使用的query数目 –iterations 循环2000次,因为要压力一段时间,可以手动kill掉 –engine 是innodb的数据库引擎 –debug-info 会在执行结束的时候打印一些cpu和内存信息。

4. 性能测试

(1)性能因素
1,测试环境

如果是线下机器要尽可能与线上一致

2,测试数据

mysql分为带缓存和不带缓存的查询两种,线下构造不带缓存的请求

3,压力请求

(2)性能指标
【数据库性能指标】

QPS(TPS):每秒钟request/事务 数量
并发数: 系统同时处理的request/事务数
响应时间: 一般取平均响应时间

【系统性能指标】

CPU:
idle: 显示了cpu处在空闲状态的时间百分比
wa值:wa 列显示了IO等待所占用的CPU时间的百分比。
这里wa的参考值为30%,如果wa超过30%,说明IO等待严重,这可能是磁盘大量随机访问造成的,也可能磁盘或者磁盘访问控制器的带宽瓶颈造成的

内存: mysql不用过多关注内存,主要是读写操作,涉及到C模块的要特别关注下,内存泄露最直观的的表现就是内存随时间上涨。

IO: 关注下面的指标即可: 上面说的CPu的wa值,以及
util%: 一秒中有百分之多少的时间用于 I/O 操作,或者说一秒中有多少时间 I/O 队列是非空的.即 delta(use)/s/1000 (因为use的单位为毫秒)如果 %util 接近 100%,说明产生的I/O请求太多,I/O系统已经满负荷,该磁盘可能存在瓶颈.

(3) 性能场景
综合性能因素和性能的衡量指标,以及当前的测试目的,构造测试场景 需要模拟线上的场景,本次构造的场景

1,模拟线上小流量

-----简单压一下,看当前的系统性能指标,如果小流量都不行,说明系统存在严重的性能瓶颈。

2,模拟线上全流量

--- 全流量的模拟要细致,该测试出了测试全流量之外,还可以压力一晚上,查看系统稳定性,补充稳定性测试。

3, 模拟线上双倍流量

--考虑到峰值是普通流量的两倍,以及线上切机房的时候的流量

4,极限压力测试

需要特别跟DBA和RD确认当前机器没有对外提供服务,仅供测试使用,而且极限压力时间不宜过长,一般1~2小时左右

下面来看mysqlslap对MySQL进行压力测试

我解释一下一些常用的选项。
这里要注意的几个选项:
--concurrency代表并发数量,多个可以用逗号隔开,当然你也可以用自己的分隔符隔开,这个时候要用到--delimiter开关。
--engines代表要测试的引擎,可以有多个,用分隔符隔开。
--iterations代表要运行这些测试多少次。
--auto-generate-sql 代表用系统自己生成的SQL脚本来测试。
--auto-generate-sql-load-type 代表要测试的是读还是写还是两者混合的(read,write,update,mixed)
--number-of-queries 代表总共要运行多少次查询。每个客户运行的查询数量可以用查询总数/并发数来计算。比如倒数第二个结果2=200/100。
--debug-info 代表要额外输出CPU以及内存的相关信息。
--number-int-cols 代表示例表中的INTEGER类型的属性有几个。
--number-char-cols 意思同上。
--create-schema 代表自己定义的模式(在MySQL中也就是库)。
--query 代表自己的SQL脚本。
--only-print 如果只想打印看看SQL语句是什么,可以用这个选项。

现在来看一些我测试的例子。

1、用自带的SQL脚本来测试。
MySQL版本为5.1.23
[root@localhost ~]# mysqlslap --defaults-file=/usr/local/mysql-maria/my.cnf --concurrency=50,100,200 --iterations=1 --number-int-cols=4 --number-char-cols=35 --auto-generate-sql --auto-generate-sql-add-autoincrement --auto-generate-sql-load-type=mixed --engine=myisam,innodb --number-of-queries=200 --debug-info -uroot -p1 -S/tmp/mysql_3310.sock

Benchmark
        Running for engine myisam
        Average number of seconds to run all queries: 0.063 seconds
        Minimum number of seconds to run all queries: 0.063 seconds
        Maximum number of seconds to run all queries: 0.063 seconds
        Number of clients running queries: 50
        Average number of queries per client: 4

Benchmark
        Running for engine myisam
        Average number of seconds to run all queries: 0.070 seconds
        Minimum number of seconds to run all queries: 0.070 seconds
        Maximum number of seconds to run all queries: 0.070 seconds
        Number of clients running queries: 100
        Average number of queries per client: 2

Benchmark
        Running for engine myisam
        Average number of seconds to run all queries: 0.092 seconds
        Minimum number of seconds to run all queries: 0.092 seconds
        Maximum number of seconds to run all queries: 0.092 seconds
        Number of clients running queries: 200
        Average number of queries per client: 1

Benchmark
        Running for engine innodb
        Average number of seconds to run all queries: 0.115 seconds
        Minimum number of seconds to run all queries: 0.115 seconds
        Maximum number of seconds to run all queries: 0.115 seconds
        Number of clients running queries: 50
        Average number of queries per client: 4

Benchmark
        Running for engine innodb
        Average number of seconds to run all queries: 0.134 seconds
        Minimum number of seconds to run all queries: 0.134 seconds
        Maximum number of seconds to run all queries: 0.134 seconds
        Number of clients running queries: 100
        Average number of queries per client: 2

Benchmark
        Running for engine innodb
        Average number of seconds to run all queries: 0.192 seconds
        Minimum number of seconds to run all queries: 0.192 seconds
        Maximum number of seconds to run all queries: 0.192 seconds
        Number of clients running queries: 200
        Average number of queries per client: 1


User time 0.06, System time 0.15
Maximum resident set size 0, Integral resident set size 0
Non-physical pagefaults 5803, Physical pagefaults 0, Swaps 0
Blocks in 0 out 0, Messages in 0 out 0, Signals 0
Voluntary context switches 8173, Involuntary context switches 528


我来解释一下结果的含义。
拿每个引擎最后一个Benchmark示例。
对于INNODB引擎,200个客户端同时运行这些SQL语句平均要花0.192秒。相应的MYISAM为0.092秒。

2、用我们自己定义的SQL 脚本来测试。
这些数据在另外一个MySQL实例上。版本为5.0.45
先看一下这两个表的相关数据。
1)、总记录数。
mysql> select table_rows as rows from information_schema.tables where table_schema='t_girl' and table_name='article';
+--------+
| rows   |
+--------+
| 296693 |
+--------+
1 row in set (0.01 sec)

mysql> select table_rows as rows from information_schema.tables where table_schema='t_girl' and table_name='category';
+------+
| rows |
+------+
| 113  |
+------+
1 row in set (0.00 sec)

2)、总列数。
mysql> select count(*) as column_total from information_schema.columns where table_schema = 't_girl' and table_name = 'article';
+--------------+
| column_total |
+--------------+
| 32           |
+--------------+
1 row in set (0.01 sec)

mysql> select count(*) as column_total from information_schema.columns where table_schema = 't_girl' and table_name = 'category';
+--------------+
| column_total |
+--------------+
| 9            |
+--------------+
1 row in set (0.01 sec)


3)、调用的存储过程
DELIMITER $$

DROP PROCEDURE IF EXISTS `t_girl`.`sp_get_article`$$

CREATE DEFINER=`root`@`%` PROCEDURE `sp_get_article`(IN f_category_id int,
 IN f_page_size int, IN f_page_no int
)
BEGIN
  set @stmt = 'select a.* from article as a inner join ';
  set @stmt = concat(@stmt,'(select a.aid from article as a ');
  if f_category_id != 0 then
    set @stmt = concat(@stmt,' inner join (select cid from category where cid = ',f_category_id,' or parent_id = ',f_category_id,') as b on a.category_id = b.cid');
  end if;
  if f_page_size >0 && f_page_no > 0 then
    set @stmt = concat(@stmt,' limit ',(f_page_no-1)*f_page_size,',',f_page_size);
  end if;
 
  set @stmt = concat(@stmt,') as b on (a.aid = b.aid)');
  prepare s1 from @stmt;
  execute s1;
  deallocate prepare s1;
  set @stmt = NULL;
END$$

DELIMITER ;
4)、我们用mysqlslap来测试
以下得这个例子代表用mysqlslap来测试并发数为25,50,100的调用存储过程,并且总共调用5000次。
[root@localhost ~]# mysqlslap --defaults-file=/usr/local/mysql-maria/my.cnf --concurrency=25,50,100 --iterations=1 --query='call t_girl.sp_get_article(2,10,1);' --number-of-queries=5000 --debug-info -uroot -p -S/tmp/mysql50.sock
Enter password:
Benchmark
        Average number of seconds to run all queries: 3.507 seconds
        Minimum number of seconds to run all queries: 3.507 seconds
        Maximum number of seconds to run all queries: 3.507 seconds
        Number of clients running queries: 25
        Average number of queries per client: 200
平均每个并发运行200个查询用了3.507秒。
Benchmark
        Average number of seconds to run all queries: 3.742 seconds
        Minimum number of seconds to run all queries: 3.742 seconds
        Maximum number of seconds to run all queries: 3.742 seconds
        Number of clients running queries: 50
        Average number of queries per client: 100

Benchmark
        Average number of seconds to run all queries: 3.697 seconds
        Minimum number of seconds to run all queries: 3.697 seconds
        Maximum number of seconds to run all queries: 3.697 seconds
        Number of clients running queries: 100
        Average number of queries per client: 50


User time 0.87, System time 0.33
Maximum resident set size 0, Integral resident set size 0
Non-physical pagefaults 1877, Physical pagefaults 0, Swaps 0
Blocks in 0 out 0, Messages in 0 out 0, Signals 0
Voluntary context switches 27218, Involuntary context switches 3100


看一下SHOW PROCESSLIST 结果
mysql> show processlist;
+------+------+--------------------+--------------------+---------+-------+--------------------+------------------------------------------------------------------------------------------------------+
| Id   | User | Host               | db                 | Command | Time  | State              | Info                                                                                                 |
+------+------+--------------------+--------------------+---------+-------+--------------------+------------------------------------------------------------------------------------------------------+
…………
| 3177 | root | %                  | t_girl             | Query   |     0 | NULL               | select a.* from article as a inner join (select a.aid from article as a  inner join (select cid from |
| 3178 | root | %                  | t_girl             | Query   |     0 | NULL               | select a.* from article as a inner join (select a.aid from article as a  inner join (select cid from |
| 3179 | root | %                  | t_girl             | Query   |     0 | NULL               | select a.* from article as a inner join (select a.aid from article as a  inner join (select cid from |
| 3181 | root | %                  | t_girl             | Query   |     0 | NULL               | select a.* from article as a inner join (select a.aid from article as a  inner join (select cid from |
| 3180 | root | %                  | t_girl             | Query   |     0 | NULL               | select a.* from article as a inner join (select a.aid from article as a  inner join (select cid from |
| 3182 | root | %                  | t_girl             | Query   |     0 | NULL               | select a.* from article as a inner join (select a.aid from article as a  inner join (select cid from |
| 3183 | root | %                  | t_girl             | Query   |     0 | NULL               | select a.* from article as a inner join (select a.aid from article as a  inner join (select cid from |
| 3187 | root | %                  | t_girl             | Query   |     0 | removing tmp table | select a.* from article as a inner join (select a.aid from article as a  inner join (select cid from |
| 3186 | root | %                  | t_girl             | Query   |     0 | NULL               | select a.* from article as a inner join (select a.aid from article as a  inner join (select cid from |
| 3194 | root | %                  | t_girl             | Query   |     0 | NULL               | select a.* from article as a inner join (select a.aid from article as a  inner join (select cid from |
| 3203 | root | %                  | t_girl             | Query   |     0 | NULL               | deallocate prepare s1                                                                                |
…………
| 3221 | root | %                  | t_girl             | Query   |     0 | NULL               | select a.* from article as a inner join (select a.aid from article as a  inner join (select cid from |
| 3222 | root | %                  | t_girl             | Query   |     0 | NULL               | select a.* from article as a inner join (select a.aid from article as a  inner join (select cid from |
| 3223 | root | %                  | t_girl             | Query   |     0 | NULL               | select a.* from article as a inner join (select a.aid from article as a  inner join (select cid from |
| 3224 | root | %                  | t_girl             | Query   |     0 | removing tmp table | select a.* from article as a inner join (select a.aid from article as a  inner join (select cid from |
| 3225 | root | %                  | t_girl             | Query   |     0 | NULL               | select a.* from article as a inner join (select a.aid from article as a  inner join (select cid from |
| 3226 | root | %                  | t_girl             | Query   |     0 | NULL               | select a.* from article as a inner join (select a.aid from article as a  inner join (select cid from |
+------+------+--------------------+--------------------+---------+-------+--------------------+------------------------------------------------------------------------------------------------------+
55 rows in set (0.00 sec)

上面的测试语句其实也可以这样写

[root@localhost ~]# mysqlslap --defaults-file=/usr/local/mysql-maria/my.cnf --concurrency=25,50,100 --iterations=1 --create-schema='t_girl' --query='call sp_get_article(2,10,1);' --number-of-queries=5000 --debug-info -uroot -p -S/tmp/mysql50.sock

小总结一下。
mysqlslap对于模拟多个用户同时对MySQL发起“进攻”提供了方便。同时详细的提供了“高负荷攻击MySQL”的详细数据报告。
而且如果你想对于多个引擎的性能。这个工具再好不过了。

打赏

打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

百分百源码网 建议打赏1~10元,土豪随意,感谢您的阅读!

共有3人阅读,期待你的评论!发表评论
昵称: 网址: 验证码: 点击我更换图片
最新评论

本文标签

广告赞助

能出一分力是一分吧!

订阅获得更多模板

本文标签

广告赞助

订阅获得更多模板