当前位置: 首页 > 科技观察

解决DBA的困惑:数据库承载能力评估与优化方法

时间:2023-03-21 13:57:39 科技观察

作者介绍宜信科技研发中心数据库架构师韩峰。精通多种关系型数据库。曾就职于当当网、TOM在线等公司。曾在多家公司担任***DBA和数据库架构师。拥有多年一线数据库架构、设计、开发经验。《SQL优化***实践》一书的作者。作为DBA,有时会遇到这样的问题:1、如果现有业务规模扩大10倍、100倍,数据库能否支撑?2、下个月我们有大促,请问数据库有问题吗?3、计划去O工作,代码逻辑不变,数据库从Oracle切换到MySQL。MySQL能支持业务吗?4、服务器采购与选择,哪个服务器更适合我们?面对以上问题,DBA应该如何应对呢?作为DBA,我应该如何评估现有资源的使用情况?如果现有的数据库资源确实无法支撑,改造应该遵循什么原则?以下是我对以上问题的经验总结,供大家参考。1.评估工作面对这样的问题,首先要进行评估工作,可以按照以下步骤进行:1.建立性能基线针对系统运行的现状,建立性能基线。建立业务指标与绩效指标的对应关系。这里所说的性能指标包括CPU、MEM、DISK、NET等,在众多的资源中,必然存在不平衡,有短板的资源最有可能成为业务增长后的瓶颈。在具体操作上,可以先确定一个业务高峰时间段,通过监控平台或监控工具收集系统资源的使用情况。然后,根据收集到的信息,分析可能存在性能不足的地方。对于DBA来说,有必要清楚负责系统的系统的性能使用情况。通过了解业务,将业务指标映射到性能指标,很容易推断出现有系统能够承载的最大业务量。此外,对可能影响承载业务增长的缺点也将有更清晰的认识。一般来说,数据库类型的应用程序是重度消耗资源的应用程序。CPU、MEM、DISK、NET等消耗较大,但由于不同硬件的发展水平不平衡,各个数据库的资源消耗特点也不同,需要具体问题具体分析。先说说我个人对硬件发展的看法,以及它与数据库的关系:相对于其他硬件,CPU技术发展更快。随着CPU主频的提高和多核CPU技术的发展,CPU提供的计算能力往往不会成为系统的性能瓶颈。但是我们需要注意的是有些数据库并不能充分发挥CPU的能力(比如MySQL)。这时候,为了充分利用CPU资源,可以考虑“多实例混跑”等方案来提高CPU利用率。MEM随着内存技术的发展,内存的价格越来越便宜。现在我们在生产环境中可以看到128、256GB,甚至TB级别的内存。一般来说,数据库通常使用内存作为缓冲,配置大内存可以显着提高数据库的性能。另外,数据库技术本身也在适应大内存场景,通常的策略是分子池。管理单元进一步细分,如Oracle中的SubPool,MySQL中的multi-instancebufferpool。NET随着GigE、10GbE、InfiniBand技术的飞速发展,低延迟、高带宽的服务质量给数据库乃至整个IT系统带来了诸多变革。常见的应用领域包括:加速分布式数据库,例如OracleRAC。加速大数据处理,例如改进HadoopMapReduce处理。存储架构的转型从Scale-Up演进到Scale-Out。容灾方案、主备策略……磁盘与其他硬件技术相比,传统机械磁盘的发展相对来说是最慢的,往往最容易成为数据库的性能瓶颈。随着闪存技术的出现,带来了存储技术的变革。下面我们来看一下主要性能指标的对比:从以上指标来看,采用闪存技术后,存储容量有了很大的提升,系统安全的瓶颈也被消除了。这也是为什么很多DBA在不同的场合都强烈推荐使用闪存,这会给数据库性能的提升带来质的飞跃。但同时也要看到,传统的关系型数据库是按照磁盘IO模型设计的,没有考虑闪存技术,现在属于软件落后于硬件的阶段;相对而言,闪存技术更适合非关系模型。有优点。许多基于传统设计的优化理论发生了变化,例如:索引聚类因子的问题。这是我们在考虑数据库优化时需要注意的。此外,由于传统数据库与闪存技术的结合,NoSQL的性能优势变得不那么明显。选择架构时需要分析。2.建立业务压力模型根据业务特点,建立业务压力模型。简单理解就是把业务模拟抽象出来,方便后续的压力放大测试。为此,您需要对业务有充分的了解和评估。我举个小例子来说明一下:这张表模拟了某类电商业务,它包含的主要模块以及模块中的主要操作。不同的操作,事务复杂度是不同的(事务复杂度可以理解为执行SQL语句的条数)。根据不同的读写情况,区分是数据读取还是数据写入。在估算总业务量(交易量)的情况下,很容易计算出数据操作量。这样就将业务压力模型转化为数据压力模型。这里的难点在于业务逻辑的抽象能力和模块业务量的比例评估。有了上面概述的表格,对于每个业务操作,可以细化其操作。最后抽象为SQL语句和相应的访问特征。其伪代码可以描述为压力测试代码,可以根据上述伪代码编译。通过一些工具调用测试代码,产生模拟测试的压力。比如我经常用orabbtest/mydbtest(阿里楼方信最初开发的测试工具)或者sysbench等,都是不错的压力测试工具。建议企业根据自身情况,梳理出适合自己的业务压力模型。这在系统修改、升级、扩展评估、新硬件选型等很多场合都非常有用。比厂家提供的类似TPCC测试报告更有意义。据我所知,很多大公司都有比较成熟的压力模型。3.模拟压力测试考察现有数据库能否承受增加的业务压力的最好方法就是模拟压力测试。观察数据库在接近真实压力下的表现。重点观察,数据库承载能力的变化,以及主要的性能瓶颈。通常有两种方式,一种是从真实环境中引流(并根据需要放大流量,使用TCPCOPY等工具);另一种是基于上面整理的业务压力模型,通过压力工具模拟压力。前者适用于现有项目的扩容评估和系统改造评估,后者适用于新建项目原型评估、性能对标等场景。以上模拟压测结果暴露出的性能瓶颈,是我们未来需要重点改进和优化的方向。2.优化层次和步骤根据以上评价结果,确定后续的改进和优化方案。可以按照以下步骤进行:1.分析瓶颈点根据以上评估结果,分析性能瓶颈点。针对不同的瓶颈点可以采取不同的策略。有时性能测试的全过程,对于一个复杂的系统,很难明确定位性能瓶颈。此时可以使用一些APM工具来量化整个访问路径,帮助发现瓶颈。也可以像上面那样做好抽象,只对数据库端施加压力,观察数据库的行为,判断数据库是否是瓶颈。如果判断是数据库的承载能力不够,可以分级考虑。这一步是整个数据库承载能力评估中最复杂、最难的部分。需要分清是数据库承载能力不足还是其他组件的问题。即使明明是数据库问题,也要分清是整体问题还是局部问题;是单个业务功能慢,还是整体慢;是偶尔慢,还是总是慢,等等。这些问题的定义,有助于后面理清问题层次,采取不同的策略来解决。针对数据库的承载能力不足,我将常见的问题进行了分级,可以简单分为语句级、对象级、数据库级、数据库架构级、应用架构级、业务架构级。不同层次采用的方法也不同,下面分别介绍。2.Level-语句级别,比如性能核心问题,只是某条SQL语句的问题,可以有针对性的优化。这种方法是一种侵入性较小的优化方法,其影响范围也比较小。下面比较常见的语句级优化方法。说明一下,下面的方法已经排除了统计信息不准确等其他因素,只考虑了SQL语句本身的优化方法。重写SQL通过重写语句,达到调整执行计划,提高运行效率的目的。这种方式的缺点是需要研发人员修改原有代码才能部署上线。另外,有些使用O/RMapping工具生成的SQL不能直接修改语句,也不能使用这种方式。使用Hint许多数据库都提供了提示(Hint)的功能。这样就指定了语句的执行过程。该方法同样需要修改源码,走部署上线的过程。此外,这种修改方式还存在适应性差的问题。因为它指定了唯一的执行流程,随着数据规模和数据特征的变化,固定的执行流程可能不是最好的方式。这种方法实际上放弃了优化器可能生成的最优路径。storagesummary、SQLsummary、planbaseline在Oracle中也有一些内置的功能,可以固化某条语句的执行模式。本质上和上面使用Hint的原理类似。其缺点也与上述类似。调整参数有时也可以通过调整一些参数来改变语句的执行计划。但是这个方法要注意适用范围,不要全局使用,避免影响更多的语句。在session级别使用也要控制好范围,避免影响过大。3.Level-objectlevel例如核心性能问题无法在SQL层面解决,需要考虑对象层面的调整。在这种情况下,我们应该更加谨慎,需要充分评估可能的风险和收益。一个对象的结构修改可能涉及数百甚至数千个与此语句相关的执行计划更改。没有充分的测试,很难保证不出问题。如果是Oracle数据库,可以考虑使用SPA来评估。对于其他数据库,可以提前手动收集相关语句,修改后模拟回放上述语句,评估性能变化。1)影响因素在对象层面进行了调整。除了考虑对其他语句的性能影响外,还需要考虑其他因素。常见的有:数据库维护成本比较常见,比如索引。通过添加索引,往往可以加快查询速度;但是,添加索引会导致数据DML的成本增加。运维成本很常见,比如全局分区索引。对全局分区索引进行分区维护操作后,该索引将失效,需要自动或手动进行索引维护操作。具有共同存储成本的索引,索引结构是数据库中实际占用空间的结构。在以前的一些情况下,索引的总大小甚至超过了表的大小,因此在添加新索引时应评估空间使用情况。2)全生命周期管理这里还有一个很重要的概念——“对象全生命周期管理”,简单来说就是对象的生老病死。在许多系统中,对象开始创建,数据不断增加和扩展。当数据规模达到一定程度时,就会出现各种性能问题。对于一个大表和一个上亿级别的表,它的查询性能肯定是不一样的。因此,在对象设计的早期阶段,必须考虑相关的归档、清理、转储和压缩策略,同时考虑存储空间评估和生命周期管理。很多性能问题在数据清洗之后就可以轻松解决。但是,数据清洗往往是需要付出代价的,这个问题必须在设计之初就考虑到。在做数据库审查时,除了常规的结构审查和句子审查外,还要考虑这部分因素。4.级别——数据库级别到了这个级别,问题往往已经很严重了。一般来说,数据库的初始配置是根据运行系统对其的负载类型进行专门配置的。如果运行一段时间后出现性能问题,则评估为全局问题,可以考虑数据库层面的调整。然而,这种配置通常是昂贵的,例如需要特殊的关闭窗口操作。而且这种操作风险比较大,可能会带来很多不确定因素,所以要谨慎谨慎。5.Level-数据库架构级别如果性能核心问题无法在以上级别解决,可能需要调整数据库架构。常见的有读写分离的访问方式、分库分表的存储方式等,这种对应用的侵入性非常强,在某些情况下甚至不亚于重构整个系统。例如,随着业务的发展,系统的数据量或访问量超出预期,单个数据库无法满足空间或性能需求。此时,可能需要考虑采用分库分表的策略来满足这部分需求。但是,其改造的难度往往大于重新开发一个系统。比如我们可能需要一个数据中间层来屏蔽后面分库分表的细节。这个中间层可能需要完成语句解析、访问路由、数据聚合、事务处理等一系列功能。即使使用了中间层的产品,数据库的功能对于应用来说也会相对“弱化”,应用层的代码也不得不进行大量的调整以适应这种变化。此外,如何将一个正在线上运行的系统平滑地迁移到一个新的架构上,无疑又是一个飞驰的跑车换轮胎等问题。如果项目在运行过程中出现了数据库架构层面的调整,很可能说明项目前期设计规划阶段出现了错误,或者项目的业务预期出现了偏差。因此,这两点在初期就必须充分评估,在设计中要保留足够的“弹性”。6.Hierarchy-应用架构层面有些情况下,仅仅依靠数据库是无法解决的,需要综合考虑整个应用架构。在整个系统架构中,数据库往往处于系统的末端,其扩展性是最差的。因此,在应用架构设计的初期,应尽可能以不对数据库施加压力为原则进行设计。或者即使压力很大,系统也可以采用自动降级等方式来保证数据库的平稳运行。常见的有增加缓存,通过MQ实现削峰填谷等。通过增加缓存,可以大大降低数据库的访问压力,提高整个系统的吞吐量。随着MQ的引入,数据库的压力可以以一种“稳态”的形式不断地施加在数据库上,而不至于被一个异常的高峰压死。7.Hierarchy——业务架构层面最后一个案例是从业务角度做一些调整。这往往是一种妥协,通过适当的减法来保证系统的整体运行。甚至不排除牺牲部分用户体验来满足大部分用户的可用性。这就需要我们的架构师非常清楚系统能够提供的能力,对业务有充分的了解。只有充分了解所承载的业务类型以及承载业务的成本,才能做出一些选择。这里要避免一些误区,认为技术是“排他性的”。技术可以解决某些问题,但不能解决所有问题,或者解决所有问题的成本是无法接受的。这时,从业务角度稍作调整,就能达到“退一步海阔天空”的效果。