揭秘MySQL线程池内幕


揭秘MySQL线程池内幕

文章插图
 
摘要在MySQL中 , 线程池指的是用来管理处理MySQL客户端连接任务的线程的一种机制 , 我厂用的percona版本已经是集成了线程池 , 只需要通过如下参数开启即可 。
thread_handling=pool-of-threads本文在介绍MySQL线程池核心参数的基础之上对线程池内部实现机制进行进一步介绍 。
线程池导读线程池概论
在继续了解MySQL线程池之前 , 我们首先要了解为什么线程池的引入可以帮助MySQL提升性能 , 除了性能之外线程池还有哪些作用?如果把线程看做系统资源那么线程池本质上是对系统资源的管理 , 对于操作系统来说线程的创建和销毁是比较消耗系统资源的 , 频繁的创建与销毁线程必然给系统带来不必要的资源浪费 , 特别是在负载高的情况下这部分开销严重影响系统的资源使用效率从而影响系统的性能与吞吐量 , 另一方面过多的线程创建又会造成系统资源的过载消耗 , 同时带来相对频繁的线程之间上下文切换问题 。系统资源是宝贵的 , 我认为性能与资源的利用率是紧密相关的:
 
揭秘MySQL线程池内幕

文章插图
 
 
资源利用率与性能的同向性
他们往往向着一个方向发展 , 好的资源利用与通常可以带来较优的性能 , 线程池技术一方面可以减少线程重复创建与销毁这部分开销 , 从而更好地利用已经创建的线程资源 , 另一方面也可以控制线程的创建与系统的负载 , 某些场景对系统起到了保护作用 。
如何了解MySQL线程池
通过学习掌握MySQL有哪些参数 , 并深刻理解每个参数的含义以及这些参数是如何影响MySQL的等问题是一种很好的学习MySQL线程池的一种方式 , 另外在了解MySQL基本实现原理的基础之上再对MySQL线程池不足以及可以改进的地方进行更深层次的思考有利于更好地理解MySQL线程池技术 。
线程池核心参数MySQL线程池向用户开放了一些参数 , 用户可以修改这些参数从而影响线程池的行为 , 下面分别介绍一下这些核心参数 。
thread_pool_size
这个参数指的是线程组大小 , 默认是CPU核心数 , 线程池初始化的时候会根据这个数字来生成线程组 , 每个线程组初始化一个poolfd句柄 。
thread_pool_stall_limit
Timer Thread迭代的时间间隔 , 默认是500ms 。
thread_pool_oversubscribe
用于计算线程组是否太过活跃或者太过繁忙 , 也即系统的负载程度 , 用于在一定场景决策新的工作线程是否被创建于和任务是否被处理 , 这个值默认是3 。
thread_pool_max_threads
允许线程池中最大的线程数 , 默认是10000 。
thread_pool_idle_timeout
工作线程最大空闲时间 , 工作线程超过这个数还空闲的话就退出 , 这个值默认是60秒 。
thread_pool_high_prio_mode
这个参数可用于控制任务队列的使用 , 可取三个值:
  • transactions
  • statements
  • none
当为值为statements的时候则线程组只使用优先队列 , 当为值为none的时候则只使用普通队列 , 当值为transactions的时候配合thread_pool_high_prio_tickets参数生效 , 用于控制任务被放入优先队列的最大次数 。
thread_pool_high_prio_tickets
当thread_pool_high_prio_mode=transactions的时候每个连接的任务最多被放入优先队列thread_pool_high_prio_tickets次 , 并且每放一次递减 , 直到小于等于0的时候放入普通队列 , 这个值默认是4294967295 。
MySQL线程池实现内幕线程池总体架构
与JAVA的线程池不同 , JAVA线程池中是工作线程而MySQL线程池有一个线程组的概念 , 线程组内部层级才是工作线程 , 先看看MySQL线程池的大致架构:
 
揭秘MySQL线程池内幕

文章插图
 
 
线程池架构
上图大致可以看出线程池内部的结构 , 线程组为我们关注的一个较大的组件 , 线程组内部每个组件的相互协调构成了线程组 , 每个线程组良好地工作构成了线程池 。对于线程池内部 , 我认为值得了解的内容主要包括下面几个方面:


推荐阅读