参数调优 -- 并发参数innodb_thread_concurrency

innodb_thread_concurrency

innodb_thread_concurrency是动态参数可以随时修改
64个活跃连接以内直接配0
高压场景需要从高到低测试,找到最优值
高压场景下较低的值可以明显提高写入QPS的占比(高频率的读被限制了)
innodb_thread_sleep_delay(微秒)

定义在开始排队前,等多久加入队列
innodb_adaptive_max_sleep_delay(微秒)

配置innodb_thread_sleep_delay允许的最大值,配了之后innodb会自动调整innodb_thread_sleep_delay的值到一个合适的范围内(自适应算法)
innodb_concurrency_tickets(默认5000)

使用小的值时小事务可以和大事务竞争,缺点是大事务要多次才能跑完

使用大的值时大事务有优势,缺点是可能让小事务一直得不到运行

调整这个值可以参考队列长度,长度从SHOW ENGINE INNODB STATUS来看( ROW OPERATIONS section of SHOW ENGINE INNODB STATUS output),也可以从INFORMATION_SCHEMA.INNODB_TRX的TRX_CONCURRENCY_TICKETS来看。

innodb_thread_concurrency限制后活跃连接状态不会变,从innodb_trx能看出来事务是不是在排队,show engine innodb status的row部分也能看出来

对于长短事务的场景应该非常有帮助,适当减少ticket可以让短事务更容易被执行,按下面测试场景来说,一个5读SQL的事务,一个5读3写SQL的事务,两个事务长度基本相同,如果用系统线程调度的话,执行快的事务执行的频率会更高。如果打开排队,每个事务拿着相同的ticket进入innodb,执行次数会更公平。所以可以看到写的次数明显升高了。

sysbench的测试场景来说,读影响不是很大

  

1.官方使用建议
在官方文档上,对于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参数的设置进行调整。

2.笔记

tickets可以理解为MySQL层和Innodb层交互的次数,比如一个select一条数据就是需要Innodb层返回一条数据然后MySQL层进行where条件的过滤然后返回给客户端,抛开where条件过滤的情况,如果我们一条语句需要查询100条数据,那么实际上需要进入Innodb层100次,那么实际上消耗的tickets就是100。当然对于insert select这种操作,需要的tickets是普通select的两倍,因为查询需要进入Innodb层一次,insert需要再次进入Innodb层一次。

这样我们也就理解为什么innodb_concurrency_tickets可以避免(长时间处理线程)长时间堵塞(短时间处理线程)的原因了。假设innodb_concurrency_tickets为5000(默认值),有一个需要查询100W行数据的大select操作和一个需要查询100行数据的小select操作,大select操作先进行,但是当查询了5000行数据后将丢失CPU使用权,小select操作将会进行并且一次性完成。

 

posted @ 2024-02-01 17:55  懒~人  阅读(302)  评论(0编辑  收藏  举报