MySQL InnoDB配置并发线程( innodb_thread_concurrency)

http://www.ywnds.com/?p=9821html

1、thread_concurrencymysql

首先,最重要的一点,这个参数已经在最新版本的MySQL中被移除了,官方最新5.7版本的doc上面对thread_concurrency有这样的说明:算法

thread_concurrency变量是针对于Solaris 8及低版本的系统,设置了这个变量MySQL会调用thr_setconcurrency()函数。这个函数容许应用程序给同一时间运行的线程系统提示所需数量的线程。当前的Solaris版本中这个参数已经没有做用了,这个参数在MySQL 5.6.1中已经被标记为过期,在5.7.2版本的MySQL中被移除。sql

2、innodb_thread_concurrency参数介绍服务器

MySQL的两种存储引擎:MyISAM和InnoDB,InnoDB支持事务,也是MySQL默认的存储引擎,在InnoDB中,咱们能够经过设置参数innodb_thread_concurrency限制线程的数量。并发

先来看一下官方Configuring Thread Concurrency for InnoDB对innodb_thread_concurrency参数的配置说明,翻译以下:函数

InnoDB使用操做系统线程来处理用户的事务请求。(在事务提交或回滚以前可能给InnoDB引擎带来不少的请求)。在现代化操做系统和多核处理器的服务器上,上下文切换是很是高效的,大多数工做负载运行没有任何并发线程数量的限制。在MySQL 5.5及以上版本中,MySQL作了可伸缩性的改进,它减小了这种在InnoDB内部限制并发执行线程数量的须要。性能

它有助于在最小化的状况下进行线程之间的上下文切换,InnoDB可使用各类技术来限制操做系统并发执行线程的数量(所以大批量的请求能够在任何一个时间获得处理)。当InnoDB从用户会话收到一个新的请求,若是线程并发执行的数量达到预约义的限制,那么新的请求会先睡眠一段时间后再次尝试。在睡眠后不能按计划执行的请求会被放入先入/先出队列,并最终处理。但那些等待获取锁的线程则不会被计入到并发执行线程的数量中。 咱们能够经过设置配置参数innodb_thread_concurrency来限制并发线程的数量,一旦执行线程的数量达到这个限制,额外的线程在被放置到对队列中以前,会睡眠数微秒,能够经过设定参数innodb_thread_sleep_delay来配置睡眠时间。测试

在MySQL 5.6.3以前的版本中,MySQL要求经过测试和实验找到innodb_thread_sleep_delay的最优值,这个最优值可能会因工做负载状况不一样而发生改变。在MySQL 5.6.3及更高版本中,你能够经过设置参数innodb_adaptive_max_sleep_delay为innodb_thread_sleep_delay设置最大容许的值,InnoDB会根据当前线程调度活动自动调整innodb_thread_sleep_delay的值,这种动态调整机制有助于工做的线程,在系统负载低时或系统接近满负荷运转时,都可以顺利的调度。优化

在MySQL和InnoDB以前的版本系列中,innodb_thread_concurrency的默认值,以及其隐含的限制并发线程执行的数量都进行过调整。在当前最新版本的MySQL中,innodb_thread_concurrency的默认值为0,它表示默认状况下不限制线程并发执行的数量。

另外,InnoDB只有当并发线程数量有限时,线程才会休眠。当线程数量没有限制时,全部这些都一样被安排。也就是说,若是innodb_thread_concurrency是0,值 innodb_thread_sleep_delay被忽略。

当线程数量有限时(当innodb_thread_concurrency>0时),InnoDB经过容许在执行单个SQL语句期间进行的多个请求进入InnoDB而不须要遵照设置的限制 ,从而减小上下文切换开销innodb_thread_concurrency。因为SQL语句(例如join)可能包含多个行操做,因此InnoDB分配指定数量的 “ tickets ”,容许以最少的开销重复排列线程。

当一个新的SQL语句开始,当前线程没有“tickets”时,它就必须遵照innodb_thread_concurrency参数设置,一旦这个线程有权进入InnoDB,它会被分配一个“tickets”,它能够经过这个“tickets”用于随后进入InnoDB执行行操做,若是“tickets”使用完毕,该线程将会被驱逐,innodb_thread_concurrency参数会被放回到先入/先出队列中等待的线程等待再次观察。一旦这个线程再次有权进入InnoDB,“tickets”又会被从新分配,咱们能够经过设置全局参数innodb_concurrency_tickets来指定“tickets”的数量,默认状况下是5000。正在等待获取锁的线程,一旦锁可用,会被当即分配一个“tickets”。

这些参数的正确值取决于当前系统环境和负载状况。尝试各类不一样的值,以肯定哪些值适用于当前应用程序。在限制并发执行的线程数以前,在多核及多处理器的计算机上,检查一下InnoDB的配置参数是否能够改善性能,好比innodb_adaptive_hash_index。

3、innodb_thread_concurrency&innodb_thread_sleep_delay&innodb_concurrency_tickets

这三个参数的配合使用就是这样的一个故事(看网上一个哥们写的,摘抄下来)

一个屋子内有一个头牌妓女叫Innodb, 你们都想接近她.

老鸨(MySQL)不可能容许那么多人同时进屋去,就限制每次只能进去几个(上下和手嘛..),这个限制的名字就叫(innodb_thread_concurrency).

其余的人怎么办,只能在外面排成长队依次进入.同时老鸨说,大爷大家能够睡一会,这样就不用苦苦等待了.

这里老鸨就会个一段时间(innodb_thread_sleep_delay)叫醒一位大爷,以避免睡不醒了.

老鸨也怕老是叫醒大爷很差交代,就看快到了再叫,老鸨本身发明了一个自适应的叫醒算法,可以尽可能减小唤醒次数.

可是大爷会规定一个最长唤醒时间,就是必须在这样的时间(innodb_adaptive_max_sleep_delay)时唤醒我.

如此当有人从内部出来之后,等待的大爷(排在最前面的)就能够进入享受鱼水之欢了.

可是每位大爷可以支持的时间不同,有的一分钟(quicker),有的大爷须要几个小时.这样外面等待的大爷就会有意见,哎呀,怎么还不出来.

老鸨又想了一个办法,规定每一个人不能在姑娘房里呆10分钟以上(innodb_concurrency_tickets), 有特别持久的人就须要在10分钟时出来,在继续排队(排在队尾).

等到下一次轮到他再进行鱼水之欢.

人物对应:老鸨(MySQL), 大爷(threads), 姑娘(innodb)

如何优化innodb_concurrency_tickets,那就得看哪位大爷重要,好比宰相的儿子在这里等,那宰相的儿子又十分持久,最好就用多点时间(增大innodb_concurrency_tickets)

若是宰相的儿子不持久,那就用小时间快点排到他。

4、innodb_thread_concurrency使用建议

在官方文档上,对于innodb_thread_concurrency的使用,也给出了一些建议,以下:

若是一个工做负载中,并发用户线程的数量小于64,建议设置innodb_thread_concurrency=0;

若是工做负载一直较为严重甚至偶尔达到顶峰,建议先设置innodb_thread_concurrency=128,并经过不断的下降这个参数,96, 80, 64等等,直到发现可以提供最佳性能的线程数,例如,假设系统一般有40到50个用户,但按期的数量增长至60,70,甚至200。你会发现,性能在80个并发用户设置时表现稳定,若是高于这个数,性能反而降低。在这种状况下,建议设置innodb_thread_concurrency参数为80,以免影响性能。

若是你不但愿InnoDB使用的虚拟CPU数量比用户线程使用的虚拟CPU更多(好比20个虚拟CPU),建议经过设置innodb_thread_concurrency参数为这个值(也可能更低,这取决于性能体现),若是你的目标是将MySQL与其余应用隔离,你能够考虑绑定mysqld进程到专有的虚拟CPU。可是须要注意的是,这种绑定,在myslqd进程一直不是很忙的状况下,可能会致使非最优的硬件使用率。在这种状况下,你可能会设置mysqld进程绑定的虚拟CPU,容许其余应用程序使用虚拟CPU的一部分或所有。

在某些状况下,最佳的innodb_thread_concurrency参数设置能够比虚拟CPU的数量小。按期检测和分析系统,负载量、用户数或者工做环境的改变可能都须要对innodb_thread_concurrency参数的设置进行调整。

相关文章
相关标签/搜索