为了账号安全,请及时绑定邮箱和手机立即绑定
首页 手记 MySQL线程池

MySQL线程池

2019.02.08 15:38 2560浏览

一、相关概念

MySQL连接池:
连接池通常实现在Client端,是指应用(客户端)预先创建一定的连接,利用这些连接服务于客户端所有的DB请求。如果某一个时刻,空闲的连接数小于数据库的请求数,则需要将请求排队,等待空闲连接处理。通过连接池可以复用连接,避免连接的频繁创建和释放,从而减少请求的平均响应时间,并且在请求繁忙时,通过请求排队,可以缓冲应用对数据库的冲击。

MySQL线程池:
线程池实现在Server端,通过创建一定数量的线程服务Clientl连接请求,相对于one-conection-per-thread的一个线程服务一个连接的方式,线程池服务的最小单位是语句,即一个线程可以对应多个活跃的连接。通过线程池,可以将Server端的服务线程数控制在一定的范围,减少了系统资源的竞争和线程上下文切换带来的消耗,同时也避免出现高连接数导致的高并发问题。

MySQL线程缓存:
线程缓存实现在Server端,Client连接对应的线程会被缓存起来,缓存的线程数量由 thread_cache_size大小决定。当服务器不断有大量连接创建、关闭的场景下,使用线程缓存能够重用缓存起来的线程,避免了线程大量创建销毁带来的性能消耗,但是仍然无法解决高连接数带来的线程数过高的问题

线程缓存命中率计算 :(1-Threads_created/Connections

注意:
当线程池功能开启后,线程缓存会自动失效,即变量thread_cache_size将被忽略,Threads_cached 状态变量始终为0。

二、MySQL线程池

线程池是MySQL 5.6 开始提供的一个核心功能,MySQL 5.6 之前,处理连接的方式是 one-thread-per-connection, 对于每一个Client 连接都会创建一个独立的线程,请求结束,销毁线程。高并发下,导致线程的频繁创建和释放,以及频繁的线程上下文切换,降低了资源利用率。通过线程池,一个线程可以处理多个Client连接请求,减少线程频繁创建释放以及线程上下文切换带来的性能损耗。通过参数thread_handling来控制是否使用线程池。

thread_handling 取值:

  • no-threads (在主线程里处理所有连接,仅用于MySQL调试)

  • one-thread-per-connection(默认值,一个连接对应一个线程)

  • loaded-dynamically(适用于5.7.9及以上版本,动态加载线程池)

  • pool-of-threads(Percona版本线程池实现)

Percona MySQL版本为thread_handling参数增加了pool-of-threads,Percona 的线程池实现在server层,与官方版以plugin形式实现不同,Percona版线程池与官方版并不兼容。

三、Percona MySQL 线程池相关参数:

thread_pool_max_threads:默认值 100000,线程池中的最大线程数。

thread_pool_size:用于设置线程池中线程组的个数,默认为服务器CPU的核心数。实现分组的目的是为了把每个分组对应到每个CPU核心上,这样在同一时间点,每个分组可调用1个线程进行执行。

thread_pool_oversubscribe:默认值为3,用于控制单个CPU核心在同一时间活跃的线程数。类似于一种“超频”的概念,值越大,表示在同一时间,有更多的线程能够运行。如果这个值小于3,将会导致频繁的线程睡眠和唤醒。

thread_pool_stall_limit:线程池中无可用线程时,thread_pool_stall_limit决定等待多久后创建新线程,单位为毫秒。默认是500。在合适范围内,该值越大,MySQL服务器的整体处理性能就越好,因为较少数量的线程,会降低对于系统资源的征用。但是,并不是越大越好,因为该值越大,新线程的创建将等待更长的时间,用户的查询延迟就会越明显。

thread_pool_idle_timeout:默认值60秒,空闲线程在空闲多长时间之后销毁。

thread_pool_high_prio_tickets:默认值 4294967295,控制高优先级队列策略, 给每个新的连接授予的tickets大小,如果该值全局设置为0,表示禁用高优先级队列。

thread_pool_high_prio_mode:取值范围 transactions, statements, none,默认值 transactions。该参数提供了对每个连接在高优先级队列更加细粒度的控制。线程池分组内的待处理任务会放到任务队列中,等待worker线程处理。每个分组有两个队列,高优先级队列和普通队列,worker线程先从高优先队列取event处理,只有当高优先队列为空时才从普通队列取event处理。通过优先级队列,可以让已经开启的事务或短事务得到优先处理,及时提交释放锁等资源。该参数可设置三种模式:

  • transactions:默认值,只有一个已经开启了事务的SQL,并且thread_pool_high_prio_tickets不为0,才会进入到高优先级队列中,每个连接在thread_pool_high_prio_tickets次被放到优先队列中后,会移到普通队列中。

  • statements:独立的SQL语句总是进入高优先级队列。

  • none:禁用高优先级队列功能,所有的连接都放到普通队列中处理。

四、Percona MySQL 线程池相关状态变量:

Threadpool_idle_threads:表示线程池中的空闲线程数
Threadpool_threads:表示线程池中的所有线程数
Threads_connected:表示当前已打开的连接数量
Threads_created:表示已创建的用来处于client连接的线程数,该值为累加值
Threads_running:表示当前正在执行的线程数



作者:偏执的工匠
链接:https://www.jianshu.com/p/e8d1b18a104c


点击查看更多内容
0人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
JAVA开发工程师
手记
粉丝
200
获赞与收藏
989

关注TA,一起探索更多经验知识

同主题相似文章浏览排行榜

风间影月说签约讲师

51篇手记,涉及Java、MySQL、Redis、Spring等方向

进入讨论

Tony Bai 说签约讲师

151篇手记,涉及Go、C、Java、Python等方向

进入讨论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消