技术开发 频道

软件性能工程在数据库优化中的应用

  【IT168 专稿】本文根据【2016 第七届中国数据库技术大会】(微信搜索DTCC2014,关注中国数据库技术大会公众号)现场演讲嘉宾冷建全老师分享内容整理而成。录音整理及文字编辑IT168@ZYY@老鱼。

  讲师简介

软件性能工程在数据库优化中的应用
▲冷建全

  冷建全,人大金仓数据库业务部总监。毕业于中国人民大学信息学院,获工学硕士学位。毕业后加人大金仓,现为人大金仓公司数据库业务部总监,主要负责金仓数据库的架构设计和研发。对数据实现技术有深入研究,拥有多年研究和开发经验。

  正文:

  大家下午好,我是来自人大金仓的冷建全,我今天演讲的题目是:“软件性能工程在数据库优化中的应用”。跟大家一起探讨数据库优化中怎样系统化地思考优化工作。

  我今天的介绍主要分为如下几方面:

  1、 《软件性能工程》简介;

  2、 常见的6种系统性能优化模式;

  3、 人大金仓的简单介绍;

  《软件性能工程》本身是在探索用一种相对体系化和系统化的方式来分析性能问题。其实性能从用户的角度讲最重要的因素是响应时间、吞吐量等指标。当出现性能问题时,我认为最重要的原因还是资源无法满足系统要求,达不到我们对响应时间、吞吐量的要求,所以关于性能,关键的两个点:一个是资源,一个是对资源的使用。做性能优化最低级的方式是当响应时间、吞吐量达不到要求时,通过增加资源的方式例如增加机器、增加硬件来提高性能。但增加资源是有成本的,所以我们还是要考虑怎样在不增加资源的情况下更好的利用资源提高程序性能进而达到系统对响应时间、吞吐量的要求。围绕这个问题有6个常规的模式:

  1、 Fast Path(快速通道)。我们也叫短路径或快速路径。早期的工商银行ATM取款机登陆进去就会看到如下界面:

软件性能工程在数据库优化中的应用

  这个界面给人感觉按钮很多,有人民币、港币、美元、养老金等等很多信息,但是大部分人进来之后会点人民币,然后进行其他操作。但如果刚开始使用,在这种按钮很多的情况下,想要直接准确定位到需要的按钮可能会花一段时间,这个操作本身就会导致响应时间变慢,进而影响性能。这种模式最主要的问题是:系统中的常用功能其实只有20%,但如果我们对所有功能都无差别处理的话,我们很可能会陷入为了找20%的关键点在哪而浪费大量时间,这时可以采用Fast Path解决问题。为常用操作设置快速通道,简化无用的负载处理来提高整体的响应时间。现在的取款页面已经做得非常好了,对应到数据库优化其实就是一个sql的执行过程。

软件性能工程在数据库优化中的应用

  sql在数据库里一般会经历如下几个阶段:sql解析,词法分析,分析后形成一个词法分析树,然后对其进行逻辑优化、物理优化最后变成执行计划树,根据执行计划树生成执行计划的上下文状态,进行初始化,最后再执行。

软件性能工程在数据库优化中的应用

  如何快速高效地按照此路径运转呢?最常用的办法就是利用cache制造fast path,这里要注意两点,一是key,二是所能定位到的key的value。这是IT系统中的常见做法,数据库中也有很多。我们的数据库产品还提供result cache,对于变更较小且使用频繁的数据很有效,例如人事变动很少的人员信息,定期注册的信息等,同样我们也有各种统计视图用于定位需要cache的对象。另一类做法是通过数据组织跳过不必要的数据,例如索引、列存都是这类做法的应用。

  接下来跟大家分享一个实际案例:

  这个案例是实际工作中遇到的,应用于某省电信网管系统,面对的情况是他的业务压力大,一个业务表的IO非常大,整个表上已经有索引了,但是硬件配置偏低所以虽然有索引也无法全部缓存、定位,但访问量高,随机IO多。对我而言这个问题要怎么解决呢?

  首先要看为什么会出现这种情况,任何性能问题都要从根本上找原因,我们在产品里增加监控能力,做到块级、行级监控,通过监控发现,当其访问非常清晰的时候会出现有规律的点,某些值会访问的特别频繁。基于此,我们就可以对这个表常访问的值做cluster,之后就可以提高系统访问速度,这就是fast path典型案例。

  这种方式最大的风险就是要正确识别20%的主要对象,错误的主要对象识别会增加系统开销。比如说我做cache,我首先要快速查找定位里面是否有cache,如果没有,这个点就只能白做了。所以只能保证这20%的主要对象的效率提高,但其他操作会有一定受损。所以对20%主要对象的识别非常重要,如果识别错了只会带来副作用。

  2、 Batching(批量)。大家可以想象在京东规模很小的时候,刘总自己骑车送货,本身一次送一个快递,只有一个箱子是可以完成的,如果有多个请求,就必须先骑车去仓库把快递绑在车上,再骑车送到目的地,如此循环往复直至所有快递送完。完成请求需要的初始化、准备、结束等操作的开销较大,甚至比处理请求的开销还要大。所以解决方案就是,把这些事务采用批处理合并,减少平均处理开销。举个例子,在某市政务数据中心,大量小事务提交sync影响吞吐量,这时就可以采用批量提交解决sync问题。开发人员在写程序候也会看到许多类似的情况,比如我存在一条语句,绑参数的时候通常是一次绑1个,那么也可以通过一次绑多个的方式提高效率。集群产品的批量Insert,可以解决Insert Into Select的额外通信代价。系统整体的吞吐量提高了,但对单个操作来说是变长了,对业务本身来说属于我们可以接受的负面影响。

软件性能工程在数据库优化中的应用

  3、 Flex Path(弹性时间)。早上八点半的西二期有很多人在排队,这肯定不是我们希望的状态,针对这种情况的处理方案也非常容易理解——弹性时间,错峰运行。它本身的问题在于所有请求集中出现在某个特定时间段,集中请求导致负载高峰。业务上可以调整当然是最理想的状态,业务上无法调整的(比如:春运、秒杀),小范围的Flex Time也是可行的,例如应对秒杀的异步队列。

  给大家举个例子:某电网调度控制平台,为了缩短数据库系统发生故障后的恢复时间,通常会做检查点间隔。最早的系统在发出check point请求时,就会把共享的所有脏页面统一刷到磁盘上。我们遇到的问题是,刷check point启动点时,系统的效率整体快速下降,过一段时间又会上升。这个情况对业务的连续运行来说是不太好的一个现象,为了解决这个问题,我们在产品里引入check point完成速度目标,这样会计算两次check point之间的时间偏差,如果check point按时间设置以后3个小时做一次或者计算日志的写速度,就可以计算出下一次check point发生的时间,有了这两个数据之后,假如我有1万个请求,就可以把这1万个请求匀在3个小时内,这样对业务的影响就降低了,对业务的整体运行不会有断崖式的影响,但系统的整体恢复时间变慢了。所以说性能问题就是折中,我们要牺牲一个保证另一个,在资源的使用上做权衡。

  还有一个关于异步操作的例子,就是把复杂的操作比如并发量特别多且复杂的请求,会造成系统的响应时间变长、吞吐量下降,这时有两种思路可以解决这个问题:一是以请求为单位,比如前50个请求在这个时间段内做,另外50个在下个时间段做。另外一种方式比如操作本身很复杂的时候,可以分步做。我们可以把一个请求的前10步在一个时间段做,下一个10步在另一个时间段做,这本身也是一种弹性时间,错峰的方式。所以我想表达的意思是用弹性时间的方式既可以把任务横着切,也可以把任务切成若干段来做,这本身就是实现弹性时间段的方式。

  4、 First Things First(要事第一)。在北京上下班的时间或下雨会经常会遇到堵车非常厉害的情况,在这种情况下如果120被堵在路上将会造成非常严重的后果,这实际上就是系统本身的资源不足造成的。负载过高的情况下,系统资源发生紧缺,这种情况下系统本身没有能力处理这么多资源,但最重要的事情必须要保证在第一位执行,这个时候可以通过设置优先级的方式来设置资源,保证重要的业务按需完成。通过交通管制或其他方式设置专用通道保证120可以先行。

  我们举几个其他的例子:第一是资源争用,比如在CPU层面,实现set_backed_priority功能,用户可以在应用程序开发时调用该函数实现对整个进程或线程的优先级设置,通过这种方式提高线程数据的优先级;第二是IO层面,通过Memory间接影响,把关键数据替补到内存中;第三是Lock,提交并重新START IDLE的只读事务释放冲突的锁。

  我曾经也遇到过这样一种情况,某开发平台的框架只读事务不提交,导致长期持有大量shared lock,维护工作无法进行,加上后来的ETL上线,需要TRUNCATE,在这种情况下我们专门开发了一个功能,自动把idle只读事务提交,最终解决了这个问题。

  以上就是要事第一的方式,这种方式并不是没有问题,确实是保证了重要的事第一位,但是也会导致低优先级的请求被“饿死”,这就需要我们对自己的业务非常了解、知道最关键的事情是什么,同时优先级的设置要足够合理,既可以保证重要的事情优先处理,也可以保证其他事务不至于被“饿死”。

  5、 Coupling(耦合),也可以理解为打包。举个例子,比如我们要去登山,可能会带很多东西大刀、小刀、改锥、开瓶器、镊子等,装行李的时候就会非常头大,要装这么多东西不说,每个还非常尖锐不容易放,这就导致应用与数据之间的交互因粒度太细而过于频繁,细粒度数据逻辑处理造成的开销增加。解决方案类似于前面的批量,还是要打包!它和批处理的不同之处在于,批处理通常是处理同类型的任务请求,比如批量绑定,批量提交都是针对同类型的操作。而coupling是针对不同类型的操作。这个解决方案也是这样的思路,用瑞士军刀代替前边的所有东西,使用更粗粒度的对象以消除对多个细粒度对象的多次请求,这就是coupling,特别适用于应用/服务器通信和function/procedure的优化 。

  我们先举一个不需要技术角度理解的问题,实际上它与数据库是什么关系呢?

软件性能工程在数据库优化中的应用

  看描述可能第一时间想到JPA系列framework,这些框架的设计已经考虑了这些问题。我们在做优化的过程中也需要借鉴框架的思想:以上这个例子可以帮助大家理解coupling,就是把一些细粒度的请求想办法打包到一起,通过规避每一个请求可能带来的副作用提高效率。但是这个本身也不是没有问题,采用coupling这种方式打包完之后,对象可能会变得很臃肿,模式也会发生变化,那么就需要变更,变更本身扩展性也会受到影响。

  6、 Alternate Routes(替代路径)。替代路径主要针对高使用频率对象被多个请求独占导致处理串行化的问题。比较典型的案例是,当一个对象的冲突比较厉害时,其他所有对象都在反攻该对象,它本身就会成为一个瓶颈,导致处理变慢。解决方案也比较容易理解,找到它的替代路径,把该对象分散、并行,通过命令的方式执行。

  就比如刚刚提到的并发冲突对象的方式,比如通过某种方式做连接操作时,系统计算资源并没有增加,但是人为通过哈希方式快速扫描定位时,引入一个新的替代路径就可以缩短响应时间,提高性能。

  总结下来基本是以上6种模式,所有的性能问题都是系统对资源的使用存在问题或资源本身短缺,如果用心去思考的话会发现更多系统性能优化模式。我认为对模式的应用主要是两个层面:1、模式可以帮我们定位问题;2、模式可以告诉我们怎样解决问题。

  最后和大家分享一下,人大金仓的数据库和大数据业务:

软件性能工程在数据库优化中的应用

  今天的演讲到此结束,谢谢大家!

0
相关文章