使用MariaDB线程池提高MySQL的扩展性

news2024/11/16 3:17:01

在这里插入图片描述

摘要:MySQL的线程池能够有效地解决大量短连接的性能问题,大幅提高MySQL数据库的扩展性。但官方MySQL的线程池在收费的企业版中才有,免费的社区版中没有这个功能,这里介绍MairaDB的线程池。

关于作者,姚远:

  • Oracle ACE(Oracle和MySQL数据库方向)
  • 华为云MVP
  • 《MySQL 8.0运维与优化》的作者
  • 中国唯一一位Oracle高可用大师
  • 拥有包括 Oracle 10g和12c OCM在内的20+数据库相关认证
  • 曾任IBM公司数据库部门经理
  • 现在一家第三方公司任首席数据库专家,服务2万+客户

线程池的说明

MySQL数据库默认是为每一个连接分配一个服务端的线程进行处理,在一个连接数少并且运行稳定的生产系统中,这通常不会有什么问题。但在下面两种情况下,会遇到性能问题
前端发起的连接数过多,造成服务端生成大量的线程,消耗了大量的CPU资源,而这些连接大部分时候处于sleep的状态,后端线程空转。
瞬间增加大量短连接的会话,造成服务端不断生成线程,高峰过后又有大量线程被销毁,这样会因为context-switch造成CPU性能大幅下降。
对于这种情况通常采用线程池的方法进行解决,线程池会预先创建一定数量的线程,当有连接的请求需要处理时,MySQL会从线程池中分配一条线程进行处理,到处理完成后,这条线程又会回到线程池中,下次它可能会被分配处理另外一个连接到请求。

单连接对单线程和线程池的对比

线程类型适用场景线程执行单位
one-thread-per-connection连接数不多而且稳定连接
pool-of-threads高并发、短连接SQL语句

需要说明的是:服务端的线程池和客户端的连接池不是一回事。

连接池和线程池的对比

池的类型优化目标功能
Connection Pool客户端减少建立连接的时间和连接占用的资源
Thread Pool服务端减少线程重复建立和context-switch的资源

线程池在MySQL的企业版才有,社区版没有,下面的图说明了MySQL企业版通过线程池有效地提高MySQL扩展性
(https://www.mysql.com/products/enterprise/scalability.html)
在这里插入图片描述
Oracle声称线程池让MySQL的扩展性提高了60倍。遗憾的是免费的社区版中并没有这个功能,但免费的Percona和MariaDB中都有这个功能。这里以MariaDB为例介绍线程池的作用。

安装MariaDB

在MariaDB的官方网站上可以下载安装包,在Linux上的安装方法如下:

groupadd mysql
useradd -g mysql mysql
cd /usr/local
tar -zxvpf /path-to/mariadb-VERSION-OS.tar.gz
ln -s mariadb-VERSION-OS mysql
cd mysql
./scripts/mysql_install_db --user=mysql
chown -R root .
chown -R mysql data

启动MariaDB:

root@yaoyuan ~# /usr/local/mysql/bin/mysqld_safe  --user=mysql &

登陆MariaDB,root或者mysql用户登陆不需要密码

[mysql@yuan ~]$ mysql
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 5
Server version: 10.6.11-MariaDB MariaDB Server


Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.


Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.


MariaDB [(none)]> \s
--------------
mysql  Ver 15.1 Distrib 10.6.11-MariaDB, for linux-systemd (x86_64) using readline 5.1


Connection id:    5
Current database:  
Current user:    mysql@localhost
SSL:      Not in use
Current pager:    stdout
Using outfile:    ''
Using delimiter:  ;
Server:      MariaDB
Server version:    10.6.11-MariaDB MariaDB Server
Protocol version:  10
Connection:    Localhost via UNIX socket
Server characterset:  latin1
Db     characterset:  latin1
Client characterset:  utf8mb3
Conn.  characterset:  utf8mb3
UNIX socket:    /tmp/mysql.sock
Uptime:      1 hour 34 min 51 sec


Threads: 1  Questions: 47  Slow queries: 0  Opens: 37  Open tables: 30  Queries per second avg: 0.008
--------------

配置线程池

控制线程池的主要参数是thread_handling,这个参数的默认值one-thread-per-connection,就是一个连接对应一个线程。

MariaDB [information_schema]> show variables like 'thread_h%';
+-----------------+---------------------------+
| Variable_name   | Value                     |
+-----------------+---------------------------+
| thread_handling | one-thread-per-connection |
+-----------------+---------------------------+
1 row in set (0.001 sec)

激活线程池的方法是在参数文件中把这个参数配置成pool-of-threads:

[mariadb]
...
thread_handling=pool-of-threads

启动后可以看到线程池的相关参数的默认值

MariaDB [(none)]> show variables like 'thread%';
+--------------------------------+-----------------+
| Variable_name                  | Value           |
+--------------------------------+-----------------+
| thread_cache_size              | 151             |
| thread_handling                | pool-of-threads |
| thread_pool_dedicated_listener | OFF             |
| thread_pool_exact_stats        | OFF             |
| thread_pool_idle_timeout       | 60              |
| thread_pool_max_threads        | 65536           |
| thread_pool_oversubscribe      | 3               |
| thread_pool_prio_kickup_timer  | 1000            |
| thread_pool_priority           | auto            |
| thread_pool_size               | 1               |
| thread_pool_stall_limit        | 500             |
| thread_stack                   | 299008          |
+--------------------------------+-----------------+
12 rows in set (0.075 sec)

hread_pool_size:线程池的大小,这个参数的默认值由cpu的个数决定,默认是CPU的个数,这里是虚拟机,只有一个虚拟CPU,因此是1。
thread_pool_max_threads:线程池中的最大线程,默认65536。

测试线程池

测试环境是只有一个虚拟CPU的虚拟机。

参数配置 /etc/my.cnf


[mariadb]
thread_handling=pool-of-threads
thread_pool_size=10
max_connections=1000
thread_pool_max_threads=50

创建1万条记录的表

[mysql@yuan ~]$ mysqlslap --create="create table table_a(col1 int primary key auto_increment, col2 varchar(255))" --query="insert into table_a(col2) values(md5(rand()))" --concurrency=10 --number-of-queries=10000 --no-drop
Benchmark
  Average number of seconds to run all queries: 1.982 seconds
  Minimum number of seconds to run all queries: 1.982 seconds
  Maximum number of seconds to run all queries: 1.982 seconds
  Number of clients running queries: 10
  Average number of queries per client: 1000

并发500个连接进行测试

[mysql@yuan ~]$  mysqlslap --query='select count(*) from table_a where col2<>md5(rand())' --concurrency=500 --iterations=10
Benchmark
  Average number of seconds to run all queries: 7.809 seconds
  Minimum number of seconds to run all queries: 7.762 seconds
  Maximum number of seconds to run all queries: 8.033 seconds
  Number of clients running queries: 500
  Average number of queries per client: 1

每个SQL语句运行的时间大约是7秒多,实际上这是因为并发造成context-switch而影响了执行的效率,如果是单线程会快很多,例如:

[mysql@yuan ~]$  mysqlslap --query='select count(*) from table_a where col2<>md5(rand())' --concurrency=1 --iterations=10
Benchmark
  Average number of seconds to run all queries: 0.015 seconds
  Minimum number of seconds to run all queries: 0.015 seconds
  Maximum number of seconds to run all queries: 0.016 seconds
  Number of clients running queries: 1
  Average number of queries per client: 1

观察500个连接运行时的状态参数

[mysql@yuan ~]$  mysqladmin extended-status -i5 -c100|grep Thread
| Threadpool_idle_threads                                | 24                                               |
| Threadpool_threads                                     | 50                                               |
| Threads_cached                                         | 0                                                |
| Threads_connected                                      | 371                                              |
| Threads_created                                        | 113                                              |
| Threads_running                                        | 26                                               |

| Threadpool_idle_threads                                | 32                                               |
| Threadpool_threads                                     | 50                                               |
| Threads_cached                                         | 0                                                |
| Threads_connected                                      | 195                                              |
| Threads_created                                        | 113                                              |
| Threads_running                                        | 18                                               |

| Threadpool_idle_threads                                | 20                                               |
| Threadpool_threads                                     | 50                                               |
| Threads_cached                                         | 0                                                |
| Threads_connected                                      | 465                                              |
| Threads_created                                        | 113                                              |
| Threads_running                                        | 30                                               |

| Threadpool_idle_threads                                | 24                                               |
| Threadpool_threads                                     | 50                                               |
| Threads_cached                                         | 0                                                |
| Threads_connected                                      | 287                                              |
| Threads_created                                        | 113                                              |
| Threads_running                                        | 25                                               |

| Threadpool_idle_threads                                | 48                                               |
| Threadpool_threads                                     | 50                                               |
| Threads_cached                                         | 0                                                |
| Threads_connected                                      | 47                                               |
| Threads_created                                        | 113                                              |
| Threads_running                                        | 2                                                |

分析MariaDB的状态参数可以得到以下结论:

  • Threadpool_idle_threads+Threads_running=Threadpool_threads
  • Threads_created值一直没有变,表示一直没有创建新的线程处理连接。
  • Threads_cached是在one-thread-per-connection时缓存的线程,在线程池使用时是零。

实际互联网的应用中,网民登录到网站后大部分时间是浏览网页,执行操作的时间只占很少一部分,可以使用下面的命令模拟网民的每一分钟执行一个SQL:

[mysql@yuan ~]$  mysqlslap --query='select count(*) from table_a where col2<>md5(rand());select sleep(6);' --concurrency=1 --iterations=20
Benchmark
  Average number of seconds to run all queries: 6.015 seconds
  Minimum number of seconds to run all queries: 6.015 seconds
  Maximum number of seconds to run all queries: 6.017 seconds
  Number of clients running queries: 1
  Average number of queries per client: 1

再次观察MariaDB的状态参数

| Threadpool_idle_threads                                | 19                                               |
| Threadpool_threads                                     | 20                                               |
| Threads_cached                                         | 0                                                |
| Threads_connected                                      | 5                                                |
| Threads_created                                        | 133                                              |
| Threads_running                                        | 2    
                                            |
| Threadpool_idle_threads                                | 19                                               |
| Threadpool_threads                                     | 20                                               |
| Threads_cached                                         | 0                                                |
| Threads_connected                                      | 5                                                |
| Threads_created                                        | 133                                              |
| Threads_running                                        | 2                                                |

| Threadpool_idle_threads                                | 19                                               |
| Threadpool_threads                                     | 20                                               |
| Threads_cached                                         | 0                                                |
| Threads_connected                                      | 5                                                |
| Threads_created                                        | 133                                              |
| Threads_running                                        | 2                                                |

发现这时线程池里面的线程数下降到20个,大部分时间线程池中只有一个线程在提供服务。

总结

经过前面的测试,我们可以看到,线程池对减少MySQL服务端线程数量的作用非常明显,通过包括一定数量的线程的线程池可以向大量的连接提供服务。
如果连接中执行的SQL运行时间较长,例如数据仓库类的业务,就不适合用线程池。另外非常简单的SQL(例如select 1)也会因为启动了线程池而比直接连接时运行得稍微慢一点。

欢迎加我的微信👇

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/127644.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

不用梯子,GitHub也能访问并提速

引言 我们都知道国内访问github会非常慢&#xff0c;甚至打不开&#xff0c;具体原因这里就不聊了~我们这里聊怎么不用梯子&#xff0c;GitHub也能访问并提速&#xff01; Github打开慢的原因 Github打开慢的原因其中一个原因&#xff1a;GitHub的CDN域名遭到DNS污染&#xf…

好用的开源个人博客推荐

原文网址&#xff1a;好用的开源个人博客推荐_IT利刃出鞘的博客-CSDN博客 简介 本文推荐个人从几十款开源个人博客中精选的几款开源博客。 halo Github 地址 &#xff1a;https://github.com/halo-dev/halo Star : 24.3k 简介 &#xff1a;一个优秀的开源博客应用。 技术 …

java学习day66(乐友商城)搜索过滤

1.过滤功能分析 首先看下页面要实现的效果&#xff1a; 整个过滤部分有3块&#xff1a; 顶部的导航&#xff0c;已经选择的过滤条件展示&#xff1a; 商品分类面包屑&#xff0c;根据用户选择的商品分类变化 其它已选择过滤参数 过滤条件展示&#xff0c;又包含3部分 商品分…

CNN神经网络

CNN神经网络0.引言0.1.卷积0.2.Relu函数0.3.池化pooling0.4.小节1.前向传播1.1.input layer --> convolution layer1.2.Hidden Layer --> convolution layer1.3.Hidden layer --> pooling layer1.4.Hidden layer --> full connected layer1.5.小节2.反向传播2.1.po…

如何实现微信和淘宝的扫码登录

1、引言 扫码登录这个功能&#xff0c;最早应该是微信的PC端开始搞&#xff0c;虽然有点反人类的功能&#xff08;不扫码也没别的方式登录&#xff09;&#xff0c;但不得不说还是很酷的。 下面这张图&#xff0c;不管是IM开发者还是普通用户&#xff0c;应该很熟悉&#xff…

高德地图WebGIS

GIS:地理信息系统 1 Web前端JSAPI X.1 创建app ​​​​ X.2 地图显示

热榜,Alibaba最新发布SprinBoot:进阶原理实战与面试题分析指南

为什么要写这本书&#xff1f; 我们知道&#xff0c;Spring Boot是一个集成性的开源框架&#xff0c;内部整合了很多第三方组件和框架。这些组件和框架应用如此之广泛&#xff0c;以至于大家反而往往对如何更好地使用Spring Boot自身的功能特性并不是很重视。事实上&#xff0…

自动化会计从这四个流程开始

自动化会计从这四个流程开始 会计和财务业务流程的自动化对企业领导者来说是一个巨大的机会。对于首席财务官 &#xff08;CFO&#xff09; 而言&#xff0c;可以让他们在改善运营和降低成本等传统角色中脱颖而出&#xff0c;同时利用他们在自动化方面的经验成为整个公司数字业…

SpringBoot 单元测试利器-Mockito

Mockito 是一种 Java mock 框架&#xff0c;他主要是用来做 mock 测试的&#xff0c;他可以模拟任何 Spring 管理的 bean、模拟方法的返回值、模拟抛出异常...等&#xff0c;在了解 Mockito 的具体用法之前&#xff0c;得先了解什麽是 mock 测试 1. 什么是 mock 测试&#xff…

Java Long对象对比,用equals函数

文章目录一、前文二、调试三、后记一、前文 同事问我一个问题&#xff0c;我咋一看也愣住了 代码&#xff1a; if(ObjectUtil.isNotNull(temp.getUserId()) && temp.getUserId()!SecurityUtils.getUserId()) {logger.error(temp.toString());logger.error("Securi…

ICV:车规级激光雷达市场规模超7亿美元,补盲雷达有望2024年量产

全球前沿科技咨询机构ICV近期发布了车载激光雷达的市场分析报告&#xff0c;ICV在报告中表示激光雷达是自动驾驶传感器中增速最快的传感器&#xff0c;预计未来五年的复合年增长率达43.4%。此外&#xff0c;混合固态式激光雷达近五年内将仍以应用转镜技术为主。 本报告旨在评估…

【store商城项目05】新增收获地址的开发

新增收获地址的开发1.创建地址表2.创建实体类3.持久层的开发3.1规划需要执行的SQL语句3.2Mapper接口与抽象方法3.3配置SQL映射3.4测试4.业务层的开发4.1规划异常4.2接口和抽象方法4.3实现抽象方法4.4测试5.控制层的开发5.1规划异常5.2设计请求5.3处理请求5.4测试6前端页面1.创建…

【Linux】Linux权限(二)默认权限的来源

默认权限1.默认权限2.默认权限&#xff08;最终权限&#xff09;由谁决定2.1起始权限2.2umask&#xff08;权限掩码&#xff09;2.3 最终权限的计算3.总结1.默认权限 在Linux下&#xff0c;我们以普通用户创建一个普通文件&#xff0c; 这个普通文件(这里不包括可执行)的默认权…

萤石网络IPO首日破发:市值缩水20亿元,海康威视为控股股东

12月28日&#xff0c;杭州萤石网络股份有限公司&#xff08;下称“萤石网络”&#xff0c;SH:688475&#xff09;在上海证券交易所科创板上市。本次上市&#xff0c;萤石网络的发行价为28.77元/股&#xff0c;发行1.13亿股&#xff0c;募资总额为32.51亿元&#xff0c;总市值约…

【1.1】认识微服务--服务架构演变

认识微服务--服务架构演变单体架构分布式架构服务治理微服务微服务架构特征小结知识内容来自于黑马程序员视频教学和百度百科。博主仅作笔记整理便于回顾学习。如有侵权请私信我。 单体架构 单体架构&#xff1a; 将业务的所有功能集中在一个项目中开发&#xff0c;打成一个包…

线性规划求解-MATLAB Lingo Python实现

线性规划求解-MATLAB Lingo Python实现 线性规划 线性规划是辅助人们进行科学管理的一种数学方法&#xff0c;是研究线性约束条件下线性目标函数的极值问题的数学理论和方法。其展开形式可以表示为如下形式&#xff1a; Max⁡(Min⁡)zc1x1c2x2…cnxns.t. {a11x1a12x2⋯a1nxn≥…

2022年度十大科学突破榜单出炉!

科学的进步在很大程度上推动着人类社会的发展。而了解最新年度科学突破&#xff0c;有助于引领我们知晓世界科学进展&#xff0c;看清楚未来方向。故此&#xff0c;知识人网小编本期介绍《科学》杂志最新公布的2022年科学突破榜单。 12月16日&#xff0c;美国《科学》杂志网站列…

一种时间复杂度为O(2ⁿ)、空间复杂度为O(n)的子集和问题的算法

子集和问题&#xff08;Subset-Sum Problem, SSP&#xff09;是说给定一个自然数集合S{a1,a2,⋯,an}S\{a_1,a_2,\cdots,a_n\}S{a1​,a2​,⋯,an​}&#xff0c;它含有nnn个元素&#xff0c;现在又给定一个自然数sss&#xff0c;问是否存在SSS的一个子集TTT使得TTT的所有元素之和…

JavaScript 隐秘者 | Console.xxx竟然如此好用

JavaScript 隐秘者 | Console.xxx竟然如此好用 文章目录JavaScript 隐秘者 | Console.xxx竟然如此好用一、控制台调试二、对象方法 &#x1f356;1)、.assert() 条件断言2)、.clear() 清空控制台3)、.count() 计算调用数 ⭕4)、.countReset() 重置计数器5)、.debug() 调试消息6…

文献翻译 (3):非支配排序遗传算法 (Non-dominated Sorting Genetic Algorithm, NSGA-II)

文章目录1 引入2 多目标优化3 更多的定义3.1 支配3.2 非支配集3.3 全局Pareto最优集4 NSGA-II1 引入 本文主要介绍多目标优化的基本概念以及NSGA-II。 2 多目标优化 多目标优化的优化目标之间存在一定的冲突&#xff0c;例如一个目标增长&#xff0c;导致另一个减少。因此这…