Mysql压力测试工具

Mysql压力测试工具

Mysqlslap简介

mysqlslap:来自于 mariadb 包,测试的过程默认生成一个 mysqlslap 的 schema, 生成测试表 t1,查询和插入测试数据,mysqlslap 库自动生成,如果已经存在则先删除。用–only-print 来打印实际的测试过程,整个测试完成后不会在数据库中留下痕迹 使用格式

mysqlslap 示例

mysqlslap 示例

#单线程测试
mysqlslap -a -uroot -pmagedu
#多线程测试。使用--concurrency来模拟并发连接
mysqlslap -a -c 100 -uroot -pmagedu
#迭代测试。用于需要多次执行测试得到平均值
mysqlslap -a -i 10 -uroot -pmagedu
mysqlslap ---auto-generate-sql-add-autoincrement -a
mysqlslap -a --auto-generate-sql-load-type=read
mysqlslap -a --auto-generate-secondary-indexes=3
mysqlslap -a --auto-generate-sql-write-number=1000
mysqlslap --create-schema world -q "select count(*) from City”
mysqlslap -a -e innodb -uroot -pmagedu
mysqlslap -a --number-of-queries=10 -uroot -pmagedu

#测试同时不同的存储引擎的性能进行对比
mysqlslap -a --concurrency=50,100 --number-of-queries 1000 --iterations=5 --engine=myisam,innodb --debug-info -uroot -pmagedu
#执行一次测试,分别50和100个并发,执行1000次总查询
mysqlslap -a --concurrency=50,100 --number-of-queries 1000 --debug-info -uroot -pmagedu
#50和100个并发分别得到一次测试结果(Benchmark),并发数越多,执行完所有查询的时间越长。为了准确起见,可以多迭代测试几次
mysqlslap -a --concurrency=50,100 --number-of-queries 1000 --iterations=5 --debug-info -uroot -pmagedu
--concurrency代表并发数量,多个可以用逗号隔开,concurrency=10,50,100, 并发连接线程数分别是10、50、100个并发。
--engines代表要测试的引擎,可以有多个,用分隔符隔开
--iterations代表要运行这些测试多少次
--auto-generate-sql 代表用系统自己生成的SQL脚本来测试
--auto-generate-sql-load-type 代表要测试的是读还是写还是两者混合的(read,write,update,mixed)
--number-of-queries 代表总共要运行多少次查询。每个客户运行的查询数量可以用查询总数/并发数来计算
--debug-info 代表要额外输出CPU以及内存的相关信息
--number-int-cols :创建测试表的 int 型字段数量
--auto-generate-sql-add-autoincrement : 代表对生成的表自动添加auto_increment列,从5.1.18版本开始
--number-char-cols 创建测试表的 char 型字段数量
--create-schema 测试的schema,MySQL中schema也就是database
--query  使用自定义脚本执行测试,例如可以调用自定义的一个存储过程或者sql语句来执行测试
--only-print 如果只想打印看看SQL语句是什么,可以用这个选项

语句

mysqlslap --concurrency=500,600  --iterations 10 -a  --auto-generate-sql-add-autoincrement --engine=innodb --number-of-queries=10000 -h'localhost' -uroot -pP@ssw0rd123

–concurrency=500,600 指定同时有 500 个和600客户端连接

--iterations 10 指定运行这些测试10次

--auto-generate-sql-add-autoincrement 代表对生成的表自动添加auto_increment列,从5.1.18版本开始

--engines=innodb  要测试innodb引擎,可以有多个,用分隔符隔开,如 --engines=myisam,innodb

–number-of-queries=10000 指定总的测试查询次数(并发客户端数 * 每个客户端的查询次数)

sysbench简介

sysbench 是一个开源的、模块化的、跨平台的多线程性能测试工具,可以用来进行 CPU、内存、磁盘 I/O、线程、数据库的性能测试。目前支持的数据库有 MySQL、Oracle 和 PostgreSQL

Linux安装sysbench

安装方式有两种,一种是通过 yum/apt 等来安装,另一种自己下载源码包来安装,笔者这里采用的是 centos , 采用 yum 安装

sysbench 的源码包下载地址

  • 通过yum安装如下
设置yum repo仓库
curl -s https://packagecloud.io/install/repositories/akopytov/sysbench/script.rpm.sh | sudo bash
安装
sudo yum -y install sysbench
查看版本
sysbench --version

数据库测试用例准备

需要测试的是Mysql,我们需要在数据库上创建一个专门用来测试的库

mysql -uroot -pP@ssw0rd123 -e 'create database test'

通过 sysbench 创建 20 个测试表,每个表中创建 100 万数据,再通过 10 个线程对测试库发起访问,持续 5 分钟,对其进行压测

语句

sysbench --db-driver=mysql --time=300 --threads=10 --report-interval=1 --mysql-host=localhost --mysql-port=3306 --mysql-user=root --mysql-password=P@ssw0rd123 --mysql-db=test --tables=20 --table_size=1000000 oltp_read_write --db-ps-mode=disable prepare
上面命令的参数说明:
--db-driver=mysql : 表示数据库的驱动类型,我们使用的是 MySQL 所以填 mysql , 如果使用 Oracle 则填写相应的 oracle
--time=300 : 这个参数表示持续访问的时间 300 秒
--threads=10 : 表示使用 10 个线程模拟并发访问
--report-interval=1 : 表示每隔一秒输出以此压测情况
--mysql-host=localhost --mysql-port=3306 --mysql-user=root --mysql-password=P@ssw0rd123 : 这一块的配置,就是基本的数据库链接信息,指定数据库 IP ,端口,账号密码
--mysql-db=test --tables=20 --table_size=1000000 : 这三个参数设置,表示指定测试的库为 test , 同时在这个库中构建 20 个表,并且每个表中构建出 100 万条测试数据,表的名字会类似 sbtest1,sbtest2 这种格式
oltp_read_write : 表示执行 oltp 数据库的读写测试
--db-ps-mode=disable : 禁止 ps 模式
prepare : 表示按照命令设置去构建出我们的数据,也就是对前面所有命令的执行方案

全方位测试

综合读写测试

测试数据库的综合读写 TPS , 使用 oltp_read_write 模式

sysbench --db-driver=mysql --time=300 --threads=10 --report-interval=1 --mysql-host=localhost --mysql-port=3306 --mysql-user=root --mysql-password=P@ssw0rd123 --mysql-db=test --tables=20 --table_size=1000000 oltp_read_write --db-ps-mode=disable run
注意:命令最后不再是 之前的 prepare,这里是 run ,表示运行压测,前面的是准备数据
上面是直接输出到控制台,我们也可以将其全部记录在文件中,通过管道,| tee /tmp/mysysbench.log 整个命令如下:
sysbench --db-driver=mysql --time=300 --threads=10 --report-interval=1 --mysql-host=localhost --mysql-port=3306 --mysql-user=root --mysql-password=P@ssw0rd123 --mysql-db=test --tables=20 --table_size=1000000 oltp_read_write --db-ps-mode=disable run | tee /tmp/mysysbench.log

只读性能测试

测试数据库的只读性能,使用 oltp_read_only 模式

sysbench --db-driver=mysql --time=300 --threads=10 --report-interval=1 --mysql-host=localhost --mysql-port=3306 --mysql-user=root --mysql-password=P@ssw0rd123 --mysql-db=test --tables=20 --table_size=1000000 oltp_read_only --db-ps-mode=disable run
通过管道将其全部记录在文件中,| tee /tmp/mysysbench.log 整个命令如下:
sysbench --db-driver=mysql --time=300 --threads=10 --report-interval=1 --mysql-host=localhost --mysql-port=3306 --mysql-user=root --mysql-password=P@ssw0rd123 --mysql-db=test --tables=20 --table_size=1000000 oltp_read_only --db-ps-mode=disable run | tee /tmp/read.log

删除性能测试

测试数据库的删除性能,使用模式:oltp_delete模式

sysbench --db-driver=mysql --time=300 --threads=10 --report-interval=1 --mysql-host=localhost --mysql-port=3306 --mysql-user=root --mysql-password=P@ssw0rd123 --mysql-db=test --tables=20 --table_size=1000000 oltp_delete --db-ps-mode=disable run
通过管道将其全部记录在文件中,| tee /tmp/mysysbench.log 
sysbench --db-driver=mysql --time=300 --threads=10 --report-interval=1 --mysql-host=localhost --mysql-port=3306 --mysql-user=root --mysql-password=P@ssw0rd123 --mysql-db=test --tables=20 --table_size=1000000 oltp_delete --db-ps-mode=disable run | tee /tmp/delete.log

更新索引字段测试

测试数据库的更新索引字段的性能,使用模式:oltp_update_index

sysbench --db-driver=mysql --time=300 --threads=10 --report-interval=1 --mysql-host=localhost --mysql-port=3306 --mysql-user=root --mysql-password=P@ssw0rd123 --mysql-db=test --tables=20 --table_size=1000000 oltp_update_index --db-ps-mode=disable run | tee /tmp/indexes.log 
通过管道将其全部记录在文件中,| tee /tmp/indexes.log 
sysbench --db-driver=mysql --time=300 --threads=10 --report-interval=1 --mysql-host=localhost --mysql-port=3306 --mysql-user=root --mysql-password=P@ssw0rd123 --mysql-db=test --tables=20 --table_size=1000000 oltp_update_index --db-ps-mode=disable run | tee /tmp/indexes.log 

更改非索引字段测试

测试数据库中更新非索引字段的性能,使用模式:oltp_update_non_index

sysbench --db-driver=mysql --time=300 --threads=10 --report-interval=1 --mysql-host=localhost --mysql-port=3306 --mysql-user=root --mysql-password=P@ssw0rd123 --mysql-db=test --tables=20 --table_size=1000000 oltp_update_non_index --db-ps-mode=disable run
通过管道将其全部记录在文件中同上

插入性能测试

测试数据库的数据插入性能,使用模式:oltp_insert

sysbench --db-driver=mysql --time=300 --threads=10 --report-interval=1 --mysql-host=localhost --mysql-port=3306 --mysql-user=root --mysql-password=P@ssw0rd123 --mysql-db=test --tables=20 --table_size=1000000 oltp_insert --db-ps-mode=disable run
通过管道将其全部记录保存文件中同上

写入性能测试

测试数据库的写入性能,使用模式:oltp_write_only

sysbench --db-driver=mysql --time=300 --threads=10 --report-interval=1 --mysql-host=localhost --mysql-port=3306 --mysql-user=root --mysql-password=P@ssw0rd123 --mysql-db=test --tables=20 --table_size=1000000 oltp_write_only --db-ps-mode=disable run
通过管道将其全部记录保存文件中同上

清理数据

前面命令进行了各种测试,在测试完之后我们可以通过下面的 cleanup 命令来清除构建的测试数据

sysbench --db-driver=mysql --time=300 --threads=10 --report-interval=1 --mysql-host=localhost --mysql-port=3306 --mysql-user=root --mysql-password=P@ssw0rd123 --mysql-db=test --tables=20 --table_size=1000000 oltp_read_write --db-ps-mode=disable cleanup

压测结果分析

通过上面的命令我们可以全方位的得到测试的结果,我们直接每个一秒输出一次结果,在控制台会输出类似下面的东西:

[ 200s ] thds: 10 tps: 1166.06 qps: 6979.26 (r/w/o: 0.00/3978.09/3001.17) lat (ms,95%): 24.83 err/s: 0.00 reconn/s: 0.00

解释一下其中的含义,首先 [200s] 表示这是在第 200 秒的时候输出的一段压测统计结果,其他字段如下:

  • thds:10 : 表示当前有 10 个线程正在压测
  • tps:1166.06 : 表示当前每秒执行了 1166.06个事务
  • qps:6979.26: 表示当前每秒可以执行 6979.26 个请求
  • (r/w/o: 0.00/3978.09/3001.17) : 表示在每秒 6979.26 个请求中,有 0 个读请求,3978.09 个写请求,3001.17 个其他请求,其实就是对 qps 的细化
  • lat (ms,95%): 24.83:表示 95% 的请求的延迟都在 24.83 毫秒以下
  • err/s: 0.00 reconn/s: 0.00:表示有 0 个请求失败,发生了 0 次的网络重连

在压测结束后会输出一个总的压测结果,如下

SQL statistics:
    queries performed:
        read:                             0   //这是说在300s的压测期间执行了0次的读请求
        write:                           607431  //这是说在压测期间执行了60多万次写的请求
        other:                           1375676  //这是说在压测期间执行了137万次的其他请求
        total:                           1983107  //这是说一共执行了198万多次的请求
        //这是说一共执行了198万多次的事务,每秒执行6610+请求
    transactions:                        1983107 (6610.21 per sec.)
    //这是说一共执行了198万多次的事务,每秒执行6610+请求
    queries:                             1983107 (6610.21 per sec.)
    ignored errors:                      0      (0.00 per sec.)
    reconnects:                          0      (0.00 per sec.)
//下面是一共执行了300s的压测,执行了19万+的事务
General statistics:
    total time:                          300.0047s
    total number of events:              1983107

Latency (ms):
         min:                                    0.04 //请求中延迟最小的是0.04ms
         avg:                                    1.51 //所有请求平均延迟是1.51ms
         max:                                   69.55 //延迟最大的请求时69.55ms
         95th percentile:                        7.17 //95%的请求延迟都在7.17ms
         sum:                              2996920.73

Threads fairness:
    events (avg/stddev):           198310.7000/596.05
    execution time (avg/stddev):   299.6921/0.00

常用监控命令

  • 在压测过程中我们要时刻关注服务器的 CPU 、磁盘 I/O 、网络负载等信息,一旦发现任何一个超出一定负荷,则不适合再继续加大线程数来压测了
  • 一定要注意,压测的过程是要保证机器各项指标在正常范围内的最大负载,而不是我们不断的增大 sysbench 的线程数,不关系其他指标,这样即使机器每秒抗住了很高的 qps , 但是这时候的机器已经是满负荷运行了,内存,cpu,网络带宽等都几乎被打满,这种情况机器随时可能挂掉,这时候的测压就没有什么代表性了,因为你不可能在生产者让它达到这样的负荷

观察 CPU 的的负荷

  • 在 Linux 下最常见的命令就是 top 命令,可以输出详细的情况,如下:
  • 对于上面的输出,我们详细来分析一下,首先看第一行的输出

![](/Users/admin/Library/Application Support/typora-user-images/image-20221019174146640.png)

17:41:42:表示当前的时间
up 5 days:表示已经运行了多长时间
3 user:当前机器有几个用户在使用
load average: 0.77, 2.08, 2.41:这是核心,表示 CPU 在 一分钟、五分钟、十五分钟 内的平均负载情况,简单解释一下,我是一个四核的 CPU ,此时如果我们的 CPU 负载是 0.15 ,那么表示这四个核心中连一个核心都没使用满,表明整体比较空闲;如果整个负载是 1,则表示四个核中有一个已经使用的比较繁忙了,但是其他三个还是比较空闲的;如果负载是 4,则说明当前四个核心都处于跑满的状态,如果负载大于四,假设 6,那说明四核的 CPU 被超负荷使用也无法处理完当前的任务,有很多线程与要等待 CPU 资源

内存的使用情况

KiB Mem : 7990072 total, 124656 free, 1085436 used, 6779980 buff/cache

  • 7990072total : 总的内存,差不多 8G
  • 124656 free:当前可用内存,1G
  • 1085436 used:已使用内存
  • 6779980 buff/cache:用于 IO 缓冲的内存

磁盘 IO 检测

在检测 CPU 和内存使用的同时,我们还需要检测磁盘的使用状况,包括 IO 吞吐量,IOPS 等信息主要通过 dstat 命令来查看,如果系统没有装可以通过 yum install dstat 进行安装**执行`` dstat -d` 命令,可以看到如下:

[root@mysql ~] dstat -d
-dsk/total-
 read  writ
 19M  584k
 15M  206k
 12M  166k
 18M  166k
 18M  166k
 12M  166k
 12M  166k
 66M  166k
 23M  166k
 18M  166k
 18M  166k
 12M  166k
 12M  166k
 66M  166k
 12M  166k
 12M  166k
 12M  166k

上面显示的内存可以看到存储的 IO 吞吐量的详细数据,每秒读 19M 数据,每秒写 166K 的数据,这个吞吐量并不是很高,一般普通的机械硬盘可以到达上百 MB 的读写量

**查看 IOPS **

使用命令 dstat -r 来查看 IOPS 的情况

[root@mysql ~] dstat -r
--io/total-
 read  writ
0.05  15.4
   0   756
   0   688
   0   577
   0   635
   0   719
   0   618
   0   593
   0   656
   0   662
   0   692
   0   770
   0   643
   0   741
   0   697
   0   621
   0   756
   0   721
   0   759

如上面结果可以看到,读写分别的 IOPS 的值,也就是说随即磁盘读取 / 写入每秒多少次通常来说磁盘的读写每秒在两三百次是可接受的

网卡流量检测

通过 dstat -n 来查看网卡的具体流量情况

[root@mysql ~] dstat -n
-net/total-
 recv  send
   0     0
  66B  206B
  66B  166B
 126B  166B
 186B  166B
 126B  166B
  66B  166B
  66B  166B
  66B  166B
  66B  166B
  66B  166B
 158B  166B
 158B  166B
 158B  166B
 126B  166B
 352B  166B

网卡每秒接收和发送的数据量。通常来说如果我们电脑是千兆网卡,那么每秒钟网卡的总流量也就在 100M 左右,甚至更低

BENCHMARK简介

BENCHMARK 是 MySQL 中的内置函数,而不是针对数据库的基准测试工具。

这个函数的功能是用来测试数据库中特定表达式的执行时间的,基本语法结构是:

BENCHMARK (loop_count, expr),其中 loop_count 是循环次数,expr 是要循环的表达式。这个函数的返回值通常是 0,并且会在返回中附带一行来指出执行时间。

可以看到执行 500000000 次 2*3 一共用了 9.16 秒 //这个可以验证Mysql慢查询 其他不建议

mysql> select benchmark(500000000,2*3);
+--------------------------+
| benchmark(500000000,2*3) |
+--------------------------+
|                        0 |
+--------------------------+
1 row in set (9.16 sec)
posted @ 2022-10-20 10:56  我真的兔了  阅读(771)  评论(0编辑  收藏  举报