您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 市场营销 > 开发运维测试--认清性能问题
今年越来越多开发者开始关注移动应用性能管理和性能监测,我们找到一位国外资深的开发者对性能的相关理论,希望各位喜欢。1.公理化方法当我在1989年加入oracle公司时,解决性能问题(人们通常说的oracle调优)是很困难的。只有少部分人声称他们很擅长这个,很多人都去咨询他们。当时,我进到oracle调优这个领域时,我完全没准备好。最近我又开始对mysql进行调优,这看起来和我20年前在oracle公司做的差不多。它让我想起了当我13岁刚接触代数学时是多么的困难。在那个年龄我只能依靠“数学直觉”来解决类似3x+4=13这样的方程。问题是我们之中大部分人都没有所谓的“数学直觉”。我记得当看到这样的问题:3x+4=13求解x,只能采用试错法偶然发现x应该是3。试错法给我的感觉虽然能解决一些简单的方程式,但很慢而且不爽。一旦等式稍有变化如3x+4=14,试错法就不能适应。那么该怎么办呢?当时我没有好好思考过,直到15岁时JamesR.Harkey指引我走上正确的道路。Harkey先生教会我使用公里方法来解决代数方程问题。他给我们展示了一系列的步骤(还给了我很多家庭作业进行练习)。做作业时除了记录下这些步骤,还要写下我们是如何思考的。这样我们不仅自己想的很清楚,而且通过一系列可靠的,可重复的步骤来向阅读我们作业的人证明了我们确实搞明白了。Harkey先生看到的我的作业像下面这样:3.1x+4=13待求解方程3.1x+4-4=13-4减去相等的值3.1x=9加法逆运算,化简3.1x∕3.1=9∕3.1除以相等的值x≈2.903乘法逆运算,化简求解这就是Harkey先生教导的适用于代数学、几何学、三角学和微积分的公理化方法。由一系列符合逻辑的、可证明和审计的小步骤组成。这是我第一次真正从数学中学到的东西。自然,当时我没能认识到其中的价值,但证明作为一种技能对我后来的成功至关重要。我发现在生活中,知道一件事很重要,但能向别人讲清楚(证明)更重要。没有好的证明技能,就很难成为一名好的顾问、好的领导甚至好的员工。我在上世纪90年代中期的目标是为oracle性能优化创建一套类似的、严格的公理化方法。后来我将其扩展到了oracle之外,建立了一套适用于所有计算机软件性能优化的公理化方法。好吧,我发现并非所有人都喜欢这种说法,那我们换一种说法:我们的目标就是帮助你想清楚如何优化你的软件系统性能。2.什么是性能?假如你去google下performance这个关键字,可能会得到5亿个链接。其中涉及的内容范围可能从自行车比赛到可怕的员工审查流程(如今很多公司已经学会了避免这个流程)。但假如我去google下performance这个关键字,大部分的首页链接都会与这篇文章的主题有关:计算机软件执行无论何种任务所花费的时间。任务这个词是一个很适合的开始。任务是一个面向业务的工作单元。任务能够嵌套:打印发货单是一个任务,打印一张发货单(一个子任务)也是一个任务。当一个用户说起性能时,他通常指的是系统执行一系列任务所花费的时间。响应时间是任务的执行时长,用每个任务的时间来度量,像:每点击秒数。例如我用google搜索关键字performance的响应时间是0.24秒。这个数据来自我的浏览器渲,它渲染完google网页花费的时间,那么很明显,这量化了我对google性能的直觉感知。一些人对另外一个性能指标很感兴趣:吞吐量。吞吐量是在一个特定时间段内完成的任务的计数,例如:每秒点击数。通常为一群人提供服务比为个别人提供服务的人更关心吞吐量。例如,一个独立会计会更关心日报的响应时间是否会导致今晚需要加班,而会计部的经理更关心系统的是否能支撑所有的会计处理完今天的数据。3.响应时间VS.吞吐量通常来讲,响应时间和吞吐量是一个倒数关系(响应时间越长吞吐越低),但这并不确切。实际情况更微妙、复杂一些。例:假如,在一些性能基准测试中,你的系统的测量结果是每秒能处理1000个任务,那么用户的平均响应时间是多少?你可能会说平均响应时间等于1/1000=.001秒/每任务,但它真不是这样的。假如在你的系统内部拥有1000个相同的、独立的、并行的服务执行通道,每个通道都在等待请求到来并提供服务。在这种情况下,每个请求其实花费了1秒。现在我们知道,平均响应时间其实应该在每任务0秒到1秒之间。但是我们不能仅仅从吞吐量的测量数据中推导出平均响应时间。(事实上存在数学模型从吞吐量推导出平均响应时间,但这个模型要求更多的输入参数,而不仅仅是吞吐量)你必须单独测量它。反过来说也是一样的,你应该能从我上面给出的例子中得到启发。下面是一个更有趣的例子。例:你的客户要求一个新任务必须满足在单核cpu的计算机上达到每秒100的吞吐量。假如这个新任务在客户的系统上执行一次需要0.001秒。那么你的程序能够满足客户要求的吞吐量么?你可能会说,跑一次这个任务只需要千分之一秒,那么在一秒内完成100次显然是绰绰有余的。恩,是的,你很正确,假如这个任务被很好的串行化了。例如,你的程序处理100个任务执行请求是在一个循环中,一个接一个的执行,那就是正确的。但是如果这100个任务到达你的系统是完全随机的来自100个不同的用户,那该怎么办呢?cpu调度器和串行资源(oracle的闩和锁,内存可写缓冲区访问)这些糟糕的实际情况会严格限制你的并发吞吐量低于每秒100。最终,你可能会达到客户的期望也可能达不到。你不能仅仅从响应时间推导出吞吐量,你必须单独测量吞吐量。所以,响应时间和吞吐量不是那么简单的互为倒数关系。你想要知道这两个指标,就必须一起测量它们。那么响应时间和吞吐量到底哪一个更重要呢?在一些场景下,说哪一个都是合理的。但在大多数情况下,两者都同样重要。因为,对系统来说它的业务需求通常是这样的,在大于99%的情况下响应时间要少于1秒,并且能支持10分钟内持续不低于1000的吞吐量。4.百分比指标在上一节,我用了“大于99%”这样的描述来表达对响应时间的期望。但大部分人可能更习惯于这样的描述:“平均响应时间少于r秒”。但从经验的角度,使用百分比方式更好。例:假如你对一些每天运行在你的计算机上的任务的响应时间的容忍极限是1秒。进一步假设表1列出了该任务执行10次的测量值。这两个列表的平均响应时间都是1秒。哪一个你认为更好?你看到虽然两个列表拥有同样的平均响应时间,但本质上差别很大。ListA90%的响应时间是低于1秒的,而ListB只有60%的时间是低于1秒的。从用户体验的角度来说,ListB表明会有40%的用户会感到不满意,而ListA仅有10%的不满意率,虽然它们平均响应时间相同。ListA90%的响应时间是0.987秒,而ListB90%的响应时间是1.273秒。因此使用百分比描述的响应时间比平均响应时间包含更多的信息量。99.9%的跟踪货运单的任务必须在0.5秒内完成。5.问题诊断最近我被邀请去解决的一些性能问题的描述都是些关于响应时间的。如:“过去只用不到1秒的时间就能完成X任务,但是现在却需要20秒。”当然,一些真正的问题隐藏在其他一些问题描述的表象背后,例如:“我们的系统变的很慢,完全没法用了。”虽然我经常碰到类似这样的表述,但并不意味着你应该这样去描述问题。首先你得清晰得描述问题本身,才可能把它们弄清楚。一个好办法是去询问,你想要达到得目标状态是怎样的呢?找到一些细节,你可以用量化的方式来表达它们。例如:执行X任务大部分情况下都超过20秒,希望能在95%的情况下小于1秒。理论上这听起来很棒,但要是你的用户根本没有很具体的可以量化的目标呢?或者你的用户根本就不知道怎样去量化,更糟糕的情况是你的用户如果还有一些完全不切实际的期望怎么办?你如何知道到底什么是“可能的”,什么是“不切实际的”?好吧,下面我们继续探讨这些问题。6.序列图序列图是一种UML(统一建模语言)中定义的图形种类,用于表达对象间交互的发生顺序。序列图特别适合用于可视化的表达响应时间。在图1中,我们展示了一个由浏览器、应用服务器和数据库构成的简单应用系统的序列图。假如我们扩展下序列图的表示,让请求和响应之间距离表示服务该请求的消耗时长。在图2中我展示了一个扩展后的序列图。通过图2,你可以很直观的看到到底是哪个部分消耗了最多的时间。你能直观的感受到整个响应时间在各个部分的构成。序列图很好的帮助人们从概念上直观的理解一个任务如何在系统各个部分之间顺序流转的。序列图也能很好的表达并行执行的任务。序列图也是一个很棒的工具用于在业务层次分析性能问题。序列图是很好的描述性能问题的概念工具,但要把性能问题分析清楚我们还需要其他的。序列图的问题是,假设有个任务花费了2468秒才执行完成(大约41分钟8秒)。在这41分钟里,应用服务器和数据库大约交互了322968次。把这个过程画成序列图大概就是下面图3的样子:在应用服务器和数据库之间有如此之多的箭头,以至于你完全看不清细节了。我们可能需要花费数周才能画完这个图,但这并不是一个有效的方法。序列图虽然很好的概念可视化了任务的执行流和时间流,但要仔细分析清楚响应时间的问题我们还需要别的工具。7.性能剖析对于像上述这种拥有大量调用交互的情况,序列图不能很好的描述。我们需要一种更方便的聚合视图来更容易的理解到底哪个部分消耗了最多的时间。表2给出了一个性能剖析的例子。性能剖析是对响应时间的表格化分解,按响应时长倒序排列如下。例:表2中的性能剖析是很初级的,但它能告诉你top8的慢任务占用了2468秒。从中你大概可以得到每个函数的响应时长占比。也可以从中算出每个函数调用的平均响应时间。从表2的数据表明,大约70.8%的响应时间消耗在了DB:Fetch()这个方法上。如果你进一步深入方法调用中会发现App:await_db_netIO()方法与DB:Fetch()的一一对应关系。于是能知道每个部分消耗了多少时间,通过性能剖析你开始能够明确的回答像这样的问题:“这个任务需要运行多长时间?”从第5节你可以知道,对问题诊断的第一步来说这是一个很重要的问题。8.阿姆达尔定律性能剖析能帮你分析清楚性能问题。即便基恩·阿姆达尔在1967年没有告诉我们阿姆达尔定律,你也可以在看到性能剖析表格时自己归纳出来。阿姆达尔定律指出:系统中对某一部件采用更快执行方式所能获得的系统性能改进程度,取决于这种执行方式被使用的频率,或所占总执行时间的比例所以如果你尝试改进的部分只占总响应间的5%,那么对总响应时间的提高最多不会超过5%。这意味着你改进的部分在性能剖析列表中排位越高(假设它们按倒序排列),你获得的收益就越大。但这并不意味着你一定要按照性能剖析列表的顺序从高到低进行改进,这里你还需要考虑改进的成本问题。例:看下表3,它基本和表2一样。表3额外给出了你实施最好的改进方案所能达到的效果以及相应的实施成本。那么你应该先实现哪一项改进呢?阿姆达尔法则告诉我们改进第一项的潜在收益最大,大约可以减少851秒(34.5%*2468秒)。但改进第一项真的非常昂贵,那么改进第二项也许能产生更多的净收益。这才是我们真正需要改进的瓶颈所在,尽管它仅能节省大约303秒。你首先实施哪一项改进,归结于你对成本评估有多大把握,简单省事的改进的措施是否考虑了改进可能造成的系统风险?一个很简单的改进,例如调整了某个参数,取消了一个索引可能会潜在的破坏了一些目前性能表现良好的功能,而你又完全没考虑倒。靠谱的成本评估则是展现你技术能力的另一个领域了。另一个因素值得考虑的是,你可以通过一些小的成功来积累政治资本。也许一些便宜低风险的改进并不能带来响应时间的大幅度降低,但可以通过跟踪记录这些小改进来印证你对响应时间提升的预测。在神话和迷信统治了数十年的软件性能领域,这些对性能的预测和印证的跟踪记录,可以影响你的同事(工程师、经理、客户)并建立自己的信誉,然后你才可能实施更昂贵的改进方案。最后提醒一句:当你不断取得胜利并建议实施成本更高、风险更大的改进措施时,可千万别掉以轻心。信任是很脆弱的,你做了很多事情才取得信任,但可能只是因为一次粗心大意的错误就会摧毁它。9.偏斜度当
本文标题:开发运维测试--认清性能问题
链接地址:https://www.777doc.com/doc-2427823 .html