• mysqlslap压力测试和线程池


    目录

    1. mysqlslap介绍

    2. mysqlslap常用参数

    3. 开始测试

    3.1 单线程

    3.2 多线程 

    3.3 50和100个并发

    3.4 迭代测试 

    4.结果解释

    5.线程池

    5.1 开启线程池

    5.2 关于线程池的参数


    1. mysqlslap介绍

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

    mysqlslap官方文档

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

    2. mysqlslap常用参数

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

    1. [root@localhost soft]# mysqlslap -uroot -p123456 -c50,100 --query=stock.sql --number-of-queries=100000
    2. mysqlslap: [Warning] Using a password on the command line interface can be insecure.
    3. Benchmark
    4. Average number of seconds to run all queries: 21.113 seconds
    5. Minimum number of seconds to run all queries: 21.113 seconds
    6. Maximum number of seconds to run all queries: 21.113 seconds
    7. Number of clients running queries: 50
    8. Average number of queries per client: 2000
    9. Benchmark
    10. Average number of seconds to run all queries: 21.445 seconds
    11. Minimum number of seconds to run all queries: 21.445 seconds
    12. Maximum number of seconds to run all queries: 21.445 seconds
    13. Number of clients running queries: 100
    14. Average number of queries per client: 1000

    3.4 迭代测试 

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

    1. [root@localhost soft]# mysqlslap -uroot -p123456 -c50,100 --query=stock.sql --number-of-queries=100000 -i3
    2. mysqlslap: [Warning] Using a password on the command line interface can be insecure.
    3. Benchmark
    4. Average number of seconds to run all queries: 20.784 seconds
    5. Minimum number of seconds to run all queries: 20.439 seconds
    6. Maximum number of seconds to run all queries: 21.095 seconds
    7. Number of clients running queries: 50
    8. Average number of queries per client: 2000
    9. Benchmark
    10. Average number of seconds to run all queries: 22.958 seconds
    11. Minimum number of seconds to run all queries: 22.471 seconds
    12. Maximum number of seconds to run all queries: 23.381 seconds
    13. Number of clients running queries: 100
    14. Average number of queries per client: 1000

    4.结果解释

    1. Benchmark
    2. #运行所有语句的平均秒数
    3. Average number of seconds to run all queries: 22.958 seconds
    4. #运行所有语句的最小秒数
    5. Minimum number of seconds to run all queries: 22.471 seconds
    6. #运行所有语句的最大秒数
    7. Maximum number of seconds to run all queries: 23.381 seconds
    8. #100并发
    9. Number of clients running queries: 100
    10. #每个客户端执行的语句数
    11. 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使配置生效

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

    5.2 关于线程池的参数

    1. (root@localhost) [(none)]> show variables like 'thread%';
    2. +-------------------------------+-----------------+
    3. | Variable_name | Value |
    4. +-------------------------------+-----------------+
    5. | thread_cache_size | 13 |
    6. | thread_handling | pool-of-threads |
    7. | thread_pool_high_prio_mode | transactions |
    8. | thread_pool_high_prio_tickets | 4294967295 |
    9. | thread_pool_idle_timeout | 60 |
    10. | thread_pool_max_threads | 100000 |
    11. | thread_pool_oversubscribe | 3 | #group中的最大线程数,每个group的最大线程数为thread_pool_oversubscribe+1
    12. | thread_pool_size | 4 | #线程池的Group的数量,默认为系统CPU的个数
    13. | thread_pool_stall_limit | 500 |
    14. | thread_stack | 262144 | #每个线程堆栈大小
    15. | thread_statistics | OFF | #
    16. +-------------------------------+-----------------+
    • 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。

  • 相关阅读:
    【Java面试】说一下你对CompletableFuture的理解
    牛客刷题<25>输入序列连续的序列检测
    椭圆曲线离散对数问题以及求解
    如何成就更高远控帧率和流畅度?向日葵SADDC算法浅析
    实现一个简单的Database1
    k8s二进制安装
    java之单元测试与注解与枚举
    4.2串的模式匹配(含KMP算法)
    飞睿智能高精度、低功耗测距,无线室内定位UWB芯片如何改变智能家居
    中间件 | Kafka - [安装 & 配置 & 启动]
  • 原文地址:https://blog.csdn.net/zj88189748/article/details/137773639