文章转载自:https://www.cnblogs.com/f-ck-need-u/p/9281909.html

ProxySQL的线程

ProxySQL由多个模块组成,是一个多线程的daemon类程序。每个模块都有一个或多个线程去执行任务。

例如,以下是刚启动ProxySQL时的进程情况,一个main进程,一个主线程,21个线程。

# pstree | grep proxy
|-proxysql---proxysql---21*[{proxysql}]

下面是正常运行时使用的线程列表:

1.1 Main thread

这其实是一个进程,该进程只负责引导、启动核心模块以及启动其它核心线程。

1.2 Admin thread

该线程负责以下几件事:

  • 初始化并引导启动Admin接口。
  • 从磁盘数据库或配置文件中加载配置,为ProxySQL的运行提供环境。
  • 启动一个监听者,让其负责监听并接受到Admin接口的新连接,并为每个这样的连接创建一个新线程。

所以,每连接一次admin接口,就会新生成一个线程。每次退出admin接口时,减去一个线程。

1.3 MySQL workers

mysql-threads线程负责处理MySQL流量,包括所有来自客户端的连接以及所有到后端服务器节点的连接。也就是:用少量线程处理任意多数量的连接。

MySQL workers线程在相同的端口上进行监听。当新客户端发起连接请求,其中一个MySQL worker线程将成功接受该连接,并创建一个MySQL会话(session):客户端和会话绑定在该worker线程上,直到连接断开。换句话说,在断开连接之前,某客户端的所有连接总是被同一个worker线程处理。

默认情况下,MySQL worker的线程数量为4。

mysql> select @@mysql-threads;
+-----------------+
| @@mysql-threads |
+-----------------+
| 4 |
+-----------------+

mysql-threads变量修改后,必须重启ProxySQL才能生效,这是少有的需要重启的变量之一(另一个是mysql-stacksize)。例如,修改为8个mysql worker线程。

set mysql-threads=8;
save mysql variables to disk; select * from runtime_global_variables
where variable_name='mysql-threads';
+---------------+----------------+
| variable_name | variable_value |
+---------------+----------------+
| mysql-threads | 4 |
+---------------+----------------+ service proxysql stop
service proxysql start select * from runtime_global_variables
where variable_name='mysql-threads';
+---------------+----------------+
| variable_name | variable_value |
+---------------+----------------+
| mysql-threads | 8 |
+---------------+----------------+

1.4 MySQL auxiliary threads

这些线程其实就是空闲线程(idle threads)。

如果proxysql使用--idle-threads选项启动,每个worker线程都会伴随启动一个auxiliary线程。每个worker线程以及它的auxiliary线程一起工作:第一个线程处理活动的连接,并将所有的空闲连接派遣到第二个线程上,但第二个线程只要等待到了发生在空闲连接上的一个事件(或超时),就会将连接还给第一个线程。

当活动的客户端连接数量远少于空闲客户端连接数量时,强烈建议使用"idle threads"。这使得ProxySQL可以处理几十万个连接(测试时是100W个连接)。

1.5 Monitor模块相关的线程

monitor模块有自己的线程管理系统,还有自己的线程池。正常情况下,monitor模块有以下几个线程:

  • 一个master线程,负责生成、协调其它monitor相关的线程。
  • 一个负责监控connect的线程。
  • 一个负责监控ping的线程。
  • 一个负责监控read_only的线程。
  • 一个负责监控replication lag的线程。
  • 一个线程池提供monitor worker线程,上面每个监控线程都是任务的生产者,worker线程从任务队列消费一个任务并执行该任务。该线程池初始时默认为mysql thread的两倍。

线程池负责执行所有的检查任务,并通过以上各调度线程来监控调度情况。线程池会基于监控队列中待检查的数量多少而自动增长、收缩。基于检查的结果,会使用相同的线程对结果进行处理,例如避开一个节点、重新配置一个主机组。

1.6 Query Cache purge thread

该线程是需要时才生成的,它扮演的是垃圾收集器,回收查询缓存。通过垃圾收集器,可保证在客户端等待响应的过程中绝不会回收缓存。

1.7 其它线程

在ProxySQL运行过程中,偶尔会派生临时线程,这些临时线程是为了向后端发送KILL语句,以便杀掉后端服务器上对查询长时间无响应的查询线程。

此外,ilbmariadbclient库还会使用一些后台线程,这些线程是为了和后端MySQL server进行一些特定的异步交互任务。

还有一些模块,例如内置的Http server,正处于实验阶段的cluster、ClickHouse Server、SQLite3 Server,如果启用了这些功能,则会按需创建它们对应的线程。

ProxySQL的线程池

在ProxySQL中,有两个地方使用了线程池:

  • 快速建立和后端MySQL的连接:ProxySQL为了尽快和后端MySQL建立新的TCP连接,使用了一个线程池来等待accept()返回新连接。
  • Monitor模块:为了尽快执行各监控线程生产的监控任务,monitor模块提供了一个monitor worker线程池,可以快速从任务队列中消费任务。

需要注意的是,正常情况下,MySQL worker线程是最繁忙、最消耗CPU资源的部分,但在一个极其繁忙的环境下,monitor模块需要监控的连接数过多,消耗的CPU也是不可忽视的。

ProxySQL的连接池

ProxySQL同样有两个连接池,和线程池部分是对应的。

3.1 快速连接到后端MySQL节点

线程池是为了快速和后端建立新的TCP连接,而这里的连接池是为了快速和后端建立连接。

ProxySQL使用一个连接池来存放一定数量的"之前已经和某后端建立连接,但当前是空闲连接"的连接。当需要向这些连接对应的后端发送新的数据包时,可以快速地取回连接,因为这些连接早已经被打开。

当应用程序发送了一个MySQL请求给ProxySQL时,ProxySQL首先解析要路由到哪个后端,如果连接池中已经有和该后端的连接,将重用该连接,否则将创建一个新的和后端的连接。

当处理完客户端的请求后,连接会还回主机组管理器(HostGroup Manager)。如果主机组管理器判断了该连接是可以被安全共享的,且连接池未满,则该连接会放进连接池。

放进连接池的连接都是空闲连接,正在使用的连接是不可能进入连接池的。ProxySQL会定期发送ping消息来维持空闲连接。如果某连接从上一次ping之后,如果还没有被使用,则该连接被定义为空闲连接。对于空闲连接ping的时间间隔由变量mysql-ping_interval_server_msec控制。

但是,不是所有的未使用的连接都会放进连接池。该变量用来控制某后端的空闲连接和最大总连接数的百分比。对于每个hostgroup/backend,主机组管理器只会保持连接池中的最大连接数为mysql-free_connections_pct * mysql_servers.max_connections / 100。池中的每个空闲连接都通过间断性的ping来维持它的打开状态。

当一个连接放回连接池时,会计算这个连接之后还能处理多少个语句,当处理的语句数量达到该阈值后,将关闭该连接(v1.4.3之前)或者重置该连接(从v1.4.4开始)。

3.1.1 相关变量

mysql-ping_interval_server_msec

ProxySQL为了维持和后端的空闲连接,每隔一段时间发送一次ping,该变量指定发起ping的时间间隔。默认值为10000毫秒(即10秒)。

mysql-ping_timeout_server

ProxySQL为了维持和后端的空闲连接,每隔一段时间发送一次ping。该变量指定ping得到回复的超时时间。默认值为200毫秒。

mysql-connection_max_age_ms

当该变量设置的值大于0时(单位毫秒),如果某个空闲连接(当前没有任何会话使用)的空闲时长超过了这里设置的值,则这个连接会关闭。默认值为0,表示不会因为存活时间而关闭空闲连接。

3.2 Monitor模块的连接池

Monitor有它自己的连接池。当连接池中空闲连接的空闲时长达到了3 * mysql-monitor_ping_interval(毫秒)后,该空闲连接将自动被purge。

变量mysql-monitor_ping_interval的默认值为1分钟(60000毫秒),所以,monitor连接池中的空闲连接默认最长维持3分钟。

ProxySQL(5):线程、线程池、连接池的更多相关文章

  1. (转)websphere线程池 连接池设置

    原文:http://www.talkwithtrend.com/Article/207511 池(Pool)是WebSphere中最常涉及的概念之一.从网络.Web 服务器.Web 容器.EJB 容器 ...

  2. MySQL 线程池&连接池&长连接&短连接

    线程池 简介 1.mysql每连接每线程,mysql都分配一个单独的线程,该线程处理客户端发来的所有命令 2.每个线程会占用一定的系统资源,线程数越多消耗的系统资源也越多 3.线程的创建和销毁有一定的 ...

  3. 线程池-连接池-JDBC实例-JDBC连接池技术

    线程池和连接池   线程池的原理:     来看一下线程池究竟是怎么一回事?其实线程池的原理很简单,类似于操作系统中的缓冲区的概念,它的流程如下:先启动若干数量的线程,并让这些线程都处于睡眠状态,当客 ...

  4. common-pool2对象池(连接池)的介绍及使用

    我们在服务器开发的过程中,往往会有一些对象,它的创建和初始化需要的时间比较长,比如数据库连接,网络IO,大数据对象等.在大量使用这些对象时,如果不采用一些技术优化,就会造成一些不可忽略的性能影响.一种 ...

  5. MySQL中间件之ProxySQL(5):线程、线程池、连接池

    返回ProxySQL系列文章:http://www.cnblogs.com/f-ck-need-u/p/7586194.html 1.ProxySQL的线程 ProxySQL由多个模块组成,是一个多线 ...

  6. Tomcat 连接池详解

    (转) JDBC 连接池 org.apache.tomcat.jdbc.pool 是Apache-Commons DBCP连接池的一种替换或备选方案. 那究竟为何需要一个新的连接池? 原因如下: Co ...

  7. Http持久连接与HttpClient连接池

    一.背景 HTTP协议是无状态的协议,即每一次请求都是互相独立的.因此它的最初实现是,每一个http请求都会打开一个tcp socket连接,当交互完毕后会关闭这个连接. HTTP协议是全双工的协议, ...

  8. Http 持久连接与 HttpClient 连接池

    一.背景 HTTP协议是无状态的协议,即每一次请求都是互相独立的.因此它的最初实现是,每一个http请求都会打开一个tcp socket连接,当交互完毕后会关闭这个连接. HTTP协议是全双工的协议, ...

  9. Tomcat 的 JDBC 连接池

    JDBC 连接池 org.apache.tomcat.jdbc.pool 是 Apache Commons DBCP 连接池的一种替换或备选方案. 那究竟为何需要一个新的连接池? 原因如下: Comm ...

随机推荐

  1. 简单状压dp的思考 - 最大独立集问题和最大团问题 - 壹

    本文参考:CPH ,USACO Guide (大佬请越过,这是初学笔记,不要吐槽内容) 前置知识:位运算基础,动态规划基础 介绍 状态是元素的子集的动态规划算法,可以用位运算来高效的优化. 那么第一道 ...

  2. javaScript去重的11种方法

    前言 去重是开发和面试中经常遇到的问题,下面是总结的 11 种去重方法 方法 示例数组 var arr = [1, 2, 4, 5, 5, 2, 1, 1, 4, 6] set + 解构赋值 这种方法 ...

  3. java通过注解顺序通过映射导出excel

    import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.ann ...

  4. 揭开服务网格~Istio Service Mesh神秘的面纱

    目录 一.写在前面 二.微服务与K8S 三.服务网格与K8S 四.常见的产品 五.Istio架构 六.Istio的核心资源介绍 6.1.VirtualService 6.2.Destination R ...

  5. DHCP原理及配置

    DHCP工作原理 集中的管理.分配IP地址,使client动态的获得IP地址.Gateway地址.DNS服务器地址等信息,并能够提升地址的使用率. 简单来说,DHCP就是一个不需要账号密码登录的.自动 ...

  6. 2022.7.9 单向链表&数组优化

    相比起数组,链表解决了数组不方便移动,插入,删除元素的弊端,但相应的,链表付出了更加大的内存牺牲换来的这些功能的实现. 链表概述 包含单链表,双链表,循环单链表,实际应用中的功能不同,但实现方式都差不 ...

  7. CF455ABoredom

    题目大意: 给你一个由 \(n\) 个整数构成的序列 \(a\),玩家可以进行几个步骤,每一步他可以选择序列中的一个元素(我们把它的值定义为 \(a_k\))并删除它,此时值等于 \(a_{k + 1 ...

  8. Linux中安装JDK详细步骤

    一.下载Linux版本的JDK 进入官网下载对应的JDK,下载之前需要先登录 官网地址 -> https://www.oracle.com/ 登录成功后,找到对应的下载位置 根据自己电脑下载对应 ...

  9. PostgreSQL定时备份

    # PostgreSQL定时备份 # 版本:PostgreSQL14.0 # 一.如果你在pg_hba.conf中设定了密码登录,那么你就需要设置一个默认密码共psql登录的时候跳过验证.如果是roo ...

  10. SQLServer的两个日期相减(间隔)datediff函数

    select datediff(year, 开始日期,结束日期); --两日期间隔年  select datediff(quarter, 开始日期,结束日期); --两日期间隔季  select da ...