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

返回ProxySQL系列文章:http://www.cnblogs.com/f-ck-need-u/p/7586194.htmlhtml

 

1.ProxySQL的线程

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

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

[root@s1 ~]# 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线程处理。session

默认状况下,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,若是启用了这些功能,则会按需建立它们对应的线程。

2.ProxySQL的线程池

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

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

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

3.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分钟。

相关文章
相关标签/搜索