加入收藏 | 设为首页 | 会员中心 | 我要投稿 应用网_丽江站长网 (http://www.0888zz.com/)- 科技、建站、数据工具、云上网络、机器学习!
当前位置: 首页 > 服务器 > 安全 > 正文

腾讯云布道师:一次性能峰值提升10W的DB调优之旅

发布时间:2021-01-08 06:42:53 所属栏目:安全 来源:网络整理
导读:副标题#e# 《腾讯云布道师:一次性能峰值提升10W的DB调优之旅》要点: 本文介绍了腾讯云布道师:一次性能峰值提升10W的DB调优之旅,希望对您有用。如果有疑问,可以联系我们。 作者:张青林,腾讯云布道师、MySQL架构师,隶属腾讯TEG-基础架构部-CDB内核开发
副标题[/!--empirenews.page--]

《腾讯云布道师:一次性能峰值提升10W的DB调优之旅》要点:
本文介绍了腾讯云布道师:一次性能峰值提升10W的DB调优之旅,希望对您有用。如果有疑问,可以联系我们。

作者:张青林,腾讯云布道师、MySQL架构师,隶属腾讯TEG-基础架构部-CDB内核开发团队,专注于MySQL内核研发&相关架构工作,有着服务多个10W级QPS客户的数据库优化及稳定性维护经验.

腾讯云数据库团队:继承腾讯数据库团队十多年海量存储的内部数据库运营和运维经验,推出一系列高性能关系型、分布式、文档型和缓存类数据库产品,并提供高可用性、自动化运维和易维护的云数据库综合解决方案.

前言

经过周末两天的折腾,在大家的帮助下最终将用户DB的性能峰值由最初的不到7W的QPS+TPS提升至17W,心情也由最初的忐忑过渡到现在的平静,现在想来,整个的优化过程感觉还是比较好玩的,趁着现在还有些印象,就把整个排查&优化过程详细记录下来,以备不时之需,也希望能给其他人一些启发.

问题背景

上周团队聚餐时,老大说有一个用户使用DB的时候遇到了问题,现有的DB性能无法满足用户的性能需求.用户在对现有的DB进行压力测试时发现QPS+TPS小于7W/S,继续加大压力的时候Load上涨、IdleCPU很低、Threadrunning飙升、性能下降,最终导致网站处理并发能力的下降,无法达到预期的吞吐量.

用户在对现有逻辑及吞吐量计算的基础上提出了性能指标,即DB的单机性能QPS+TPS大于10W/S,只有这样才能满足业务要求,否则DB就是整个链路的瓶颈.

由于用户的上线时间临近,上线压力比较大,老大说周末尽力搞定,如果搞不定,只能上最好的机器来解决性能问题,这样的话,成本就要上来了.(当时正在吃饭,瞬间感觉压力山大,不能好好吃肉了有木有……)

现场信息收集

第二天还没醒就收到老大的RTX消息,然后怀着疑惑的心情火速上线,登录到机器上,开始了DB性能的调优之旅……

首先,使用orzdba监控工具查看了用户实例的性能状态,如下所示:

从上面的性能信息可以发现命中率 100%,即用户基本是全内存操作,thread running 较高,CPU 有少量,thread running 彪升,到底线程在做什么呢?

怀着这样的疑问,然后执行了一下 pstack {pid of mysqld} > pid.info 以获取实例的内部线程信息,然后使用 pt-pmp pid.info 将堆栈信息进行显示,发现了如下的信息:

根据上述的 pt-pmp & pstack 文件相结合,可以看到如下堆栈:

根据上面收集的信息我们可以清楚的得出以下结论:

  • 应用在执行SQL语句的过程中,table_cache_manager 中的锁冲突比较严重;
  • MySQL Server?层中的 MDL_lock 冲突比较重;
  • 实例开启了 Performance_schema 功能;

经过了上面的分析,我们需要着重查看上述问题的相关变量,变量设置的情况会对性能造成直接的影响,执行结果如下:

参数分析

这里我们先来介绍一下上述参数在 MySQL 中的作用 & 含义:

table_open_cache_instances 简介

table_open_cache_instances 指的是 MySQL 缓存 table 句柄的分区的个数,而每一个 cache_instance 可以包含不超过table_open_cache/table_open_cache_instances 的table_cache_element,MySQL 打开表的过程可以简单的概括为:

  1. 根据线程的 thread_id 确定线程将要使用的 table_cache,即 thread_id % table_cache_instances;
  2. 从该 tabel_cache 元素中查找相关系连的 table_cache_element,如果存在转 3,如果不存在转 4;
  3. 从 2 中查找的table_cache_element 的 free_tables 中出取一个并返回,并调整 table_cache_element 中的 free_tables & used_tables 元素;
  4. ?如果 2 中不存在,则重新创建一个 table,并加入对应的 table_cache_element 的 used_tables的列表;

?从以上过程可以看出,MySQL 在打开表的过程中会首先从 table_cache 中进行查找有没有可以直接使用的表句柄,有则直接使用,没有则会创建并加入到对应的 table_cache 中对应的 table_cache_element 中,从刚才提取的现场信息来看,有大量的线程在查找 table_cache 的过程中阻塞着了,而 table_open_cache_instances 的个数为 1,因此,此参数的设置需要调整,由于 table_open_cache_instances 的大小和 线程 ID & 并发 有关系,考虑当前的并发是1000左右,于是将该植设置为 32;

MySQL 中不同的线程虽然使用各自的 table 句柄,但是共享着同一个table_share,如果想从源码上了解 table & table_share 以及 两者之间的相互,可以从变量 table_open_cache,table_open_cache_instances,table_definition_cache 入手,阅读 Table_cache_manager,Table_cache,Table_cache::get_table 等相关代码,由于篇幅限制,在此不在详述.

MDL Lock 的前世今生

?在 5.1 中有一个 binlog log 乱序的问题,详情及复现方法可以参考这篇文章:《alter table rename 操作导致复制中断》(http://mysqllover.com/?p=93),MDL_LOCK 就是为了解决上述问题而在 5.5 中引入的.

(编辑:应用网_丽江站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读