解DBA之惑:数据库承载能力评估及优化手段

做为DBA,有时会被挑战相似这样的问题:数据库

  • 若是现有业务规模增长10倍、100倍,数据库是否可以支撑?
  • 下个月咱们搞大促,数据库这边没问题吧?
  • 计划进行去O工做,代码逻辑不变,数据库从Oracle切换到MySQL,MySQL能支撑业务吗?
  • 服务器采购选型,到底哪款服务器更适合咱们呢?

面对诸如上面的这些质疑,DBA应该如何面对?segmentfault

身为DBA该如何评估现有资源使用状况?缓存

若是现有数据库资源确实没法支撑,又该本着什么原则进行改造呢?性能优化

本文是针对上面问题的一些经验总结,供你们参考。服务器

1、评估工做

面对这样的问题,首先要进行评估工做,可遵循下面的步骤:架构

一、创建性能基线

针对系统运行现状,创建性能基线。将业务指标与性能指标创建起对应关系。这里所说的性能指标包括CPU、MEM、DISK、NET等。在诸多资源中,确定存在不均衡的状况,短板的资源最有可能成为业务增加后的瓶颈。在具体操做上,可首先肯定一个业务高峰时间段,经过监控平台或监控工具收集系统各资源的使用状况。而后依据收集的信息,分析可能的性能短板在哪里。 app

对于DBA来讲,对本身掌管系统的性能使用状况要了然于胸。经过对业务的了解,将业务指标映射到性能指标上,就能够很容易地推断出现有系统可承载的最大业务量。此外,对于可能影响承载业务增加的短板,也会有比较清晰的认识。 运维

通常来讲,数据库类的应用是重资源消耗类的应用。对CPU、MEM、DISK、NET等,均有较大的消耗。但因为不一样硬件发展水平不均衡,各数据库资源消耗特色也不一样,所以须要具体问题具体分析。 分布式

下面谈谈我对硬件发展及与数据库关系的一点我的观点:工具

  • CPU

相对于其余硬件而言,CPU技术发展较快。随着CPU主频提升及多核CPU技术的发展,CPU提供的计算能力每每不会成为系统的性能瓶颈。但咱们须要注意的是,有些数据库是没法彻底利用CPU的能力(例如MySQL就是这样)。此时,为了充分利用CPU的资源,能够考虑诸如"多实例混跑"的方案,提升CPU利用率。

  • MEM

随着内存技术的发挥,内存的价格愈来愈便宜。如今咱们在生产环境中,能够见到12八、256GB,甚至TB级的内存也不罕见。通常来讲,数据库一般会利用内存做为缓冲区,大内存的配置对数据库的性能有着比较明显的提高。此外,数据库自身技术也在适应着大内存的场景,一般采用的策略是划分子池。将管理的单位进一步细分,例如Oracle中的Sub Pool、MySQL中的多instance buffer pool。

  • NET

随着GigE、10GbE、InfiniBand技术的飞速发展,低延迟、高带宽的服务品质给数据库乃至整个IT系统带来了不少变化。常见的应用领域有:

    • 加速分布式数据库,例如Oracle RAC。
    • 加速大数据处理,例如提高Hadoop MapReduce处理。
    • 存储架构的变革,从Scale-Up向Scale-Out演变。
    • 容灾方案,主备策略…
    • DISK

    相对于其余硬件技术发展而言,传统的机械式磁盘是相对而言发展最慢的,其每每也是最容易成为数据库的性能瓶颈。随着闪存技术的横空出世,为存储技术带来的一种变革。下面咱们来看看主要性能指标的对比:

    从上述指标来看,使用闪存技术后,存储能力大大提升,消除了系统最大的瓶颈。这也是为何不少DBA都在不一样场合,大力推荐使用闪存,其对于数据库性能的提高会带来质的飞跃。但与此同时,咱们也应该注意到,传统关系型数据库是按照磁盘IO模型设计的,没有考虑到闪存技术,如今属于软件落后于硬件的阶段;相对而言,闪存技术对于非关系型模型更有优点。

    不少基于传统设计的优化理论发生了变化,例如: 索引聚簇因子的问题。这一点是须要咱们在考虑数据库优化时,主要注意的。此外,NoSQL的性能优点由于传统数据库结合闪存技术,而变得不明显。须要在架构选择时加以分析。

    二、创建业务压力模型

    根据业务特征,创建业务压力模型。简单理解就是将业务模拟抽象出来,便于后面进行压力放大测试。要作到这一步,须要对业务有着充分的了解和评估。

    下面经过一个小例子说明一下:

    这个表格模拟了某个类电商的业务,其包含的主要模块及模块中的主要操做。针对不一样的操做其交易复杂度不一样 (交易复杂度可理解为执行SQL语句的个数)。根据不一样的读写状况,区分是数据读仍是数据写。在估算了业务总量(交易量)的状况下,很容易推算出数据操做的量。经过这种方式将业务压力模型转化为数据压力模型。此处的难点在于对业务逻辑的抽象能力及对模块业务量的比例评估。

    有了上述概览的表格后,针对每一种业务操做,可细化其操做。最终将其抽象成SQL语句及对应的访问特征。其伪代码可描述为

    可依据上述伪代码,编制压力测试代码。经过一些工具调用测试代码,产生模拟测试的压力。例如我常用的oradbtest/mydbtest(原阿里楼方鑫的一个测试工具)或sysbench等,都是不错的压力测试工具。

    建议企业根据自身状况,整理出本身的业务压力模型。这在系统改造、升级、扩容评估、新硬件选型等多种场合都颇有用处。它要比厂商提供的相似TPCC测试报告,更有意义。据我了解,不少规模较大的公司都有比较成熟的压力模型。

    三、模拟压力测试

    要想考察现有数据库可否承载增加后的业务压力,最好的方式就是模拟压力测试。观察在近似真实的压力下,数据库的表现。重点观察,数据库的承载力变化、主要性能瓶颈等。一般能够有两种方式,一种是从真实环境导流(并可根据须要放大流量,可利用相似TCPCOPY等工具);一种是根据前面整理的业务压力模型,经过压力工具模拟压力。前者适用于已有项目的扩容评估、系统改造评估等,后者适用于新上项目原型方案评估、性能基准测试等场景。

    上述模拟压力测试结果中,暴露出的性能瓶颈点,就是咱们后面须要着重改进、优化的方向。

    2、优化层次及步骤

    针对上面的评估结果,来肯定后面的改进、优化方案。可遵循以下一些步骤:

    一、分析瓶颈点

    根据上面的评测结果,分析性能瓶颈点。针对不一样瓶颈点,可采起不一样的一些策略。有时候性能测试时全流程的,对于一个复杂系统来讲,要明肯定位到性能瓶颈点比较困难。此时,可借助一些APM工具,量化整个访问路径,协助找到瓶颈。也能够相似上面的作法,作好抽象工做,只对数据库端施加压力,观察数据库行为,判读数据库是否为瓶颈。如判断就是数据库的承载能力不够,可按照不一样层次进行考虑。

    在整个评估数据库承载能力中,这一步骤是最复杂的、也是最难的一部分。要区分清楚是不是数据库承载能力不足,仍是其余组件的问题。即便明确是数据库的问题,也要分清楚是总体or局部的问题;是单一业务功能慢,仍是总体都比较慢;是偶尔会慢,仍是一直都很慢等等。这些问题的界定有助于后面明确问题层次,采起不一样的策略进行解决。

    针对数据库承载能力不足,我将常见出现问题进行了层次划分,可简单分为语句级、对象级、数据库级、数据库架构级、应用架构级、业务架构级。不一样层次采起的方式也有所不一样,下面分别描述一下。

    二、层次-语句级

    如性能核心问题,只是某条SQL语句的问题,可有针对性地进行优化。这种方式是侵入性比较小的一种优化方式,其影响范围也比较小。下面对比常见的语句级优化方法。说明一下,下面方法已经排除了诸如统计信息不许确等其余因素,仅从SQL语句自己优化方式考虑。

    • 改写SQL

    经过改写语句,达到调整执行计划,提升运行效率的目的。这种方式的缺点是须要研发人员修改原代码,而后再进行部署上线的过程。此外,有些使用O/R Mapping工具产生的SQL,没法直接修改语句,也没法使用此方法。

    • 使用Hint

    不少种数据库都提供了提示(Hint)的功能。经过这种方式来指定语句的执行过程。这种方式一样须要修改源代码,经历部署上线的过程。此外,这种修改方式还存在适应性较差的问题。由于其指定了特有的执行过程,随着数据规模、数据特征的变化,固化的执行过程可能不是最佳方式了。这种方式其实是放弃了优化器可能产生的最优路径。

    • 存储概要、SQL概要、计划基线

    在Oracle中还内置了一些功能,它们能够固化某一条语句的执行方式,从本质上来说,其原理和上面使用Hint差很少。其缺点也相似上面。

    • 调整参数

    有时也可经过调整某些参数,进而改变语句的执行计划。可是这种方式要注意适用范围,不要在全局使用,避免影响较多的语句。在会话级使用也要控制范围,避免产生较大影响。

    三、层次-对象级

    如性能核心问题,在SQL层面没法解决,须要考虑对象层面的调整。这种状况要比较慎重,须要充分评估可能带来的风险及收益。一个对象的结构修改,能够涉及到数百条、甚至数千条和此相关语句的执行计划变动。如不作充分测试的状况下,很难保证不出问题。若是是Oracle数据库,可考虑使用SPA评估一下。其余数据库的话,可提早手工收集一下相关语句,模拟修改后重放上述语句,评估性能变化。

    1)影响因素

    在对象级进行调整,除了考虑对其余语句的性能影响外,还须要考虑其余因素。常见的如下这些:

    • 数据库维护成本

    常见的例如索引。经过添加索引,每每能够起到加速查询的目的;可是增长索引,会致使数据DML成本的增长。

    • 运维成本

    常见的例如全局分区索引。全局分区索引在进行分区维护动做后,会致使索引失效,须要自动或手动进行维护索引动做。

    • 存储成本

    常见的索引,索引结构是数据库中真实占据空间的结构。在以往的一些案例中,甚至出现过索引总大小超过表大小的状况,所以新增时要评估其空间使用。

    2)全生命周期管理

    这里还有另一个很重要的概念——“对象全生命周期管理”,简单来讲就是对象的生老病死。在不少系统中,对象重新建开始,数据不断增长、膨胀,当数据规模达到必定量级后,各类性能问题就出现了。对一个百万级的表和亿万级的表,其查询性能确定不能同日而语。所以,在对象设计初期,就要考虑相关的归档、清理、转储、压缩策略,将存储空间的评估与生命周期管理一块儿考虑。

    不少性能问题,在作了数据清理后都迎刃而解。但数据清理每每是须要代价的,必须在设计之初就考虑这个问题。在作数据库评审的时候,除了常规的结构评审、语句评审外,也要考虑这部分因素。

    四、层次-数据库级

    到了这个层面,问题每每已经比较严重了。通常状况下,数据库的初始配置都是基于其上面运行系统的负载类型进行专门配置的。若是运行一段时间后,出现性能问题,经评估是属于全局性问题的,能够考虑进行数据库级别的调整。可是这种配置每每代价也比较大,例如须要专门的停机窗口操做等。并且这种操做的风险性也比较大,有可能会带来不少不肯定因素,所以要慎而又慎。

    五、层次-数据库架构级

    如性能核心问题,没法在上述层面解决,可能就须要调整数据库架构。常见的例如采起读写分离的访问方式、分库分表存储方式等。这种对应用的侵入性很强了,有些状况下甚至不亚于重构整个系统。

    例如,随着业务的发展,系统的数据量或访问量超出了预期,经过单一数据库没法知足空间或性能要求。此时,可能就须要考虑采用一种分库分表策略,来知足这部分的需求。但其改造难度,每每比从新开发一套系统还要大。

    好比,咱们可能须要一个数据中间层,来屏蔽后面的分库分表细节。这个中间层可能须要完成语句解析、访问路由、数据聚合、事务处理等一系列功能。即便使用了中间层产品,对于应用来讲,数据库的功能也会相对“弱化”,应用级代码不得不进行不少的调整来适应这种变化。此外,如何把一个线上正在运行的系统,顺利平稳地迁移到新的结构下,这无疑又是一个给飞驰的跑车换轮胎的问题等等。

    若是项目在运行中,出现了数据库架构级的调整,颇有可能说明在前期项目设计规划阶段出现了失误,或者对项目的业务预期出现了误差。所以,这两点必定在初始阶段进行充分的评估,并在设计上保留有充分的“弹性”。

    六、层次-应用架构级

    有些状况下,单纯依靠数据库是没法解决的,须要综合考虑整个应用架构。在整个系统架构中,数据库每每处于系统的最末端,其扩展性是最差的。所以,在应用架构设计初期,就应该本着尽可能不要对数据库产生压力的原则进行设计。或者即便有大的压力,系统能够采起自动降级等方式保证数据库的平稳运行。

    常见的例如增长缓存、经过MQ实现削峰填谷等。经过增长缓存,能够大幅度减小对数据库的访问压力,提升总体系统的吞吐能力。引入MQ,则能够将对数据库的压力以“稳态”的形式,向数据库持续施压,而不至于被某个异常高峰压死。

    七、层次-业务架构级

    最后一种状况是从业务角度进行一些调整。这每每是一种妥协,经过作适当的减法保证系统的总体运行。甚至不排除牺牲一部分用户体验等方式,来知足大部分用户的可用性。这就须要咱们的架构师对系统能提供的能力要很清楚,对业务也要有充分的了解。对于承载什么样的业务,及为了承载业务所须要花费的代价成本有充分的认知,才能够作出一些取舍。

    这里要避免一些误区,认为技术是“万能”的。技术能够解决必定的问题,但不能解决全部问题,或者解决全部问题的成本代价是难以接受的。这个时候,从业务角度稍做调整,就能够达到“退一步海阔天空”的结果。

    拓展阅读:自制小工具大大加速MySQL SQL语句优化(附源码)

    全面解析Oracle等待事件的分类、发现及优化

    按部就班解读Oracle AWR性能分析报告

    SQL优化:一篇文章说清楚Oracle Hint的正确使用姿式

    性能优化利器:数据库审核平台Themis的选型与实践

    做者:韩锋

    来源:宜信技术学院

    相关文章
    相关标签/搜索