【案例】常驻查询引发的thread pool 性能问题之一

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS MySQL,高可用系列 2核4GB
简介: 一 问题现象    线上某业务A的数据库版本MySQL 从5.5 升级到5.6 版本之后多次出现RT抖动的问题,其现象主要为:     1 rt严重不稳定,部分query rt非常高。
问题现象
    线上某业务A的数据库版本MySQL 从5.5 升级到5.6 版本之后多次出现RT抖动的问题,其现象主要为:
    1 rt严重不稳定,部分query rt非常高。
    2 orzdba间歇性阻塞。

二 原理知识

    在MySQL Thread Pool根据参数thread_pool_size被分为若干个group,每个group维护client 发起的 connections,当MySQL建立 connection 时, MySQL 根据connection的thread id 对thread_pool_size取模,将connection 发起的sql 语句分配到对应的group。每个group的最大worker数量为thread_pool_oversubscribe+1。若worker达到最大数量后还是不足以处理回话请求,则连接在本group上等待,导致sql 语句的rt 增大。

三 问题分析
     目前线上的配置参数thread_pool_size为32,thread_pool_oversubscribe 为3 ,也即是ThreadPool共有32个group,每个group最多可容许4个worker。 但是业务A的场景中存在6个binlog dump任务和2个从库和1个日志抓取任务,因为COM_BINLOG_DUMP命令是个执行时间非常长的命令(可以理解为slow query),因此其长期持有worker。 当一个group被2个及以上COM_BINLOG_DUMP命令长期持有的时候,相对于其他group其处理能力会下降到其他group的1/2甚至1/4,最严重的会导致完全阻塞一个group。
Thread Pool本身没有存在group之间的均衡策略,因此新的连接还是会均匀的分配到所有的group上,当负载较大的时候,被COM_BINLOG_DUMP占有的group出现了严重的排队现象。
    在业务A场景中排队时间大约在10-30秒之间,因此有部分query的rt达到10-30秒;而大部分query还是被分配到正常的group上,其rt还是正常的。 根据观察,一般拥堵的group在1-2个之间,因此影响1/32 ~ 1/16的query .

四 验证
      根据以上的原理,为了更好的复现,将thread_pool_oversubscribe调整为2,即每个group有2个worker;同时将thread_pool_size调整为3.
通过锁表阻塞的方法模拟落在group 1的2个COM_BINLOG_DUMP,此时group 1只剩下1个worker,而group 0和group 2还剩在3个worker。
并发向mysql发送select sleep(2),来模拟业务
case 1
 
同一时间并发发起18个query。这时每个group分到6个query。因为g0和g2都有3个worker,因此这些query在4秒钟时处理完毕,但是g1只有1个worker,需要12秒
测试结果如下:符合预期

  1. [root@rac1:/u01/test]$sh test_rt.sh 
  2. Sun Oct 12 15:13:42 CST 2014
  3. Sun Oct 12 15:13:42 CST 2014
  4. Sun Oct 12 15:13:42 CST 2014
  5. Sun Oct 12 15:13:42 CST 2014
  6. Sun Oct 12 15:13:42 CST 2014
  7. Sun Oct 12 15:13:42 CST 2014
  8. Sun Oct 12 15:13:42 CST 2014
  9. Sun Oct 12 15:13:44 CST 2014
  10. Sun Oct 12 15:13:44 CST 2014
  11. Sun Oct 12 15:13:44 CST 2014
  12. Sun Oct 12 15:13:44 CST 2014
  13. Sun Oct 12 15:13:44 CST 2014
  14. Sun Oct 12 15:13:44 CST 2014
  15. Sun Oct 12 15:13:44 CST 2014
  16. Sun Oct 12 15:13:46 CST 2014
  17. Sun Oct 12 15:13:48 CST 2014
  18. Sun Oct 12 15:13:50 CST 2014
  19. Sun Oct 12 15:13:52 CST 2014
case 2:
     开始时发起6个query,以后每隔2秒并发发起3个query。 因为每个query本身耗时2秒,因此对于g0和g2完全能够处理这种并发,但是g1只有1个worker,因此永远都有一个query需要等待,所以被分配到g1上的query都需要等待2秒后才能被执行。
这个时候开启orzdba就会发现有1/3的概率被hang住2秒。线上出现的就是这种现象。

五 解决
1 系统层面 通过改大thread_pool_oversubscribe和thread_pool_size可以极大的减小这种现象的发生,但是不能完全的避免;
同时大量的常驻长连接是否合理(业务A中有9个拉binlog的连接常驻),也值得商榷(减少常驻连接也可以极大的减小这种现象的发生)。
2 源码设计层面:针对类似于binlogdump 的常驻链接存在很多优化点,针对binlogdump 这种长连接优化worker持有策略或者计数方式。

感谢 江疑 同学的详细分析。
test_rt.sh 脚本内容
 
  1. #!/bin/bash
  2. function test()
  3. {
  4.     mysql.local -e \'select sleep(2)\' > /dev/null
  5.     date
  6. }

  7. function r1()
  8. {
  9.     for i in {1..18};
  10.     do
  11.         test &
  12.     done
  13. }

  14. function r2()
  15. {
  16.     for i in {1..3};
  17.     do
  18.         test &
  19.     done
  20. }

  21. function r3()
  22. {
  23.     for i in {1..9000};
  24.     do
  25.         r2
  26.         sleep 2
  27.     done
  28. }

  29. r1



相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
3月前
|
存储 设计模式 Java
Go - 使用 sync.Pool 来减少 GC 压力
Go - 使用 sync.Pool 来减少 GC 压力
64 0
|
存储 SQL 缓存
细说MySQL中磁盘与CPU的交互——神秘的Buffer Pool
MySQL是如何读取记录的?Buffer Pool缓存功不可没!什么是Buffer Pool?它的结构是什么样的?当数据不断的读取,缓存的数据如何更新?本文将带你详细了解这些!
138 0
细说MySQL中磁盘与CPU的交互——神秘的Buffer Pool
|
缓存 监控 算法
案例15-创建大量对象导致cpu飙升
创建大量对象导致cpu飙升
210 0
|
缓存 安全 Java
GoFrame gpool 对象复用池 | 对比sync.pool
要介绍gpool对象复用池之前,大家有必要先了解一下go原生提供的sync.pool。
226 0