十位数据库专家:如何透过性能优化看系统架构的合理性

         十位数据库专家:如何透过性能优化看系统架构的合理性 

本文首发于一年多以前,由当时十位民生银行的数据库专家合著,系统地从架构的角度对数据库性能问题进行分析解读b,是多年项目开发和运维工作的经验总结。文章受到广大读者的关注,原分为上中下三篇,此次应读者要求“合体”发布,方便大家收藏参考。

作者:牛新庄 袁春光 朱彬 王健 陈晓峰 胡经伟 曹伟伟 刘星 詹玉林 甘荃

综述

本文尝试在软件系统架构的众多组成部分中突出的讨论性能问题,尤其是数据库有关的性能问题。从架构的角度对这些数据库的性能问题进行评估,试着在架构的设计中找到答案。

首先我们会简单的认识一下何为架构、架构如何重要,在架构的通用语义中如何考虑性能问题,如何建立起性能模型。

接着,我们会深入的讨论数据库中的性能问题:性能模型的考虑、影响性能的各种因素、性能调优的原则和方法等等。

最后我们通过四个很有价值的实例,讨论了性能问题的发生和解决的方法。

(文章很系统,因此也较长,可以循序渐进,也可以根据以上综述先跳到兴趣部分阅读,欢迎收藏转发。)

1 架构

1.1 什么是架构

不论是不是真的理解架构或精通架构,每个从事软件系统实现这一工作的人员,肯定在自觉或不自觉的完成了设计或实现一个架构。也就是架构作为软件系统的灵魂,套用一句流行语:不管你认识或者不认识架构,架构就在那里,不可改变。就像建筑行业一样,不论建房之前是否有一个设计图纸,只要是建筑物,就不可避免的存在一个建筑架构,而且建筑物的特点、质量、功能都取决于这一架构。软件系统亦是如此。

本文引入架构这一概念,并非专门探讨架构这一主题,因此下面借鉴两个比较权威的架构定义,有兴趣深入的读者可以研究其相关内容。

IEEE 1471的定义为:架构是在组件,彼此间和与环境间的关系,引导设计发展原则中体现的系统的基本结构。

系统是为实现某个(些)特殊作用的组件的集合。

专用系统包括个人应用,传统概念上的系统,子系统,系统中的系统,产品线,产品系列,整个企业和其他利益集团。一个系统是为了实现一个或多个任务而存在。

环境决定了开发,操作,策略和其他影响系统的设置和条件。

任务是指系统为了实现对对象设置的使用或操作。

涉众是对于系统有利益关系或关注的个人,团队或组织。

卡内基梅隆大学软件研究所的定义为:软件架构是一系列相关的抽象模式,用于指导大型软件系统各个方面的设计。软件架构是一个系统的草图。软件架构描述的对象是直接构成系统的抽象组件。各个组件之间的连接则明确和相对细致地描述组件之间的通讯。在实现阶段,这些抽象组件被细化为实际的组件,比如具体某个类或者对象。在面向对象领域中,组件之间的连接通常用接口_(计算机科学)来实现。

下面我试着列出了不同角度体现出的影响架构的因素。

影响架构的因素1:在软件系统生命周期的各阶段,影响架构的因素有如下图所示的各个方面

影响架构的因素2:从不同需求层次出发,影响架构的因素有如下图所示:

1.2 架构的重要性

上面在提到关于建筑这一示例时,尽可以体现架构对于建筑的重要性,如无合理的架构,建筑物就存在坍塌的危险。同理,在软件系统中,如果架构存在缺陷,则一样会影响软件系统正常功能,甚至是整体系统的生命。因此架构在软件系统中重要性是毋庸置疑的。

所以我们在建设一个软件系统时,绝对有必要事前建立一个合理的、高效的架构。这也是软件系统的核心角色:架构师的重要职责。

2 架构设计中的性能模型

架构的组成是多样的,相应的每一部分都很重要,而本文将会集中讨论架构中性能问题。最后会落实到数据库的性能问题。

作为软件系统非常重要的一项指标,性能不避免的成为架构设计中非常重要的一环,架构是由很多不同层次的组件组成的,具体到性能的设计,每个组成架构的组件,都会有不同角度的体现,为了从架构的角度和范畴来统一的规划和设计性能,目前比较普遍采用的方法是在设计架构时,同时规划或设计一个性能模型。由性能模型来指引和管理整个架构范围内的性能问题。

性能模型需要达成的目标如下:

管理性能相关的风险:

·将业务目标映射至性能目标

·平衡性能与质量之间的关系

·标识和分析典型性能场景

·拟定具体指标和测试案例

·评估模型并确保最终能实现性能目标

为了更好的表现性能模型,性能模型表现形式主要分为两类:

·一套结构化的信息,用于描述性能相关的各种元素。

·一套过程,用于定义、获取上述的信息和处理方法。

为了实现性能模型的目标,性能模型应该包含如下的内容:

·关键程序路径及对性能的影响

·如何利用计算资源及这些计算资源对性能的影响

·最常用的代码或模块

·访问关键资源的方法及资源竞争的解决

·代码或模块的访问关系,标识本地与远程的不同

·在性能实现中性能的折中

·同步调用与异步调用的评估

·梳理耗资源较高(I/O,CPU,MEM等)功能或模块

·定义各性能目标的优先级别

·性能目标对设计的影响

模型中对性能信息的描述可以参考下面的内容:

·根据业务确定系统的响应时间和各种资源的利用率目标

·确定最终的部署环境(包括各种软件及版本和硬件)

·一定确定基于场景的负载测试案例

在架构的建设中,性能模型的建设是不可避免的环节,而且针对数据库的性能管理,也同样需要建立起合适的性能模型,才能在评估数据库层次的性能问题时游刃有余。

3 数据库的性能模型

“架构是美的,就像从高空俯览的一幅美景,要一点一点的去欣赏”。前面的部分,我们是从万米高空俯览整个系统,让大家欣赏到了系统架构的全景之美,那么接下来,我们下降到2000米,欣赏一下数据库架构的美景吧。

“在北京居住的久了,也就习惯里北京的交通”,这句话是句无奈的自我安慰,是对城市交通规划的无奈。如果将系统比喻成一座功能齐全的大城市,那么数据库就是这座大城市里的基础建筑,比如城市的街区、道路、桥梁、房屋等,数据库架构师就是这座大城市的规划师,负责设计出最适宜人们居住的环境,交通作为城市的传输通道,直接影响着人们的出行效率和生活质量。差的数据库架构会让数据库在大负载多并发的情况下变得运行缓慢,就像丑的交通规划会让这座城市变的拥堵不堪一样,因此如果在出现数据库性能的时候去考虑改变数据库架构设计,无异于为北京市重新规划蜘蛛网似的道路结构,是绝对无法接受的。

在之前的篇幅里我们提到了性能模型,了解了性能模型如何从整体上帮助我们进行系统架构,提高系统性能,那么我们在这里就降低一下高度,详细的讨论一下数据库架构中的数据库性能模型。首先数据库架构的目的是为了让数据库运行的够快、更稳定,同时有很强的线性扩展能力,可以快速处理更多的用户请求,因此任何形式的性能问题都可以归结为如何在最低资源利用率的情况下提高数据库吞吐量和降低响应时间问题。

那么影响数据库性能的4个因素为:CPU,磁盘,网络和内存。根据木桶原理,只有不断对这四个因素进行优化配置,消除短板,才能最终达到增大吞吐量、降低响应时间的目的。

数据库性能模型为数据库架构师提供了一套调优数据库性能的方法论,从宏观上来看,我们将其抽象为输入,处理和输出三个部分,如下图所示:

3.1 输入

输入部分里描述了一个数据库架构师在设计高性能的数据库之前一定要搞清楚的一件事情,即你的目标是什么?这里有句话送给大家——“性能最优的系统不一定是最好的系统”。作为架构师,不要为了调优而调优,只要系统能达到应用的要求,就够了。希望下面四项输入可以帮助大家梳理你的调优目标。

3.2 处理

对于数据库架构师而言,处理可以按照两大块顺序执行,首先根据应用场景和增长规模,确定数据库的逻辑架构,接着根据各种指标和预算,确定数据库的物理架构。逻辑架构是用抽象的方法描述数据库的架构,该方法脱离具体的硬件和软件,脱离具体的技术和协议,具有很强的重用性;物理架构则更多的从物理和实现上着手,根据不同的硬件、软件、技术和协议来调整数据库的参数配置,是逻辑架构的具体实现。可以说“逻辑架构决定物理架构,物理架构支撑逻辑架构”。

下面,我们先看一下数据库的逻辑架构包括哪些东西。

也许你的系统很庞杂,有很多的功能,要实现很多的业务,但是这些业务经过界面、中间件、代码逻辑处理后,到达数据库的就只会是基本的增删改查操作,因此判断业务属于哪种类型很简单,大并发、小数据处理的是OLTP系统,小并发、大数据处理的是OLAP系统,两者皆有的是混合系统,不同的系统适用不同的数据库架构。这里介绍几种常见的用于处理OLTP和OLAP的数据库架构。

对称多处理器(SMP)系统由同一台机器中几个能力相等的处理器组成,像磁盘空间和内存这类资源是共享的,利用可用的多个处理器,可以更快地完成不同的数据库操作。该数据库系统还可将单个查询的工作分布在可用的处理器中,以提高处理速度。其他数据库操作,例如,装入数据、备份和复原表空间以及对现有数据创建索引,都可以利用多个处理器。

用户请求通常是以线程形式存在,在SMP环境中,用户的请求通过系统总线被平均分配到不同的CPU上进行处理,这些不同的CPU共享同一块内存空间和磁盘,线程之间通过信号量进行通信,因此这种结构的线程间通信的成本非常小,同时用户可以通过增加CPU、内存或者硬盘来提高整体的机器性能,非常适合处理OLTP类型的应用。

Sharing Nothing架构(多分区数据库)指的是将一个数据库分成多个逻辑分区,每个逻辑分区可以运行在不同的机器上甚至同一个机器的不同处理器上,每个逻辑分区拥有独立的处理器、内存空间、磁盘空间和日志空间,互相之间通过网络进行通信。用户数据通过一定的规则,比如哈希或者轮训等,被分别存储到不同的数据库分区的磁盘中。不同的数据库分区之间不共享任何资源。

在这种架构下,一个用户请求被分解成多个线程,分派到不同的数据库分区并行执行,这些线程执行结束后,通过网络将结果汇总到一起,经过处理后返回给用户。

用户可以根据CPU的处理能力的不同,为数据库分区分配不同的处理器个数,做到每个CPU都能充分运行。因此这种架构决定了其在处理大数据量复杂查询的场景下具有非常优秀的性能,相比传统的SMP数据库架构,在OLAP的用户场景中,拥有不可比拟的优势。但是由于其通信网络的高延时和复杂的预处理,因此决定了其在处理小查询、大并发、增删改操作时,时间会有明显的增长,因此并不适合OLTP的用户场景。

然而随着业务的发展,用户数越来越多,那么能否将对称多处理器(SMP)系统进行一个扩展,支持多台不同的物理机器呢?答案是肯定的。Share Disk(共享磁盘)技术就是对这种扩展架构的实现。该技术可以支持更大的在线并发处理,提供良好的扩展能力和高可用性支持,其基本结构如下。

在该结构下,一个数据库以多个节点的形式存在,每个节点拥有不同的CPU和内存资源,但是共享同样的数据库磁盘,这些节点在形式上是对等的,没有主仆关系,他们可以通过网络磁盘技术同时操作一个数据库文件或者日志文件,不同节点之间通过InfiniBand网络的直接内存读写(RDMA)技术实现数据在内存的直接读写,最大限度的避免了网络延时。由于各个节点是对等关系并且没有任何持久化的资源,因此添加节点实现线性扩展将变的非常容易,同时任何一个节点的宕机故障也不会影响整个数据库系统的可用性。

我们甚至可以基于上面两组架构做更进一步的结合,将Share Disk和Share Nothing进一步融合,形成一个适合混合场景的架构。磁盘管理系统可以利用一定的算法将数据打散存放在不同的磁盘里,让大数据的复杂查询可以在不同的磁盘内同时进行,经过磁盘管理系统的预处理返回给不同的数据库节点,达到大数据量和高并发的完美结合。

由于篇幅有限,数据库逻辑架构我们就先谈到这里,就不再详细展开了,下面我们再来谈一谈数据库的物理架构。要想做好数据库物理架构,需要掌握下面几点:

·掌握物理架构的方法论。

·掌握数据库的性能指标。

·掌握数据库的实现原理。

·掌握各种调优方法。

就数据库物理设计的方法论而言,有下面四个方法。

方法一:根据数据库逻辑设计,找到相应数据库产品的实现方法。

对于同一套数据库逻辑设计,不同的数据库产品有不同的实现方法,下面的表格列出了不同数据库产品的实现技术。

方法二:合理设计数据库对象

数据库对象是数据库的逻辑概念,其设计的好坏除了决定系统功能,有时还会决定系统的性能,其设计主要包括模型的设计,表类型的选择,索引的设计,分区设计,表空间的设计等。

在模型的设计上,我们通常采用第三范式来进行数据库对象的模型设计,但是有时为了性能考虑,我们通常会做一些退化,比如设计一些冗余字段或者将多表合并来加快系统的查询性能。例如对于有大量数据的销售流水表,完全按照第三范式来做的话会有一个外键关联客户信息,一个外键关联产品信息。

但是如果系统在运行一段时间后,这三张表的数据变的非常多,那么连接查询的性能将会变的很差,我们通常的做法是再设计一张横向表,将客户信息和产品信息全都放到销售流水表里去,这样就避免了关联查询。

表通常分为很多种,除了基本表外,还有临时表,多维表,分区表,范围集群表,物化视图表等。不同的表有不同的用途,如果错误使用的话,也会对性能有比较大的影响。比如在不需要物化视图的地方使用的物化视图表,那么会对源表的增删改性能照成影响。

合理的使用正确的索引是提高系统执行效率的关键因素,对索引的使用需要注意以下一些问题:

1)注意LIKE运算符。

2)注意NULL值。

3)优化复合索引。

4)注意索引的相关参数。

5)注意索引与谓词的关系。

6)根据查询所使用的列建立索引。

7)根据条件语句中的谓词的选择度创建索引。

8)避免在建有索引的列上使用函数。

9)在那些需要被排序的列上创建索引。

10)合理使用include关键词创建索引。

11)指定索引的排序属性。

数据库的页大小也是在数据库设计的时候就应该确定的,否则一旦实施就很难更改。对于执行随机行读写操作的 OLTP 应用程序,通常最好使用较小的页大小,这样不需要的行浪费的缓冲池空间就会较少。对于一次访问大量连续行的OLAP 应用程序,页大小大一些会比较好,这样就能减少读取特定数目的行所需的 I/O 请求数,更大的页大小也可以允许您减少索引中的级别数。总之,在满足以上条件的情况下,交易系统使用较小的页更适合,仓储系统使用较大的页更适合。

对表空间的选择,通常的数据库都会包含系统管理的表空间和数据库管理的表空间两种类型。系统管理表空间由操作系统的文件系统管理器分配和管理空间,管理灵活但是性能很差。数据库管理的空间由数据库管理程序控制存储空间,表空间容器可使用文件系统或裸设备,虽然管理复杂,但是在性能上会有很大的提升。

方法三:合理设计存储

磁盘作为数据库的最底层,从发明至今,依然没有摆脱机械设备固有的速度限制,面对速度和容量突飞猛进的CPU和内存,存储在很多情况下依然是系统的最终瓶颈,因此作为数据库架构师,必须很好的规划存储。一般存储规划应该从下面几点进行:

1)磁盘I/O的吞吐量(每秒I/O数IOPS和每秒传输的数据量MPS)。

对于磁盘密集型的系统,磁盘IOPS和MPS指标尤为重要,一次I/O指的是磁盘在没有换道的情况下产生读写的操作,通常一块1万5千转的SAS盘的IOPS能在150-175之间,对于大并发的系统,我们应该充分估计系统峰值的IOPS数和MPS数,采用合适的RAID技术和磁盘数量,以防止出现CPU IO Wait高的情况。对于平均负载来说,通常建议10到20块盘对应一个CPU的Core。

2)存储的容量规划。

SATA、SAS、光纤盘,不同的盘具有不同的容量,速度和价格,如何平衡容量、速度和价格之间的关系也是前期数据库物理设计应该注意的问题。

3)独立磁盘记录日志。

数据库为了保证数据的一致性,在进行事务提交的时候,必须要等到数据库日志写入磁盘才算提交成功。如果日志写入缓慢的话,会照成数据库的所有事务提交缓慢,因此数据库日志最好采用独立的磁盘来单独存放,以免产生数据库整体的性能瓶颈。

4)条带话。

为了能够协调多块磁盘同时响应用户请求,数据库架构师们应该考虑如何在多块磁盘间做条带话处理,通常的存储都已经支持RAID0~5和一些互相结合的条带话技术。条带的深度和宽度也应该和数据库的扩展块大小进行合理的匹配。

方法四:优化数据库参数,减少资源竞争。

最后一点是优化配置数据库的参数,包括各种缓存池的大小,内存区的配置,刷新脏页的策略,锁的策略等。虽然各个数据库都不相同,但是所有的出发点都是为了通过数据库参数,降低物理读的次数和发生资源竞争的可能性。这里就不再详细介绍了。

3.3 输出

通过上面的处理,你们的数据库应该有一个很大的提高了,那么赶紧将调优后的数据库指标记录下来,发给项目组做最终的性能评审吧。我总结了一些应该关注的性能指标,请大家补充吧。

1)耗时最长的SQL的平均执行时间。

2)数据库的平均CPU利用率。

3)CPU的执行时间、IO等待时间和锁等待时间。

4)平均I/O响应时间。

5)支持的峰值IOPS数和MPS数。

6)物理读和逻辑读的百分比。

7)有效索引读的百分比。

8)有效行读的百分比。

3.4小结

数据库性能调整非常的博大精深,充斥了各种知识,很多人都会对此痴迷不已,但是在这节内容终了的时候我们想送大家一句话,也算给大家提个醒吧,“性能调优千万不要钻牛角尖,满足需求的系统才是最好的系统!”。

4 案例分享

为了更好地理解架构设计中的性能问题这一主题,我们尝试例举几个我们在实际工作中有着深刻体会的案例,期望读者能够在这些实例的基础上举一反三,在自己的场景中找到这种问题的解决办法。

4.1 应用模型不清导致的性能问题

随着金融体制改革日益深入,中外银行间的竞争将更加激烈。与此同时,客户的金融需求也呈现出多元化倾向。目前竞争的关键就在于,怎样发现优质客户、避免优质客户流失。就银行业务而言,一方面要推出个人理财服务、私人银行业务等业务来争夺高、中端客户。这就需要业务系统要能够及时响应客户的需求,做到快捷、便利的服务。另一方面,银行的客户经理必须对客户信息进行收集整理和分析挖掘,利用现有的客户资源优势,把零散无序的数据集中起来,挖掘出为银行创造利润的客户,并为这些客户提供更优质的服务,这是业务系统的又一个重要目标。

这样就提出一个很现实的问题:业务系统的数据库是OLTP的还是OLAP的?

4.1.1 什么是OLTP和OLAP

当今的数据处理大致可以分成两大类:联机事务处理OLTP(on-line transaction processing)、联机分析处理OLAP(On-Line Analytical Processing)。OLTP是传统的关系型数据库的主要应用,主要是基本的、日常的事务处理,例如银行交易。OLAP是数据仓库系统的主要应用,支持复杂的分析操作,侧重决策支持,并且提供直观易懂的查询结果。

On-Line Transaction Processing联机事务处理系统(OLTP),也称为面向交易的处理系统,一般都是高可用的在线系统,以小的事务以及小的查询为主,OLTP 系统旨在处理同时输入的成百上千的事务,其基本特征是满足在大并发的情况下针对事务的实时响应,所以也称为实时系统(Real time System)。衡量联机事务处理系统的一个重要性能指标是系统性能,具体体现为实时响应时间(Response Time),评估其系统的时候,一般看其每秒执行的事务数以及sql的数量。典型的OLTP系统如电子商务系统,银行,证卷等等。

On-Line Analytical Processing联机分析处理系统(OLAP),有的时候也叫DSS决策支持系统,联机分析处理的用户是企业中的专业分析人员及管理决策人员,他们在分析业务经营的数据时,从不同的角度来审视业务的衡量指标。例如分析销售数据,可能会综合时间周期、产品类别、分销渠道、地理分布、客户群类等多种因素来考量,OLAP中其实还有一类使用人员,比如银行中的客户经理,营销人员,业务人员等,他们不需要报表,而是实时的查询,并且该类查询一般都是关联很多表的复杂查询,进行数据分析和信息综合,提供营销支持,对实时性要求也比较高。

下表列出了OLTP与OLAP之间的比较。

4.1.2 具体案例

4.1.2.1 项目背景及概述

比如行内以前的某系统,该系统主要负责银行卡的积分礼品兑换,但是由于该系统的应用特点,它数据库里面同时也存放着大量的用户相关信息,可以用来支持客户经理、业务人员等进行信息的查询和分析,支持多维度的市场营销行为,基于该特点,在项目设计之初,开发人员将过多的精力放在了功能需求的满足上,在该系统上开发实现积分兑换和业务数据分析两个功能,但是从数据库的角度看,这两个功能其实对应到数据库访问行为上一个是OLTP,一个是OLAP,从而在设计之初就埋下了性能问题的隐患。

4.1.2.2 投产后的性能问题

1)数据库锁现象严重

投产后关于性能方面一个比较突出的问题就是锁冲突的问题,由于OLTP和OLAP对数据库访问模式的不同,对数据库锁的要求也不同,两种不同类型的应用同时运行,造成大量的锁升级、死锁和锁等待,虽然按照标准的数据库调优步骤,增大了locklist和maxlocks的值,仍然无法完全解决锁冲突的问题。

2)磁盘I/O出现瓶颈

实际运行过程中,磁盘I/O也出现了瓶颈,为了提高数据库的性能,尝试了对数据库服务器数据的条带化分布,将数据文件对应的文件系统分布在不同的磁盘上来提高性能,虽然个别的单个事务的执行效率会提高,但是总体对数据库的性能提升有限。

3)创建索引无法改善总体性能

由于OLTP系统查询相对简单,依靠建立适当的索引保证查询速度,但是索引只能解决那些预先定义好的问题,对OLAP的应用性能提升有限。

4.1.2.3 最终的解决办法和效果

临时解决办法:

应用开发人员对应用的并发进行限制,主要是限制OLAP的访问的并发数,并针对此开发了应用队列的管理,一旦OLAP的并发数超过阈值,便进入应用队列进行排队,以此来保证OLTP数据库访问的及时响应,最大限度的保护实时业务的响应时间。

最终解决办法:

经过应用开发人员和DBA多方努力无效后,最终还是达成统一共识:导致性能问题的主要原因是应用模型不清,对业务的行为及其对数据库的访问模式的区别进行了认真的总结,最终决定将应用和数据库进行拆分,实现OLAP和OLTP业务访问的分离,形成交易库+查询库的架构,同时为了及时的给交易库瘦身,又搭建了归档库,最终形成了交易库+查询库+归档库的数据库架构,分拆后,锁的问题,磁盘读写问题,应用的并发都得到了很大的改善,取得了良好的效果。

4.1.2.4 其他可以参考的技术

为了更好的支持OLTP或OLAP的业务处理,各个厂商也都推出了不同的技术,目前的主要方向有两个:一是利用数据库本身开发的技术,比如DB2的DPF,PureScale,ORACLE的RAC等,另外一种是专门针对OLAP系统的一体机比如Netezza,TeraData, Greenplum,ExaData等。下面简单介绍一下其中几种技术的工作原理和设计理念。

DPF:即Database partitioning feature, 是 DB2 企业版 DPF(Data Partitioning Feature)选件提供的,它主要用来为大规模数据处理、高并发数据访问提供支持。分区数据库功能采用非共享的架构,也就是前面描述的Sharing Nothing架构,数据库被分为多个分区,每个分区运行在不同的服务器节点上,各分区拥有独立的引擎、日志管理、锁管理、缓存管理等资源,实现并发多处理机制,适用于大型数据仓库(OLAP),提供强大的扩展性和性能。在DPF架构中,数据通过 Hash 算法均匀地散列到不同的分区内,每个分区只负责处理自己的数据。当用户发出 SQL 操作后,被连接的分区被称为 Coordinate Node,它负责处理用户的请求,并根据 Partition key 将用户的请求分解成多个子任务交由不同分区并行处理,最后将不同分区的执行结果经过汇总返回给用户,分区对应用来说是透明的。

pureScale是DB2基于活跃-活跃式共享磁盘的数据库集群技术,也就是前面描述的share disk(共享磁盘)的架构,它是继承IBM主机的Sysplex技术而来,用来提供高可用性,在一个节点失效的情况下,可以提供不间断服务(切换时挂起时间在20秒内)。

每个节点拥有不同的CPU和内存资源,共享同样的数据库磁盘,这些节点在形式上是对等的,可以通过网络磁盘技术同时操作一个数据库文件或者日志文件,不同节点之间通过InfiniBand网络的直接内存读写(RDMA)技术实现数据在内存的直接读写,最大限度的避免了网络延时。

由于各个节点是对等关系并且没有任何持久化的资源,因此添加节点实现线性扩展将变的非常容易,通过其扩展特性可以支持更大的在线并发处理,同时它相对于应用时透明的,运行在 DB2 pureScale 环境中的一个应用并不需要知道集群或者分区数据的不同成员。DB2 pureScale Feature 会自动地将应用转发给它认为最合适的成员。该技术比较适合OLTP,ORACLE的RAC跟purescale原理类似。purescale架构概览如下:

Netezza:数据仓库软硬件一体机的提供者,该公司于2010年被IBM收购,这种一体机适合数据仓库类高性能运算,它采用大规模并行处理(MPP)架构,同时在每个MPP节点内部的FPGA进行加速运算,针对庞大的数据量能够以“流水线”的方式进行分析处理,该架构下的各个组件已经进行了优化,不需要进行索引或对系统做调整或优化。属于Sharing Nothing 架构,适用于大型数据仓库(OLAP)。架构如下:

4.1.3 小结

本节通过举例,重点强调了应用模型不清可能会导致严重的性能问题,如果项目设计前期不重视应用模型,不仔细分析应用的访问行为的话,一旦生产系统投产,就会将所有的压力压到数据库上面,如果通过数据库性能调优也没有办法很好解决,再进行应用模型的修正和改造是很费时费力的,所谓“磨刀不误砍柴工”,所以设计清晰明了的应用模型对性能是相当重要的。

4.2 良好的存储规划对性能的提升

数据库中数据的访问离不开I/O行为,所以I/O的性能对数据库性能有着致命的影响,因此作为I/O行为的具体执行者-存储系统的性能就显得至关重要。而存储系统的特点又决定了事先的规划远远重要于事后的调优。

存储系统作为应用处理的最终数据承接端,存储系统性能直接影响应用系统及关联应用的处理效率和运行可靠性,通过存储系统规划使得存储资源运行方式更加贴近业务运营需要,存储资源保持合理运行状况,最终应用系统获得很好交易处理响应时间和更强业务承载能力。

为了更好提升系统运行可靠性和安全性,结合应用特点采用主机LVM、数据库HADR及存储SRDF等不同层面的保护技术,这些技术的使用都会对系统运行性能带来一定压力,因此更加需要切合实际的存储规划为系统运行性能奠定基础和保障,并且扩展系统运行性能的提升空间。

存储规划以业务的服务要求和应用特征,结合主机、数据库及存储资源配备状况,根据行业特征及技术平台最佳实践,设定明确和切实的服务目标,作为支撑的存储系统及关联环境的规划的基础,基于服务目标确定有效规划原则,进行方案设计和系统部署。

4.2.1 良好存储规划的目标

良好存储规划目标从业务服务需求出发,尤其重点关注交易响应时间和交易处理的持续并发能力,存储系统资源规划从部件响应能力为基础,降低存储系统热点、容灾、利用率及维护对服务能力影响。

1)降低主机磁盘响应时间

重点分析规划影响主机磁盘响应时间的关键因素涵盖数据处理IO特征、数据保护方式、部件利用率、数据处理并发性。

2)降低资源热点对性能响

重点分析规划存储连接端口、缓存、磁盘及磁盘控制卡,以及交换机端口,分析排查IO等待队列、Pending数据、命中率等数据特点。

3)降低容灾保护对性能影响

重点分析规划容灾数据高写负载数据卷、容灾数据卷数据量及写数据的均衡能力,以及容灾数据处理的链路响应等。

4)合理存储资源利用率定位

重点分析规划存储连接端口、缓存、磁盘、磁盘控制卡及容灾控制卡,以及交换机端口,分析部件利用率运行状态,部件利用率直接影响数据处理响应时间。

5)降低部件故障对系统性能影响

重点分析规划存储连接端口、缓存、磁盘及磁盘控制卡,以及交换机端口等系统部署冗余性,分析排查系统冗余部件的耦合性。

4.2.2 良好存储规划的原则

依据存储规划目标为基础,确定通用的系统部署原则,指导系统方案的设计实施,同时经过系统测试验证,对相关原则进行补充修订。

1)有效而合理Stripe方式

采用存储数据卷的META Stripe作为磁盘基本划分,在此基础可以封装主机或数据库的Double Stripe方式,通常LOG区域的Stripe Size建议保持64K。

关键及重要业务系统建议采用Mirrror方式,卷组成员建议8-16的磁盘数量。

Clone数据卷为了节省数据空间,可以采用RAID5方式,建议采用RAID7+1方式。

2)全面细致的部署资源平衡

存储阵列系统的部署资源包括FACPU、FAPort、Cache、DA、磁盘,以及数据卷Hyper卷在磁盘分布平衡。

存储交换系统的部署资源包括交换机之间、ISL通道、Port、ASIC数据通路分布平衡。

3)资源部署单元化降低故障影响面

存储阵列系统的部署资源包括FACPU、FAPort、Cache、DA、磁盘,建议分布在不同控制卡中。存储交换系统的部署资源包括交换机之间、ISL通道、Port,建议分布在不同交换机和控制卡内。

4)降低数据和索引空间对LOG空间影响

建议数据库的数据和索引空间与数据库LOG空间进行独立磁盘划分、使用独立的磁盘。

5)磁盘分组规划保护关键业务资源

建议对阵列磁盘分组划分,创建独立clone磁盘组作为Clone数据专用,创建两个数据磁盘组和一个LOG磁盘组,同时META数据卷的选择要求遍历不同磁盘。

6)合理有效数据卷数量提供容灾性能保障

建议在保证使用容量数据卷的基础上,尽可能多使用Hyper数量,提升容灾性能,建议采用META 8数据划分。

7)关键业务的支撑环境部件性能利用率不超过50%

通常支撑部件在利用率40%以下保持良好的数据处理响应时间,

存储阵列系统FACPU、FAPort、Cache、DA、磁盘部件利用率,对于关键系统使用部件利用率建议不超过50%。

8)关键业务系统进行支撑部件独享,其他系统业务峰值平摊

关键业务系统使用独立的存储阵列系统FACPU、FAPort。其他业务在磁盘系统进行业务系统平摊,对于关键业务影响很大的应用系统建议分布到其他磁盘组中。

4.2.3 良好存储规划的过程

良好存储规划以规划目标、规划原则、规划方案及系统部署四个环节进行系统统一规划部署,进行相应数据分析对比,通过多次系统测试验证,提高系统规划质量和平台支撑能力。

4.2.4 效果对比

B系统经历多次压力测试,在存储调优之前,集中处理的大任务的执行时间有85% 左右在数据库中,性能的瓶颈出现了数据库层面。而且总的执行时间大幅度的超过了设计目标,某个的大任务的执行时间达到了8小时。

经过多方的深入分析,基本得出了结论:数据库本身的优化空间很小,主要的优化方向应集中在存储层次。

存储系统针对每次测试的特点,深入的分析了存储系统存在问题,有针对性的对规划进行了修订和对部署方案进行了调整,下面是比较重大调整的效果对比分析:

1)Host Stripe调整效果分析

4月12日B系统使用LOG空间Pr2log1存储空间使用方式调整成Stripe方式,Stripe Size为64KB,在未启用SRDF情况下,主机使用LOG空间磁盘的写响应时间由15ms降低为0.7ms.

2)FA端口扩充效果分析

FA端口经过多次扩充,4月25日B系统主机系统与存储系统使用FA关系为1:1关系,在未启用SRDF情况下,主机使用数据空间磁盘的写响应时间由11ms降低为4.5ms.

3)容灾端口扩充效果分析

RF端口经过扩充,5月15日B系统主机系统与存储系统使用RF端口数量由4RF扩充到8RF,在未使用Extanded License和未加BufferCredit情况下,主机使用数据空间磁盘的写响应时间由69ms降低为45ms.

4)存储交换机增加BufferCredit及数据卷Stripe调整效果分析

5月31日,存储交换机使用Extanded License和增加BufferCredit=200,同时B系统主机的Data&Index采用HostStripe为64K情况下,主机使用数据空间磁盘的写响应时间由45ms降低为16ms.

4.2.5 小结

从上述对比测试中我们可以看到,以上的调整对性能的提升有极大的帮助,随着存储层次的I/O time大幅度的缩小,业务的执行时间也有着非常大的变化,如批处理时间由原来的8小时缩短至不到3小时,这对性能的指标来说有着质的飞跃。数据库部分的所占用的处理时间比例也大幅度的降低,数据库不再成为业务性能的瓶颈。

4.3 应用架构导致的性能问题

应用程序的主流架构设计大致经历了主机结构,C/S结构,B/S结构。随着架构的演化,性能问题表现的方式以及处理性能问题的方法和思路也发生了变化。主机结构的工作负载都集中在一台机器上,所以性能问题只会在服务器端产生。而在C/S结构中,由于客户端和服务器都有工作负载,所以性能问题在两端都有可能产生。在B/S结构中,由于架构的分层,系统由web服务器,应用服务器,数据库服务器组成,所以在各个服务器上都有潜在性能的问题。下面就来介绍一下各种架构。

4.3.1 架构的演化

主机结构:

在主机结构中,用户通过终端登录到系统,数据库、应用程序的任务都由一台服务器来处理。由于大型机有着超强的处理能力,所以这是典型的大型机的处理方式。这种架构如果不是大机环境,不推荐使用。

C/S是Client/Server的缩写,即大家熟知的客户机和服务器结构。它是软件系统体系结构,通过它可以充分利用两端硬件环境的优势,将任务合理分配到Client端和Server端来实现,降低了系统的通讯开销,服务器通常采用高性能的PC、工作站或小型机,客户端需要安装专用的客户端软件。

B/S(Browser/Server)结构即浏览器和服务器结构。它是随着Internet技术的发展对C/S结构的一种改进。在这种结构下,用户工作界面是通过浏览器来实现的,极少部分事务逻辑在前端(Browser)实现,但是主要事务逻辑在服务器端(Server)实现,形成所谓三层3-tier结构。这就形成了“瘦”客户机,“胖”服务器的结构。

在B/S双层架构,表现层的任务拆分到了单独的服务器上去执行,系统在这些服务器上专门处理表现层,他们单独负责格式化图形界面。数据库层和应用层仍然在同一台服务器上。

这种模式可以把表现层的负载分布到多台服务器上,所以不会影响应用与数据库的性能。在双层模式中,如果并发用户数量超过了一定的上限限制,则中央节点,即应用服务器和数据库服务器所在的机器,将会有潜在的瓶颈风险。

B/S三层架构是在B/S双层架构的基础上,把应用层的处理程序拆分到其他单独的服务器上去,以此来提高系统的整体性能。每一层都由单独的服务器负责处理各自的任务,多个不同的应用层服务器可以同时访问一个数据库的数据。

目前B/S架构的Web层开发框架数量非常多,而且各有特色,如:Struts、WebWork、Spring MVC、Tapestry、JSF、WebPage3.0……等,在设计初期需要根据各自的特点选择性能较好的框架。

系统架构一旦实施后就很难再做改动,所以一个好的应用架构设计对系统性能至关重要。

通过三种架构的描述可以看出,B/S三层架构不论从系统的性能、可维护性,还是扩展性,都是比较理想的架构。每一层的系统资源是相互独立的,各层的瓶颈只会影响本层,不会扩散到其他层。这种模式有着灵活的扩展能力。

4.3.2 应用架构中的并发任务管理

一般在架构设计的过程中,很少考虑并发的管理,这就导致数据库的负载加大,性能下降。其实上面提到的应用架构中,都可以设计各自层次的并发管理,从而逐级的减轻数据库的压力,提高整体系统的性能。下面就简述一下各个层次的并发设置的机制。

表现层:

在表现层中,如果是Web应用,可以通过web应用服务器的配置参数来控制访问web服务器的并发用户的连接数,如果是其他应用,可以通过应用软件提供的参数来限制并发用户连接数。

应用层:

在应用层中,可以通过应用服务器的配置参数来限制访问应用服务器的进程数。也可以通过在应用程序中通过队列的先进先出管理机制,以及顺序的管理,优先级的管理,任务的管理。以此来控制并发。如果用到中间件的功能,还可以通过数据库连接池来管理连接到数据库的用户数。

数据库层:

在数据库层中,可以通过数据库参数来限制用户连接的数量。其实数据库本身也通过锁的管理机制来管理并发,比如2个用户不能同时更新一个数据库对象。

4.3.3 过度并发带来的问题

过度的追求高并发同时又要保持数据一致性会在各个层次产生性能的影响。比如在数据库中会产生大量资源的争用,大量的锁等待,甚至产生大量的锁升级,带来严重的性能问题。

其实并发不是越大越好,一个好的系统一定会在并发和性能找一个最佳的平衡点,不会以牺牲性能为代价来提高并发。所以一定要在架构的各个层次上设计好并发的管理,让各层的并发负载尽量的均衡。

4.3.4 SAP并发管理

先描述一下SAP是如何工作的。

SAP系统通常由一个或多个实例组成,每个实例包含一个分发器,每个分发器有多个不同的服务进程,其中一个服务进程enqueue work process负责应用级别的锁管理。如果配置了均衡负载,还会有一个消息服务器来做负载均衡。

当用户需要访问系统的时候,消息服务器先做一次负载均衡,返回给用户一个当前性能比较好的的分发器,这样用户的处理请求首先会被存放到分发器对应的一个请求队列当中,然后按照先进先出的原则来处理请求。分发器会相继把请求分发给可用的工作进程,真实的数据处理是在工作进程当中完成的。

如果是更新数据,SAP还会在此数据对象上加应用级别的锁。工作进程会先访问应用级别的缓冲池,如果数据存在,直接返回给用户,否则再访问数据库。缓冲池可以加快用户请求处理的速度。经常被读取但极少修改的数据可以被缓存到SAP的共享内存中,也就是说,如果需要,数据不用每次都要到数据库中去取。而是可以很快的从缓冲池中读取。一旦处理完成后,处理结果就会通过分发器返回给用户,用户的请求不总是一直由一个工作进程来处理的,每一个工作进程都是直接连接到数据库的。

从上面的SAP访问步骤可以看出,SAP通过如下几个方面来提高系统的并发性。

1)分发器

通过在应用层面建立起队列的机制,从而控制登录到系统的并发用户数。

2)应用级别的缓冲池

在应用层设置数据缓冲池,避免用户每次都要去数据库中取数据。这极大的缩短了用户响应时间,同时也可以增加用户的并发访问数。

3)应用级别的锁管理

当用户请求需要修改某个数据对象的时候,比如销售订单,SAP会在应用层面对这个订单加锁,如果另一个用户也要对此对象有修改的需求,则会产生锁等待,但是数据库中并没有锁等待,这样就可以减少数据库中的锁,通过这几个特性可以极大地提高应用程序的并发性,在应用程序设计阶段可以按照这个特性设计出自己的并发控制功能。

4.3.5 案例分析

背景:

在某大型项目中,数据库本身比较大,为了降低存储成本,对某些大表做了行压缩,压缩之后的大小大约有6TB的数据量,此项目的特点是:应用程序逻辑比较复杂,其中数据的处理程序占整个程序的80%。并发访问量较大,同时会有200多个SQL语句在数据库执行。

由于数据库本身比较大,导致在设计上产生了上百个表空间以及上万个业务表。

问题:

在高并发数据量处理的时候系统存在大量的程序包高速缓存锁等待,导致性能急剧下降。

原因:

当某个应用程序更新程序包高速缓存的时候,就会产生一个全局的锁定,此时如果其他应用程序也要更新程序包高速缓存的时候,就会产生所等待,由于并发执行的SQL语句非常多,导致大量的锁等待,因此性能受到了极大的影响。

解决方案:

临时方案1

通过打开DB2的注册表变量

DB2_APM_PERFORMANCE启用无包锁定方式,这样就可以规避程序包高速缓存锁等待的问题。无包锁定方式虽然在一定程度上可以提高性能,但它不允许执PRECOMPILE、BIND和REBIND。所以如果需要执行BIND等这些操作的话,必须首先关闭DB2_APM_PERFORMANCE,然后重启实例后才能执行BIND。由于此方案在需要BIND等操作的时候需要重启实例,加大了运维的难度,所以此方案对于有7 x24业务需求的系统几乎是不能的。

临时方案2

通过修改JDBC DRIVER的方式解决此问题,通过修改应用程序代码,把不同的连接分布在多个connection中,通过轮询的方式以此来分散对程序包高速缓存的访问,从而避免锁竞争。

此方案实施后,性能有一定提升,但不是很明显。

针对这个问题,其实是架构设计不合理导致的,只是在数据库里面体现了出来。数据库层次的优化很难彻底解决这种性嫩问题,如果可以把架构重构的话,以下几种方式都可以减少此问题发生的机率:

1.在程序设计的时候借鉴SAP的并发管理机制,在模型层可以设计出一些队列,使任务通过队列的先进先出的机制,以及任务优先级的管理,这样就限制住了客户端对数据库的访问数量。也可以在应用服务器上设置数据库连接池,通过限制连接池的数量来限制客户端对数据库的访问数量。

2.通过把程序包高速缓存分布到多台服务器上,这样就可以减少锁等待的机率。实现这种方案的产品比如DB2 pureScale,oracle RAC。

3.根据业务拆分数据库,把不同业务的数据存放到不同的数据库中,同时开发出一套调用数据库的抽象层,这样即使有再多的数据库,对于上层来说都是透明的。这样不同业务的程序包高速缓存被分散到不同的数据库中。这样即可以解决程序包高速缓存锁等待的问题,又可以提高整体的性能。

4.3.6 小结

以上对各种架构及并发做了一个简单的介绍,总之在做应用架构设计的时候,要充分考虑到各个层次的并发均衡,可以吸取SAP的并发管理机制,不要把并发都压到数据库端,这样就会使系统的性能有整体的提高。

4.4 数据库数据生命周期管理

4.4.1 遇到的问题

业务系统在上线之初,系统的各个方面都非常的稳定,感觉运行飞快。然而随着时间的增长数据库数据量也开始积累,当积累到一定的阶段后数据量变得非常庞大,随之各种性能问题慢慢的凸显出来。

通常应用服务器是很容易水平(横向)扩展的,一台应用服务器不够,可以再增加一台,对于很多应用,应用服务器几乎具有无限制的水平扩展能力。所以一个系统,其甁颈往往出现在数据库。但是往往数据库中的数据按照要求又不能删除,数据库中的数据积累到一定的数量级之后,数据库中的性能问题就逐渐体现出现,越来越多的SQL性能问题,这些问题就不是单单优化SQL就能解决的。

从这些情况我们就不得不考虑数据库数据的生命周期问题,数据生命周期管理是一项复杂的系统工程,其规划比较简单,但是最大的难题是现有应用系统中的数据是否可以按照生命周期实施分离和删除,以及满足当年数据、历史数据使用的具体要求。

可以理解在数据库中的需要访问的数据大量减少的情况下,性能势必会得到显著提升。

在使用数据生命周期管理的方法对数据进行处理之后,由于数据的逻辑结构随之发生了变化,就需要从架构上对整个系统做适应性调整,以便适应数据库系统的变化。或者在系统设计之初,就从架构的角度对数据的生命周期有了良好的规划,同样能够保证业务能够适应这种数据变化。

在数据库系统中分为OLTP系统和OLAP系统,OLTP是传统的关系型数据库的主要应用,主要是基本的、日常的事务处理。所以在OLTP系统中我们应该保证系统有足够的处理能力,特别是CPU和IO的处理能力。为此我们应该把不需要在线使用的数据进行归档,并把归档的数据存储在历史库中,同时还可以考虑使用历史库进行查询分担生产压力。归档完成之后再对生产中的已归档数据进行安全删除。

而OLAP是数据仓库系统的主要应用,支持复杂的分析操作,侧重决策支持,并且提供直观易懂的查询结果。在仓库系统中应该进可能选择合适的系统架构,提供足够的处理能力CPU和IO,以满足复杂查询的需求。

4.4.2 案例分析

对于在线交易系统中那些类似交易流水的大表,往往因为数据量巨大,导致在查询时性能变得很差,及时创建索引也有可能提升不了多大的性能。在对这类表进行设计时,我们需要进行表结构上进行设计调整,以便快速的归档和卸载。

1)大表分区

在这里我们以DB2表分区为例,DB2表分区的优势有以下:

·分区在多个表空间内分布

·分区排除,增加SQL处理性能

·在不同的表空间内放置索引 (DB2 9.7)

·优化的 roll-in / roll-out处理(attach/deatch)

分区简化了表数据转入和转出以及管理工作,并且提高了索引位置的灵活性和查询处理效率。

对于这些在线交易的大表可以取某个特定的字段条件,对表进行分区,把表的数据分布到每个分片中。

我们可以把table1按照规划(时间,字段值范围)分成若干个分片,在不使用某个分片时可以快速的deatch出,这样保持了整个表的大小,这样就起到了在线表瘦身的作用。

另外分片因为是根据某个字段值定义的范围,如果语句中使用这个字段也能快速的定位到具体分片,从而节约IO,提高性能。

在DB2 9.7中新添加了针对索引的分片,这样在管理索引数据时更加的细微,当删除(deatch)某个分片时,对应的索引数据也可以快速的清除出整个索引,而不用对索引进行重组。另外索引分片也提高并发访问。

2)归档库建设和联邦访问

OLTP系统属于实时交易,并发量大的环境,同时查询更新的数据量并不需要很大,往往一段时间之前的数据基本上就很少进行业务访问了。我们需要把这些数据归档到归档库中,尽量的减少生产库的数据量级别,这样可以大大的减少CPU和IO的负担。

如下范例简单的介绍了某银行历史库的设计架构,希望对大家有一定的帮助,系统设计中有一个历史归档库,一个报表库。都是为了使生产系统不至于压力过大。

设计中从生产中产生的落地文件经过ETL加工,生成两种文件,一种是数据全量文件,一种是数据增量文件,全量文件被导入到历史归档库中,然后生产数据库会根据历史归档库中的数据把当前生产系统中不需要的数据清理。而另一种增量文件则为当前生产系统中的在线数据的差异,通过ETL MAPING 导入的报表库中,用以进行生产报表和其他系统的辅助查询。

通过以上两种方式,归档历史库中存储了生产系统中的冗余数据,为生产系统瘦身,另一报表库减低了生产系统的CPU和IO压力。

使用DB2的联邦功能去访问归档库,联邦技术支持异构数据库,用户在访问时可以屏蔽数据库之间的差异,这为进行数据归档集中也提供了方便。联邦的基本架构如下:

联邦技术可以轻松的把不同的数据库结合在一起,把归档的数据通过联邦传入归档库中。同时通过联邦也可以方便的对历史库进行查询。

3)数据安全删除

我们在对不需要在线交易的数据进行归档之后,需要对这些数据进行安全的删除,在删除这些数据时,需要对数据进行批量的删除,防止数据库日志满的情况发生。这里我们可以使用类似如下的存储过程进行批量的删除。当然这些清理的数据我们需要保证已经归档,删除对系统无影响。

另外IBM Optim提供了这样的数据归档和安全删除解决方案,下图为其大概的架构:

从图中,生产数据库中过度的数据按照业务人员的定义安全归档到指定的存储中,Optim工具会比对已经归档的数据然后对生产数据库中的数据进行删除,这样就可以保证生产中不需要的数据可以在归档系统中查到或者恢复,而不会出现不一致的情况。

Optim归档解决方案的主要功能如下:

从生产系统中将访问频率较低的历史、临时数据抽取到独立的归档文件中,以文件系统方式管理,从而减轻生产系统存储、维护压力,并支持廉价的历史数据分级存储能力。

归档后的数据可随时恢复至任意目标数据库用于审计、历史数据查询、报表访问等需求。归档文件也支持以不恢复方式的直接查询,用于满足访问频率较低的临时性历史查询需求。

4.4.3 小结

通过以上的各个案例介绍,我们能够理解到数据生命周期在数据库管理中的重要性,尽早的规划是规避风险的主要办法。在生产数据库中我们要了解数据生命周期的规划是否能满足当前数据库的需求,而不至于使数据库过于数据量庞大,另外还需要了解当前的规划是否能满足以后的业务量需求。使用各种技术手段,对生产系统的数据周期进行合适的调整,分散系统(CPU和I/O)的压力,对于生产系统的监控运行是非常必要的,这些将对系统的健康快速运行将起到非常大的作用。

5 总结

本文汇集民生银行多位资深DBA和架构师的切身体会,是多年项目开发和运维工作的经验总结,希望本文的一些观点能引起您的一些共鸣。“不识庐山真面目,只缘身在此山中”,这里我们引用苏轼的这句诗作为结尾,希望作为DBA的你们不要过分追求细枝末节,只看到庐山的一丘一壑,而是要把目光放远,去欣赏庐山的整体俊美。从架构的高度来看待数据库中的性能问题或许会得到更好的答案。

本文的一些观点各位读者也许有着不同理解,但是本文所提到的问题是确确实实存在,如果您有其他不同的看法或者问题,也非常希望能够一起探讨,一起共勉。

发布了23 篇原创文章 · 获赞 32 · 访问量 10万+

猜你喜欢

转载自blog.csdn.net/chenrui310/article/details/103598163