mysqlslap压力测试和线程池

目录

[1. mysqlslap介绍](#1. mysqlslap介绍)

[2. mysqlslap常用参数](#2. mysqlslap常用参数)

[3. 开始测试](#3. 开始测试)

[3.1 单线程](#3.1 单线程)

[3.2 多线程](#3.2 多线程)

[3.3 50和100个并发](#3.3 50和100个并发)

[3.4 迭代测试](#3.4 迭代测试)

4.结果解释

5.线程池

[5.1 开启线程池](#5.1 开启线程池)

[5.2 关于线程池的参数](#5.2 关于线程池的参数)


1. mysqlslap介绍

mysqlslap是一个诊断程序,旨在模拟客户端并发访问MySQL服务器,测试MySQL服务的负载,主要工作场景就是对数据库服务器做基准测试。

mysqlslap官方文档

MySQL :: MySQL 5.7 Reference Manual :: 4.5.8 mysqlslap --- A Load Emulation Client

2. mysqlslap常用参数

--auto-generate-sql, -a 自动生成测试表和数据,表示用mysqlslap工具自己生成的SQL脚本来测试并发压力。
--auto-generate-sql-load-type=type 测试语句的类型。代表要测试的环境是读操作还是写操作还是两者混合的。取值包括:read,key,write,update和mixed(默认)。
--auto-generate-sql-add-auto-increment 代表对生成的表自动添加auto_increment列,从5.1.18版本开始支持。
--number-char-cols=N, -x N 自动生成的测试表中包含多少个字符类型的列,默认1
--number-int-cols=N, -y N 自动生成的测试表中包含多少个数字类型的列,默认1
--number-of-queries=N 总的测试查询次数(并发客户数×每客户查询次数)
--query=name,-q 使用自定义脚本执行测试,例如可以调用自定义的一个存储过程或者sql语句来执行测试。
--create-schema 代表自定义的测试库名称,测试的schema,MySQL中schema也就是database。
--commint=N 多少条DML后提交一次。
--compress, -C 如果服务器和客户端支持都压缩,则压缩信息传递。
--concurrency=N, -c N 表示并发量,也就是模拟多少个客户端同时执行select。可指定多个值,以逗号或者--delimiter参数指定的值做为分隔符。例如:--concurrency=100,200,500。
--engine=engine_name, -e engine_name 代表要测试的引擎,可以有多个,用分隔符隔开。例如:--engines=myisam,innodb。
--iterations=N, -i N 测试执行的迭代次数,代表要在不同并发环境下,各自运行测试多少次。
--only-print 只打印测试语句而不实际执行。
--detach=N 执行N条语句后断开重连。
--debug-info, -T 打印内存和CPU的相关信息。

测试的过程需要生成测试表,插入测试数据,这个mysqlslap可以自动生成,默认生成一个mysqlslap的schema,如果已经存在则先删除。可以用--only-print来打印实际的测试过程,整个测试完成后不会在数据库中留下痕迹。

3. 开始测试

sbtest.sql是自己编写的压力测试脚本

3.1 单线程

[root@localhost soft]# mysqlslap -uroot -p123456 --query=stock.sql --number-of-queries=100000

3.2 多线程

[root@localhost soft]# mysqlslap -uroot -p123456 -c4 --query=sbtest.sql --number-of-queries=100000

3.3 50和100个并发

[root@localhost soft]# mysqlslap -uroot -p123456 -c50,100 --query=stock.sql --number-of-queries=100000
mysqlslap: [Warning] Using a password on the command line interface can be insecure.
Benchmark
	Average number of seconds to run all queries: 21.113 seconds
	Minimum number of seconds to run all queries: 21.113 seconds
	Maximum number of seconds to run all queries: 21.113 seconds
	Number of clients running queries: 50
	Average number of queries per client: 2000

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

3.4 迭代测试

50和100个并发,3次迭代测试,3次执行测试得到平均值

[root@localhost soft]# mysqlslap -uroot -p123456 -c50,100 --query=stock.sql --number-of-queries=100000 -i3
mysqlslap: [Warning] Using a password on the command line interface can be insecure.
Benchmark
	Average number of seconds to run all queries: 20.784 seconds
	Minimum number of seconds to run all queries: 20.439 seconds
	Maximum number of seconds to run all queries: 21.095 seconds
	Number of clients running queries: 50
	Average number of queries per client: 2000

Benchmark
	Average number of seconds to run all queries: 22.958 seconds
	Minimum number of seconds to run all queries: 22.471 seconds
	Maximum number of seconds to run all queries: 23.381 seconds
	Number of clients running queries: 100
	Average number of queries per client: 1000

4.结果解释

Benchmark
    #运行所有语句的平均秒数
	Average number of seconds to run all queries: 22.958 seconds
    #运行所有语句的最小秒数
	Minimum number of seconds to run all queries: 22.471 seconds
    #运行所有语句的最大秒数
	Maximum number of seconds to run all queries: 23.381 seconds
    #100并发
	Number of clients running queries: 100
    #每个客户端执行的语句数
	Average number of queries per client: 1000

当测试线程为4,8,16,32,64,128,256,512,1024时,线程为32 QPS达到最大,往后线程越多QPS越低,需要设置线程池,控制并发量

5.线程池

为了解决one-thread-per-connection(每个连接一个线程)存在的频繁创建和销毁大量线程以及高并发情况下msql吞吐量严重下降的问题,实现mysql在高并发环境依然能保持较高的性能。

Oracle和MariaDB都推出了ThreadPool方案,目前Oracle的Thread pool实现为Plugin方式,并且只添加到在Enterprise版本中,Percona移植了MariaDB的Thread pool功能,并做了进一步的优化。我的环境是基于Percona MySQL 5.7版本。

为了处理并发请求,MySQL提供了thread_handling 参数,用于控制线程的管理方式。它可以影响数据库的性能、吞吐量以及对并发请求的处理能力。在默认情况下,thread_handling 参数的值为one-thread-per-connection,即每个客户端连接都会分配一个独立的线程来处理。

常见的 thread_handling 参数取值(perconna mysql)

  1. one-thread-per-connection:每个客户端连接分配一个独立的线程来处理。这是默认的线程管理方式,适用于低并发的情况。在高并发的环境下,由于线程的创建和销毁开销较大,可能导致性能下降。

  2. one-thread-for-all-connections:所有客户端连接共享一个线程。这种方式适用于高并发的应用场景,可以降低线程创建和销毁的开销,提高数据库的吞吐量。不过,由于只有一个线程处理所有的连接,可能会导致请求处理的延迟增加。

  3. pool-of-threads:为客户端连接维护一个线程池,连接请求会被分配到池中的空闲线程进行处理。这种方式适用于中等并发的场景,可以在一定程度上平衡线程的创建和销毁开销与请求处理的延迟。

5.1 开启线程池

perconna mysql配置文件添加如下参数,重启mysql使配置生效

[root@localhost ~]# vi /etc/my.cnf
[mysqld]
thread_handling = pool-of-threads

5.2 关于线程池的参数

(root@localhost) [(none)]> show variables like 'thread%';
+-------------------------------+-----------------+
| Variable_name                 | Value           |
+-------------------------------+-----------------+
| thread_cache_size             | 13              |
| thread_handling               | pool-of-threads |
| thread_pool_high_prio_mode    | transactions    |
| thread_pool_high_prio_tickets | 4294967295      |
| thread_pool_idle_timeout      | 60              |
| thread_pool_max_threads       | 100000          |
| thread_pool_oversubscribe     | 3               | #group中的最大线程数,每个group的最大线程数为thread_pool_oversubscribe+1
| thread_pool_size              | 4               | #线程池的Group的数量,默认为系统CPU的个数
| thread_pool_stall_limit       | 500             |
| thread_stack                  | 262144          | #每个线程堆栈大小
| thread_statistics             | OFF             | #
+-------------------------------+-----------------+
  • thread_pool_size

该参数是设置线程池的Group的数量,默认为系统CPU的个数,充分利用CPU资源。

  • thread_pool_oversubscribe

该参数设置group中的最大线程数,每个group的最大线程数为thread_pool_oversubscribe+1,注意listener线程不包含在内。

  • thread_pool_high_prio_mode

高优先级队列的控制参数,有三个值(transactions/statements/none),默认是transactions,三个值的含义如下:

transactions:对于已经启动事务的语句放到高优先级队列中,不过还取决于后面的thread_pool_high_prio_tickets参数。

statements:这个模式所有的语句都会放到高优先级队列中,不会使用到低优先级队列。

none:这个模式不使用高优先级队列。

  • thread_pool_high_prio_tickets

该参数控制每个连接最多语序多少次被放入高优先级队列中,默认为4294967295,注意这个参数只有在thread_pool_high_prio_mode为transactions的时候才有效果。

  • thread_pool_idle_timeout

worker线程最大空闲时间,默认为60秒,超过限制后会退出。

  • thread_pool_max_threads

该参数用来限制线程池最大的线程数,超过该限制后将无法再创建更多的线程,默认为100000。

  • thread_pool_stall_limit

该参数设置timer线程的检测group是否异常的时间间隔,默认为500ms。

相关推荐
测试杂货铺2 小时前
Jmeter压测实战:Jmeter二次开发之自定义函数
自动化测试·软件测试·测试工具·jmeter·职场和发展·测试用例·压力测试
字节程序员9 小时前
四种自动化测试模型实例及优缺点详解
开发语言·javascript·ecmascript·集成测试·压力测试
waicsdn_haha17 小时前
Postman最新详细安装及使用教程【附安装包】
测试工具·api·压力测试·postman·策略模式·get·delete
测试杂货铺1 天前
如何用postman做接口自动化测试及完美的可视化报告?
自动化测试·软件测试·测试工具·职场和发展·jenkins·压力测试·postman
字节程序员1 天前
接口自动化测试实战经验分享,测试用例也能自动生成
数据库·测试用例·压力测试
群联云防护小杜2 天前
服务器压力测试怎么做
运维·服务器·网络协议·tcp/ip·阿里云·压力测试
小张认为的测试2 天前
Linux性能监控命令_nmon 安装与使用以及生成分析Excel图表
linux·服务器·测试工具·自动化·php·excel·压力测试
字节程序员2 天前
Jmeter分布式压力测试
分布式·jmeter·压力测试
互联网杂货铺3 天前
几个常见的Jmeter压测问题
自动化测试·软件测试·测试工具·jmeter·职场和发展·测试用例·压力测试
字节程序员4 天前
使用JUnit进行集成测试
jmeter·junit·单元测试·集成测试·压力测试