MySQL工作有多努力--了解MySQL Threads Running

文章目录

正文

    每秒查询次数(Queries per second,QPS)可以衡量数据库的吞吐量,但不能反映MySQL的工作强度。后者由Threads_running度量,表示为量表(而QPS是速率)。在讨论Threads_running之前,让我们考虑一个类比:
在这里插入图片描述
    上图是来自汽车的数字仪表板。左边的大圆圈是车速表,右边的大圆圈是转速表。车速表是大多数人所熟悉的:它们显示汽车行驶的速度。在上面,车速表的读数为84 km/h。转速表很常见,但并不是每个仪表盘都包含转速表。它们显示了发动机的工作强度,以每分钟转数(RPM)为单位。在上面,转速表的读数接近3,000 RPM。(转速表中间的“ M3”是变速箱齿轮。我们可以忽略这一点)
    QPS与速度(84 km/h)类似,而Threads_running与RPM(〜3k RPM)类似。
    速度和RPM的变化受多种因素的影响:加速和减速,上坡或下坡,逆风或逆风,以及(在越来越多的新车中)计算机编程可优化燃油经济性。因此,在不同的转速下可以达到相同的速度,但是通常汽车在较低的转速下燃烧较少的燃料,而在较高的转速下燃烧较多的燃料。同样,较高的RPM意味着发动机上的应力更大,从而增加了机械故障的机会。我们关心燃烧燃料和机械故障,因为两者都使我们付出了金钱。这就是为什么汽车配备转速表的原因:RPM是一项重要指标。
    QPS 和 Threads_running 也因许多因素而有很大差异:硬件规格(CPU内核和速度,存储类型和IOPs等),查询类型(读或写),查询计划,表大小,行大小,表模式(列类型,索引-特别是索引),数据访问模式(全读或全写或混合),“嘈杂的邻居”,一天中的时间(例如营业时间),一年中的时间(例如纳税季节),特殊促销,糟糕的演员,等等-随便你说吧!因此,与汽车一样,相同的QPS可以在不同的Threads_running上实现,因此这是一个重要的指标。
    Threads_running表示MySQL的工作强度。我工作的几个数据库仅运行10个线程即可完成10,000 QPS。其他人则需要运行100个线程才能达到3,000 QPS。从前面的段落中,我们知道原因:各种变化的因素。
    仅QPS不能告诉我们MySQL是否在给系统施加压力,或者,形象的说,它是否开始烧油并停止运转。
监视和处理运行中的高Threads_running是至关重要的。转速表有一个最大值,你通常不能把车推到它之外,但是MySQL非常有野心:它没有最大值,它会根据需要运行尽可能多的线程。它会尝试,但会随着Threads_running的增加而变慢并最终失败:

Threads_running MySQL
0 - 10 Normal:几乎所有硬件都没问题
10 - 30 Busy:大多数硬件通常都可以,因为服务器多核
30 - 50 High:很少有工作负载需要运行这么多线程。它可以短期爆发(<5min),但如果持续时间较长,则响应时间很可能很慢
50 - 100 Overloaded:某些硬件可以处理此问题,但是不能期望在此范围内成功运行。对于我们的本地部署硬件而言,此范围内的瞬时突发(<5s)通常是可以的。
> 100 Failing:在极少数情况下,MySQL可以运行大于100个线程,但在此范围内可能会失败

    建议指导值:

  • Threads_running < 50
  • 1:1000 Threads_running:QPS

    让我们换个角度来阐明一个重要的问题:MySQL线程是一个数据库连接。Threads_running是活动查询的数据库连接数。请记住,每个应用程序实例都有其自己的数据库连接池,这一点很重要。因此,最大可能的连接(线程)为:

Max Connections = App 实例数 * 数据库连接池大小

    连接池大小为100是合理的,但是如果将应用程序部署到5个应用程序实例,则可能有500个数据库连接。通常是这样:应用程序通常具有数百个空闲数据库连接,这是连接池的用途。(对连接的线程,MySQL也有一个尺度)直到同时运行过多的连接(线程),这才成为问题。
    一个应用程序不止一次被扩展(即部署更多的应用程序实例)以处理更多的请求,但这样做会使数据库过载,运行的线程太多。没有快速或简单的解决方案来解决这种类型的数据库性能限制。原因很简单:如果您希望MySQL在相同的时间(每秒)内执行更多的工作(查询),则每个工作必须花费较少的时间,否则无法进行计算。如果每个查询花费100毫秒,则执行速度不可能超过10QPS。您问:“啊,但是要是使用更多的CPU内核呢?”
    明白了!使用另一个CPU内核意味着运行另一个线程,现在我们正朝着一个更低的上限快速前进:运行50个线程。但这正是MySQL试图做的。如前所述,MySQL非常雄心勃勃:它没有设置Threads_running的最大值,它将根据需要运行尽可能多的线程。QPS的上限(如果存在)非常高,而Threads_running的上限非常低。为什么是这样?
    运行50个线程是一个合理的要求。到2020年,甚至应该运行1,000个线程。让我用另一个问题回答这个问题:为什么丰田没有法拉利的速度和力量?丰田的最高时速为 200km/h,法拉利的最高时速为 340km/h。为什么丰田不能跑得更快呢?为什么MySQL不能走得更快?
    两者的答案在工程的每一个细节上。例如,法拉利跑得很快,因为它有一个非常强大的引擎,但你不能只关注这里。这辆车的每一个细节都设计得既能提供动力,又不会在动力之下断裂。例如,飞机可以以258公里/小时的速度起飞和飞行,因此一辆时速340公里的法拉利将能飞行,除非其车身的空气动力学使它保持在地面上。如果设计成这样,丰田汽车的时速可以达到340公里,而MySQL可以运行1000个线程。
    像丰田一样,MySQL构建良好、可靠,而且超出了您的需要,但它本身或其周围的任何硬件、操作系统和应用程序都不是设计成法拉利的。
    实际经验表明,对于运行50个线程以上的大多数应用程序,MySQL的性能不佳。早在2014年,MySQL专家Alexey Straganov就对MySQL5.6进行了基准测试,测试运行的Threads_running非常高:Percona Server: Improve Scalability with Percona Thread Pool。在运行64个threads running时性能达到峰值。这些是实验结果,实际的应用程序查询比综合基准查询更具挑战性。
    解决方案?通过分片扩展数据库。但这是另一个漫长的话题。
    让我们以积极的结尾结束。Vadim Tkachenko也许是全球MySQL性能方面的最杰出专家,他最近实现了100,000个线程的运行:MySQL Challenge: 100k Connections

参考文档

[1]Daniel Nichter.MySQL Threads Running How Hard is MySQL Working?[EB/OL].https://hackmysql.com/post/mysql-threads-running-how-hard-is-mysql-working/,2020-04-25.
[2]Oracle Corporation.Server Status Variables[EB/OL].https://dev.mysql.com/doc/refman/8.0/en/server-status-variables.html,2021-01-01.

猜你喜欢

转载自blog.csdn.net/zsx0728/article/details/114536258
今日推荐