MySQL高性能策略——线程池

MySQL高性能策略——线程池


线程池的优点

  1. 通过复用线程,减少创建、销毁线程的开销,减少了上下文切换,提高性能
  2. 线程池限制了并发线程数,不会无限创建线程,可以起到削峰的作用,保护了数据库

    连接池 & 线程池 —— 最好是配合使用
    连接池:限制的是客户端连接数据库的线程数,处于JDBC层级,受max_connections参数影响;
    线程池:限制的是MySQL运行的线程数,处于MySQL服务器层级
    连接池大小往往要比线程池工作线程数大,比如:连接池max_connections= 4000,而线程池工作线程thread_pool_size * thread_pool_oversubscribe = 360


MySQL线程池架构

1.Timer Thread【thread_pool_stall_limit

用于周期性地检查所有Group是否处于阻塞状态,如果处于阻塞,会通过唤醒线程或创建线程来解决。

2.Thread Groups【thread_pool_size

MySQL线程池被划分为不同的线程组(Thread Group),每个Group中包含一个Listener线程、多个Worder线程和2个优先队列。
通过对请求线程的thread_id取模进行哈希路由

(1)Listener Thread

负责监听单个Group的语句,如果Listener Thread中没有任务,收到任务时Listener Thread就会转变为Worker Thread,自己执行任务,如果已有任务就会将任务提交给优先队列

(2)Worder Threads

工作线程。

(3)优先队列

低优先队列

如果语句在低优先队列停留太久,会被加入高优先队列,防止饿死

高优先队列【thread_pool_high_prio_mode

高优先队列中的任务会先被处理。

什么样的任务会被加入高优先队列?
1.事务中的语句会放入高优先队列
2.如果语句在低优先队列停留太久,会被加入高优先队列,防止饿死


MySQL线程池运作

  1. MySQL根据请求的thread_id将它路由到不同的Thread Group
  2. Thread Group的Listener Thread如果没有执行中的任务,那么就转化为Worker Thread直接处理任务,否则将任务加入优先队列
  3. Worker Thread检查优先队列中是否存在任务——如果不存在任务,则休眠,一直到被唤醒,超过thread_pool_idle_timeout后就自动退出;如果存在任务,首先检查运行中的线程数是否超过thread_pool_oversubscribe + 1,如果超过则线程休眠,否则就处理任务
  4. Timer Thread检查各个Thread Group是否存在阻塞,如果阻塞则创建/唤醒线程

线程池参数

show variables like 'thread%';

thread_handling

配置线程模型,默认是one-thread-per-connection,即不启用线程池;
启用线程池:pool-of-threads

1.thread_pool_size

Thread Group数量,默认为CPU个数。
允许值的范围在1-64,如果超过这个范围,则不会启动线程池,并且会将错误消息写入日志。

2.thread_pool_oversubscribe

单个Group中的最大并发Worker Thread数,不包括Listener Thread

3.thread_pool_high_prio_mode

控制什么样的语句可以加入高优先队列:

  1. transaction:默认,启动事务的语句加入高优先队列,需要搭配thread_pool_high_prio_tickets使用
  2. statement:所有语句都加入高优先队列
  3. none:所有语句都不加入高优先队列

4.thread_pool_high_prio_tickets

控制每个连接最多语序多少次被加入高优先队列,默认4294967295

5.thread_pool_idle_timeout

Worker Thread最大空闲时间,默认60

6.thread_pool_max_threads

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

如果已经到达了thread_pool_max_threads,那么即使单个Group没有到达thread_pool_oversubscribe + 1的线程数,也不能创建新线程。

7.thread_pool_stall_limit

Timer Thread检测每个Thread Group是否存在阻塞的时间间隔,默认50,即500ms。
允许的范围在4-600,即40ms到6s。

  1. thread_pool_stall_limit越大,阻塞的检测时间就越长,创建的线程数量会越少,系统的负载就会越小;但是新线程的创建的延迟就会越大,用户的等待时间就会增加
  2. thread_pool_stall_limit越小,阻塞的检测时间就越短,创建的线程数量会越多,系统的负载就会越大,相应的,用户的等待时间就会减少,由于长连接的减少,死锁的概率也大大降低
-------------本文结束感谢您的阅读-------------

本文标题:MySQL高性能策略——线程池

文章作者:DragonBaby308

发布时间:2019年08月02日 - 21:03

最后更新:2019年11月01日 - 21:28

原始链接:http://www.dragonbaby308.com/mysql-thread-pool/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

急事可以使用右下角的DaoVoice,我绑定了微信会立即回复,否则还是推荐Valine留言喔( ఠൠఠ )ノ
0%