概述
- mysql企业版安装插件使用
- 限制最大并发
- 减少服务器CPU调度
- mysql默认线程调度one-thread-per-connection(每连接一个线程)
- 线程池适合大量短连接或高并发情况
相关参数
Plain Text
#查看线程池参数
show global variables like '%thread_pool%';
thread_pool_high_prio_mode
有三个取值:transactions / statements / none
transactions(default): 使用优先队列和普通队列,对于事务已经开启的statement,放到优先队列中,否则放到普通队列中
statements:只使用优先队列
none: 只是用普通队列,本质上和statements相同,都是只是用一个队列
thread_pool_high_prio_tickets
取值0~4294967295,当开启了优先队列模式后(thread_pool_high_prio_mode=transactions),每个连接最多允许thread_pool_high_prio_tickets次被放到优先队列中,之后放到普通队列中,默认为4294967295
thread_pool_idle_timeout
worker线程最大空闲时间,单位为秒,超过限制后会退出,默认60
thread_pool_max_threads
threadpool中最大线程数目,所有group中worker线程总数超过该限制后不能继续创建更多线程,默认100000
thread_pool_oversubscribe
一个group中线程数过载限制,当一个group中线程数超过次限制后,继续创建worker线程会被延迟,默认3
thread_pool_size
threadpool中group数量,默认为cpu核心数,server启动时自动计算
thread_pool_stall_limit
timer线程检测间隔,单位为毫秒,默认500
架构组成
threadpool组成
threadGroup
一个threadgroup 为一个线程池 其中有 两个队列 和多个work线程
队列
- 两个队列 高级队列和低级队列
- 高级队列的任务会优先处理
- 开启事务的任务 会放到高级队列中
- 低级队列停留时间太久 也会移到高级队列
liistener线程
- 监听线程池任务
- 确定是自己变成work线程立即执行任务 还是放到队列中
- 如果队列中待执行的语句数量为0,而listener线程转换成worker线程,并立即执行对应的语句
- 如果队列中待执行的语句数量不为0,则认为任务比较多,将语句放入队列中
- 为了减少线程的创建
worker线程
真正执行SQL的线程
timer线程
- 周期检查group是否阻塞
- 出现阻塞 通过唤醒线程或新建线程解决
Plain Text
Timer线程是用来周期性检查group是否处于处于阻塞状态,当出现阻塞的时候,会通过唤醒线程或者新建线程来解决。具体的检测方法为,通过queue_event_count的值和IO任务队列是否为空来判断线程组是否为阻塞状态。每次worker线程检查队列中任务的时候,queue_event_count会+1,每次Timer检查完group是否阻塞的时候会将queue_event_count清0,如果检查的时候任务队列不为空,而queue_event_count为0,则说明任务队列没有被正常处理,此时该group出现了阻塞,Timer线程会唤醒worker线程或者新建一个wokrer线程来处理队列中的任务,防止group长时间被阻塞。
ThreadPool 如何运行
- 请求连接到mysql 通过线程id % group_size 确定group
- listenner确定执行线程
- group中的thread线程检查队列的请求,如果队列中有请求,则进行处理,如果没有请求,则休眠,一直没有被唤醒,超过thread_pool_idle_timeout后就自动退出。线程结束。当然,获取请求之前会先检查group中的running线程数是否超过thread_pool_oversubscribe+1,如果超过也会休眠。