Py学习  »  DATABASE

MySQL 内核深度优化

IT技术精选文摘 • 5 年前 • 470 次点击  

MYSQL数据库适用场景广泛,相较于Oracle、DB2性价比更高,Web网站、日志系统、数据仓库等场景都有MYSQL用武之地,但是也存在对于事务性支持不太好(MySQL 5.5版本开始默认引擎才是InnoDB事务型)、存在多个分支、读写效率瓶颈等问题。


一.内核性能的优化


由于腾讯云上的DB基本都需要跨园区灾备的特性,因此CDB for MySQL的优化主要针对主从DB部署在跨园区网络拓扑的前提下,重点去解决真实部署环境下的性能难题。经过分析和调研,我们将优化的思路归纳为:“消除冗余I/O、缩短I/O路径和避免大锁竞争”。以下是内核性能的部分案例:


1.主备DB间的复制优化


问题分析


如上图所示,在原生MySQL的复制架构中,Master侧通过Dump线程不断发送Binlog事件给Slave的I/O线程,Slave的I/O线程在接受到Binlog事件后,有两个主要的动作:


  • 写入到Relay Log中,这个过程会和Slave SQL线程争抢保护Relay Log的锁。

  • 更新复制元数据(包含Master的位置等信息)。


优化方法


经过分析,我们的优化策略是:


优化效果

如上图所示,经过优化:左图35.79%的锁竞争(futex)已经被完全消除;同压测压力下,56.15%的文件I/O开销被优化到19.16%,Slave I/O线程被优化为预期的I/O密集型线程。


2.主库事务线程和Dump线程间的优化


问题分析


如上图所示,在原生MySQL中多个事务提交线程TrxN和多个Dump线程之间会同时竞争Binlog文件资源的保护锁,多个事务提交线程对Binlog执行写入,多个Dump线程从Binlog文件读取数据并发送给Slave。所有的线程之间是串行执行的!

优化方法


经过分析,我们的优化策略是:

  • 将读写分离开来,多个写入的线程还是在锁保护下串行执行,每一个写入线程写入完成后更新当前Binlog的长度信息,多个Dump线程以Binlog文件的长度信息为读取边界,多个Dump线程之间并行执行。以这种方式来让复制拓扑中的Dump线程发送得更快!

效果


经过测试,优化后的内核,不仅提升了事务提交线程的性能,在Dump线程较多的情况下,对主从复制性能有较大提升。

二.主备库交互流程优化

问题分析

如上图所示,在原生MySQL中主备库之间的数据发送和ACK回应是简单的串行执行,在上一个事件ACK回应到达之前,不允许继续发送下一个事件;这个行为在跨园区(RTT 2-3ms)的情况性能非常差,而且也不能很好地利用带宽优势。

优化方法

经过分析,我们的优化策略是:

  • 将发送和ACK回应的接收独立到不同的线程中,由于发送和接收都是基于TCP流的传输,所以时序性是有保障的;这样发送线程可以在未收ACK之前继续发送,接受线程收到ACK后唤醒等待的线程执行相应的任务。

效果

根据实际用例测试,优化后的TPS提升为15%左右。


三.内核功能的优化


1. 预留运维帐号连接数配额

2. 主备强同步


针对一些应用对数据的一致性要求非常高,CDB在MySQL原生半同步的基础上进行了深度优化,确保一个事务在主库上提交之前一定已经复制到至少一个备库上。确保主库宕机时数据的一致性。


四.外围系统的优化


除了以上提到的MySQL内核侧的部分优化,我们也在外围OSS平台进行了多处优化。例如使用异步MySQL ping协议实现大量实例的监控、通过分布式技术来加固原有系统的HA/服务发现和自动扩容等功能、在数据安全/故障切换和快速恢复方面也进行了多处优化。

公众号推荐:



今天看啥 - 高品质阅读平台
本文地址:http://www.jintiankansha.me/t/CtGUB5HKjf
Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/13466
 
470 次点击