前言
通常对MySQL进行深入了解,会从基础入手,从而循序渐进;但是本系列会从性能优化这个切点去深入MySQL原理内幕,但是这里有个前提是你已经有MySQL相关的实际开发经验或者比较熟练的掌握了MySQL的基本使用。
为什么要从性能优化这样的”高级“方面作为入口?
我们知道从基础来深入一门技术是枯燥的,学习周期也比较长,容易导致学习的目的性分散,同时如果没有很好的实践也是易忘的,需要反复回顾来加深印象,总的下来,学习成本会比较高。而对于掌握基本使用的人来说,从实际场景的角度下探进行深入学习,目的性更强,掌握的也会更牢固,效率会更高。
之前看到过一个技术的学习方法,很是认同:
接下里就让我们开始吧!
场景
实际开发中,不可避免的我们都会听过性能调优这样一个感觉很高级,貌似离我们也很遥远的词。在MySQL中,它的高级就在于短短四个字却是浓缩了MySQL架构及所有功能的原理;而遥远在于没有实际业务场景的需要或者人为技术要求。
现在我们就来“暴力''拉进和它距离,作为一个已经工作几年的Java开发,这天和往常一样上班开机摸鱼,突然架构师过来了,他觉得你技术能力不错,要求你负责另一个项目的开发以及使用的MySQL数据库相关性能调优。
你没办法拒绝,虽然你知道自己对MySQL使用熟练,也了解不少相关功能,像索引、事务、读写分离、分库分表啊,但都是基础概念,并没有深入,同时对于性能调优除了知道索引外,完全不知道从哪个方面入手。
所以现在的场景就是:项目要求对MySQL进行性能调优。
需求
虽然有了场景,但是这个场景目前定义的比较大,那么我们接下来就要好好想想这个场景下可能会产生哪些需求?比如sql的慢查询、连接超时、内存、CPU使用率过高等等,但是在落实到这些具体的需求细节之前,我们需要先站在全局的角度下思考一下。
核心
首先我们要知道性能调优的核心是什么?或者说为了达到什么样的目标?不同的场景下可能每个人的说法都不相同,但是我们去优化数据库都是为了更好的去支撑上层业务,从而提高使用者的体验,这个使用者可能是用户,也可能是其他的应用,其实本质上归纳起来无非为两种:
- 减少响应时间:减少数据库每个增删改查操作的执行时间。
- 提高吞吐量:提高数据库单位时间内能够执行的操作数量。
维度
那为了达到上面的核心目标,我们应该从什么维度或者说哪些方面去进行性能调优?所以接下来会从三个维度去进行分析。
客户端优化
首先是客户端优化,作为开发人员,面临最多的数据库优化可能就是在这方面;甚至你经常会去做这些优化,但是却并没有真正的去深入了解它的原理,比如:
SQL语句 :通常业务中最常见的可能就是SQL的查询速度慢问题,那对它的优化,我们就需要从SQL的执行过程原理开始。
数据库连接池:项目中通常都已经配置好相应的数据库连接池,像Druid、HikariCP等,拿来即用;甚至可能你都不知道它是用来做什么的,或者你仅仅只知道它的作用却从来没有去重视过它。
服务端优化
接下来就是服务端优化,对于开发来说,可能最少的就是去关注MySQL的安装及部署,通常根据官方文档网或者网上的一些博客的教程去直接安装部署使用了,对于部署的服务器可能也是随便找一个可用的Linux系统,而并不清楚它的具体配置(导致开发中可能经常背锅之一,碰到偶现的慢sql等问题的时候就会吐槽数据库服务器配置太辣鸡了,另一个锅可能就是网络问题)。其实不然,服务端对于数据库的性能来说也是非常重要的,通常可以从以下两个方面去优化:
硬件与操作系统:它对于我们来说是最容易想到理解的,因为我们知道像MySQL的服务器这样的程序应用的前提就是需要硬件和操作系统的承载。而像内存、CPU、磁盘、网络等配置直接从物理层面限制了服务器的性能。所以有选择的合适配置,对于MySQL的性能提升往往是最直接的。
MySQL的配置:MySQL的配置文件中支持很多的配置项,同时很多重要的配置也帮我们设置了默认值,通常让我们无需修改就可以正常部署使用;但是这也代表了默认配置并不是适用于当前项目及系统的最佳配置,导致我们不能完全的发挥出它的所有性能。
架构层优化
最后就是架构层面的优化,相信对于开发人员来说,这可能也是最去关注的。通常根据项目的实际业务需求,会有下面几个方面的优化:
表结构与存储引擎:相信我们都知道数据库表的结构设计对于业务来说是非常重要的,良好的表结构设计也是高性能的基石,可以有效地避免资源的浪费,以及带来很好的性能提升。同时MySQL中的表支持多种存储引擎,每种存储引擎的设计都有各自的特点,最常用的就是默认的InnoDB;而针对不同的表使用的不同存储引擎都有各自的选择及优化。
应用层方案:相对于把所有压力都放到数据库来说,在应用层面的同样有有很多方式来进行优化,从而达到尽量减轻数据库服务器的压力,也是一种对数据库的调优,利用像缓存、限流、异步等方案。
读写分离:对于项目中读多写少的业务,可以利用读写分离的方案去解决数据库的读瓶颈,通过分为主、从库,其中主库用于写操作,从库通过数据的复制同步用于读操作的方式,解决数据库事务隔离级别中的读写锁的竞争冲突,分摊了数据库的压力,从而提升数据库的性能,但是主从复制的机制也会带来数据延时的问题。
分库分表:按照业务去拆分数据库为垂直分库,把单张表数据按照一定规则拆分到不同表中为水平分表;这样的拆分操作可以通过分而治之,来减少单个数据库节点的访问压力,以及单个表数据的存储压力。
高可用方案:如果数据库意外宕机了,或者某个节点挂了无法提供访问,就会导致吞吐量下降,甚至完全无法响应,所以高可用都样也是数据库高性能的基础。像传统基于主从复制的HAProxy+keepalived方案、NDB Cluster、Galera多主同步复制的集群方案、MMM方案、以及MySQL5.7版本推出的InnoDB集群MGR方案等。
总结
本文基于MySQL性能调优的场景,在需要调优的具体需求之上进行了多维度的分析,仅仅只是抛砖引玉,后面会针对这些维度的调优来慢慢深入MySQL原理内幕。
文章中如有不妥之处,请批评指正,非常感谢。
把一件事做到极致就是天分!