x86、arm指令都很多,无论是应用程序员还是数据库内核研发大多时候都不需要对这些指令深入理解,但是 Pause 指令和数据库操作太紧密了,本文通过一次非常有趣的性能优化来引入对 Pause 指令的理解,期望可以事半功倍地搞清楚 CPU指令集是如何影响你的程序的。
文章分成两大部分,第一部分是 MySQL 集群的一次全表扫描性能优化过程; 第二部分是问题解决后的原理分析以及Pause指令的来龙去脉和优缺点以及应用场景分析。
为理解方便做了部分简化:
client -> Tomcat -> LVS -> MySQL(32 个 MySQLD实例集群,每个实例8Core)
通过 client 压 Tomcat 和 MySQL 集群(对数据做分库分表),MySQL 集群是32个实例,每个业务 SQL 都需要经过 Tomcat 拆分成 256 个 SQL 发送给 32 个MySQL(每个MySQL上有8个分库),这 256 条下发给 MySQL 的 SQL 不是完全串行,但也不是完全并行,有一定的并行性。
业务 SQL 如下是一个简单的select sum求和,这个 SQL在每个MySQL上都很快(有索引)
SELECT SUM(emp_arr_amt) FROM table_c WHERE INSUTYPE='310' AND Revs_Flag='Z' AND accrym='201910' AND emp_no='1050457';
● 后述或者截图中的逻辑RT/QPS是指 client 上看到的Tomcat的 RT 和 QPS;
● RT :response time 请求响应时间,判断性能瓶颈的唯一指标;
● 物理RT/QPS是指Tomcat看到的MySQL RT 和QPS(这里的 RT 是指到达Tomcat节点网卡的 RT ,所以还包含了网络消耗)
通过client压一个Tomcat节点+32个MySQL,QPS大概是430,Tomcat节点CPU跑满,MySQL RT 是0.5ms,增加一个Tomcat节点,QPS大概是700,Tomcat CPU接近跑满,MySQL RT 是0.6ms,到这里性能基本随着扩容线性增加,是符合预期的。
继续增加Tomcat节点来横向扩容性能,通过client压三个Tomcat节点+32个MySQL,QPS还是700,Tomcat节点CPU跑不满,MySQL RT 是0.8ms,这就严重不符合预期了。
性能压测原则:
加并发QPS不再上升说明到了某个瓶颈,哪个环节RT增加最多瓶颈就在哪里
到这里一切都还是符合我们的经验的,看起来就是 MySQL 有瓶颈(RT 增加明显)。
现场DBA通过监控看到MySQL CPU不到20%,没有慢查询,并且尝试用client越过所有中间环节直接压其中一个MySQL,可以将 MySQL CPU 跑满,这时的QPS大概是38000(对应上面的场景client QPS为700的时候,单个MySQL上的QPS才跑到6000) 所以排除了MySQL的嫌疑(这个推理不够严谨为后面排查埋下了大坑)。
那么接下来的嫌疑在网络、LVS 等中间环节上。
首先通过大查询排除了带宽的问题,因为这里都是小包,pps到了72万,很自然想到了网关、LVS的限流之类的
pps监控,这台物理机有4个MySQL实例上,pps 9万左右,9*32/4=72万
最终所有网络因素都被排除,核心证据是:做压测的时候反复从 Tomcat 上 ping 后面的MySQL,RT 跟没有压力的时候一样,也说