acm-header
登录

ACM通信

实践

清晰思考性能,第2部分


表现阶段

信贷:极光剧院

回到顶部

在本文的第1部分(通信, 2010年9月,第55页),我介绍了一些性能的基本原理。性能a之间有关系吗任务时间它消耗。这种关系是可以测量的吞吐量响应时间。因为用户对性能差异的感觉比他们对平均值的感觉更强烈,所以最好用百分位格式,例如“任务”T必须有响应时间的R几秒或更少P执行死刑的比例或更多。”要诊断性能问题,需要根据吞吐量或响应时间,或两者,客观地陈述目标。

一个序列图是一个有用的图形化工具,可以帮助您了解任务的执行如何消耗您的时间。一个配置文件是一个表,显示关于单个任务执行的响应时间的详细信息。有了概要文件,您就可以确切地了解拟议投资的改进程度,但前提是您要了解做出错误假设的陷阱倾斜。

最大限度地减少风险。正如第1部分中提到的,修复一个任务的性能可能会损害另一个任务的性能,这让我想起了在丹麦发生的一件事。这是一个简短的故事:

场景:丹麦Måløv的餐桌;实际上,oak table Network是一个由Oracle从业者组成的网络,他们相信使用科学的方法来改进基于Oracle的系统的开发和管理。8大约有10个人围着桌子坐着,在笔记本电脑上工作,进行各种各样的交谈。

卡里:伙计们,我热死了。你介意我把窗户打开一点,让一些冷空气进来吗?

Carel-Jan:你为什么不脱下你的厚毛衣呢?

最后。

这里有一个普遍的原则,最优化的人都知道:当每个人都很高兴,除了你,确保你的本地事务是有序的,在你去搅乱影响其他人的全球事务之前。

这就是为什么每当有人提议改变系统的Oracle SQL*Net包大小时,我都会感到害怕,因为问题实际上是两个编写得很糟糕的Java程序,它们进行了不必要的数据库调用(因此,也进行了不必要的网络I/O调用)。如果除了一两个程序的用户之外,所有人都很顺利,那么问题最安全的解决方案就是将范围本地化到这一两个程序。

效率。即使整个系统中的每个人都受到了影响,您仍然应该首先关注业务需要修复的程序。开始的方法是确保程序尽可能高效地工作。效率是在不增加容量和不牺牲所需业务功能的情况下,可以减少多少任务执行的总服务时间的倒数。

换句话说,效率是浪费的反比。以下是数据库应用程序世界中常见的浪费例子:

  • 中间层程序为它插入到数据库中的每一行创建不同的SQL语句。它执行10000个数据库准备调用(因此有10,000个网络I/O调用),而它只需要一个就可以完成任务准备调用(因此减少了9,999个网络I/O调用)。
  • 中间层程序生成100个数据库获取调用(因此是100个网络I/O调用)来获取994行。它可以在10内获取994行获取调用(因此减少了90个网络I/O调用)。
  • 一个SQL语句(我在这里选择的文章形容词完全暴露了我是在Oracle社区中接触SQL的)要访问数据库缓冲区缓存7,428,322次,以返回一个698行结果集。一个额外的过滤器谓词可以返回最终用户真正想要看到的7行,而只需要对数据库缓冲区缓存进行52次操作。

当然,如果一个系统存在一些全局问题,导致整个系统中大量任务的效率低下(例如,考虑不周全的索引、设置不合理的参数、配置不合理的硬件),那么您应该修复它。但是,不要调优系统以适应效率低下的程序。(不可否认,有时你需要止血带来防止流血致死,但不要使用权宜之计作为永久解决方案。解决效率低下)。在解决程序本身的低效率方面有大量的杠杆作用。即使这些程序是商业现成的应用程序,从长远来看,与您的软件供应商合作使您的程序高效将比尝试优化您的系统以在固有低效的工作负载下运行更有利于您。

提高程序效率的改进可以为系统上的每个人带来巨大的好处。很容易看出顶部减少浪费如何有助于修复任务的响应时间。许多人还不理解的是,提高一个程序的效率会对系统上的其他程序产生性能改进的副作用,而这些程序与被修复的程序没有明显的关系。它的发生是因为负载在系统。

负载是由并发任务执行引起的对资源的竞争。这就是为什么软件开发人员进行的性能测试不能捕捉到生产中后来出现的所有性能问题的原因。

负荷的一种测量方法是利用,即在指定的时间间隔内,资源使用情况除以资源容量。随着资源利用率的增加,用户在向该资源请求服务时的响应时间也会增加。任何在大城市的高峰时段乘坐过汽车的人都经历过这种现象。当交通非常拥挤时,你必须在收费亭等更长的时间。

当你在拥挤的交通中以30英里每小时的速度行驶,而不是在开阔的道路上以60英里每小时的速度行驶时,你使用的软件并不会像你的汽车那样“走得更慢”。无论如何,计算机软件总是以相同的速度运行(每个时钟周期有恒定数量的指令),但是当系统上的资源变得繁忙时,响应时间肯定会下降。

当负载增加时,系统变慢有两个原因:排队延迟而且相干延迟。

排队延迟。负载和响应时间之间的数学关系是众所周知的。一个数学模型叫做M/M/,在满足一组特别有用的特定需求的系统中,将响应时间与负载联系起来。7M/M/的假设之一您所建模的系统是否具有“理论上完美的可伸缩性”。这类似于拥有一个“没有摩擦”的物理系统,这是物理学入门课程中许多问题都会用到的假设。

不考虑一些过分的假设,比如关于完美可伸缩性的假设,M/M/有很多关于性能的东西可以教我们。图1用M/M/表示响应时间与负载之间的关系

在图中,您可以从数学上看到在不同负载条件下使用系统时的感受。在低负载时,您的响应时间基本上与无负载时的响应时间相同。随着负载的增加,您会感到响应时间有轻微的、逐渐的下降。这种逐渐的退化实际上并没有造成太大的危害,但是随着负载继续增加,响应时间开始以一种既不轻微也不逐渐的方式退化。相反,退化变得非常不愉快,事实上,是双曲线的。

响应时间(右),在完美的可扩展性M/M/模型,由两个组件组成:服务时间(S)而且排队延迟(问),或R年代+.服务时间是任务消耗给定资源的持续时间,以每次任务执行的时间来衡量,如秒每点击。排队延迟是指任务在给定资源上排队等待其使用该资源的机会所花费的时间。排队延迟也以每次任务执行的时间来衡量(例如,每次单击的秒数)。

换句话说,当你在Taco Tico点午餐时,你的响应时间(R)为排队延迟时间(你在柜台前等人点餐的时间,加上服务时间(年代),当你开始和点单员交谈时,你花了很多时间来等待你的订单打到你的手上。排队延迟是给定任务的响应时间与在其他未加载系统上的相同任务的响应时间之间的差值(不要忘记我们的完美的可伸缩性假设)。

回到顶部

我的膝盖

当谈到性能时,你想从系统中得到两件事:

  • 你能得到的最佳响应时间:你不想为完成任务而等待太长时间。
  • 您可以获得的最佳吞吐量:您希望能够将尽可能多的负载塞到系统中,以便尽可能多的人可以同时运行他们的任务。

不幸的是,这两个目标是矛盾的。优化第一个目标需要最小化系统上的负载;优化第二个目标需要你最大化它。你不能同时做这两件事。在某个负载水平(即某个利用率值)之间的某个位置是系统的最佳负载。

达到这种最佳平衡的利用值称为膝盖。在这个点上,吞吐量最大化,对响应时间的负面影响最小。(我一直在争论用这个词是否合适膝盖在这种情况下。就目前而言,我将继续使用它;看到侧边栏详情)。在数学上,膝盖是响应时间除以利用率达到最小值时的利用率值。膝盖的一个很好的特性是它出现在利用值处,穿过原点的一条线与响应时间曲线相切。在一个精心制作的M/M/图中,你可以很好地用直边定位膝盖,如图所示图2

M/M/的另一个很好的性质膝盖是你只需要知道一个参数的值来计算它。这个参数是平行的,齐次的,独立的服务渠道。服务通道是一种资源,它与其他相同的资源共享一个队列,例如收费站中的一个摊位或SMP(对称多处理)计算机中的一个CPU。

斜体小写在术语M/M/中正在建模的系统中服务通道的数量。M / M /膝值对于任意系统是很难计算的,但我已经做过了表1,它显示了一些常用服务通道计数的膝值。(到这里,你可能想知道M/M/中的其他两个M代表什么排队模型的名字。它们与关于传入请求时间的随机性和服务时间的随机性的假设有关。看到http://en.wikipedia.org/wiki/Kendall%27s_notation如需更多信息,或优化Oracle性能7更多。)

为什么膝盖值如此重要?对于具有随机时间服务请求的系统,允许持续的资源负载超过膝值将导致响应时间和吞吐量随着负载的微观变化而严重波动。因此,在具有随机请求到达的系统上,至关重要的是要管理负载,以使其不会超过膝值。

回到顶部

膝盖的相关性

这个膝盖的概念到底有多重要?毕竟,正如我告诉你的,M/M/模型假设了一个荒谬的乌托邦式的想法,即你所考虑的系统是完美伸缩的。我知道你在想什么:它没有。

M / M /给我们的知识是,即使你的系统是完美的伸缩,你仍然会遭受巨大的性能问题,一旦你的平均负载超过膝盖的值表1.你的系统不如理论系统M/M/模型。因此,利用率值在你的系统的双膝发生时将比中值更有约束表1.(我用的是复数而且膝盖因为您可以用一种模型建模cpu,用另一种模型建模磁盘,用另一种模型建模I/O控制器,等等。)

回顾一下:

  • 系统中的每个资源都有一个“膝盖”。
  • 每个资源的“膝”值小于或等于你可以查询的“膝”值表1.你的系统规模越不完美,你的膝盖值就越小(更糟糕)。
  • 在具有随机请求到达的系统上,如果您允许系统上任何资源的持续利用率超过该资源的最小值,那么就会出现性能问题。
  • 因此,管理您的负载以使您的资源利用率不会超过您的膝盖值是至关重要的。

回到顶部

容量规划

理解膝盖可以瓦解你的能力计划中的许多复杂性。它是这样工作的:

  • 对于给定资源,您的目标容量是在峰值时间可以轻松地运行任务,而不会使利用率超出您的承受能力。
  • 如果你保持你的利用率低于你的膝盖,你的系统行为大致线性-没有大的双曲线意外。
  • 但是,如果您让系统运行的任何资源超过了它们的膝盖利用率,那么就会出现性能问题(无论您是否意识到这些问题)。
  • 如果你有性能问题,那么你不需要把时间花在数学模型上;您需要花费时间通过重新调度负载、消除负载或增加容量来解决这些问题。

这就是容量规划如何与性能管理过程相适应。

回到顶部

随机到达

你可能已经注意到我用了这个词随机到达好几次了。为什么这很重要?


膝值在随机到达的系统中如此重要的原因是,这些值往往会聚集在一起,造成利用率的临时峰值。


有些系统有一些您现在可能没有的东西:完全确定的作业调度。有些系统(虽然现在很少见)被配置为允许服务请求以绝对的机器人方式进入系统,例如,以每秒一个任务的速度。我指的不是平均每秒一个任务的速度(例如,一秒两个任务,下一秒一个任务都没有);我指的是每秒完成一项任务,就像机器人把汽车零件放进装配线上的垃圾箱一样。

如果到达你的系统的行为完全是确定的,这意味着你知道完全当下一个服务请求到来时,您可以运行资源利用率超过他们的膝盖利用率,而不必产生性能问题。在具有确定性到达的系统上,您的目标是运行资源利用率达到100%,而不会向系统中塞进太多的工作负载,从而导致请求开始排队。

膝值如此重要的原因是随机到达的是,这些往往聚集在一起,导致利用率的临时峰值。这些峰值需要足够的空闲容量来消耗,这样用户就不必在每次出现峰值时忍受明显的排队延迟(这会导致明显的响应时间波动)。

对于给定的资源,只要它们的持续时间不超过几秒钟,其利用率的临时峰值就可以超过你的膝盖值。但是多少秒算多呢?我认为(但还没有尝试去证明)你至少应该确保你的峰值持续时间不超过8秒。(如果你听说过“8秒规则”,你就会认出这个数字。2答案当然是,如果你不能满足基于百分比的响应时间承诺或对用户的吞吐量承诺,那么你的峰值就太长了。

回到顶部

相干延迟

您的系统没有理论上完美的可伸缩性。即使我从来没有专门研究过你的系统,我敢打赌,无论你现在考虑的是什么计算机应用系统,它都不符合M/M/“理论上完美的可扩展性”假设。相干延迟是你可以用来模拟不完美的因素。4它是任务在通信和协调对共享资源的访问上所花费的时间。与响应时间、服务时间和排队延迟一样,一致性延迟是以每次任务执行的时间来衡量的,即每次单击的秒数。

我不会描述预测一致性延迟的数学模型,但好消息是,如果您分析您的软件任务执行情况,您将在它发生时看到它。在Oracle中,像下面这样的定时事件是一致性延迟的例子:

  • 排队
  • 缓冲忙等待
  • 门闩免费

你不能用M/M/来建模这样的一致性延迟.那是因为M/M/假定所有你的服务渠道是平行的、同质的和独立的。这意味着该模型假设,在您礼貌地在FIFO队列中等待足够长的时间后,所有排在您前面的请求都退出了服务队列,然后将轮到您接受服务。然而,一致性延迟并不是这样工作的。

想象一个HTML数据输入表单,其中一个标记为“Update”的按钮执行一条SQL更新语句,另一个标记为“Save”的按钮执行一条SQL提交语句。这样构建的应用程序几乎保证了糟糕的性能。这是因为它的设计使得用户很有可能点击更新,查看他的日历,意识到“哦哦,我吃午饭迟到了”,然后吃了两个小时的午饭,然后下午再点击保存。

这对系统上其他想要更新同一行的任务的影响将是毁灭性的。每个任务都必须等待行上的锁(或者,在某些系统中,更糟糕的情况是:行页面上的锁),直到锁定的用户决定继续执行并单击save,直到数据库管理员终止用户的会话,这当然会对认为自己更新了一行的人产生令人讨厌的副作用。

在这种情况下,任务等待锁释放的时间与系统的繁忙程度无关。它将取决于存在于系统各种资源利用之外的随机因素。这就是为什么你不能在M/M/中建模这类东西这也是为什么您永远不能假设在单元测试类型的环境中执行的性能测试就足以决定是否在生产系统中插入新代码。


所有这些关于排队延迟和一致性延迟的讨论导致了一个非常困难的问题:如何才能对一个新应用程序进行足够的测试,以确保不会因为性能问题而破坏生产实现?


回到顶部

性能测试

所有这些关于排队延迟和一致性延迟的讨论导致了一个非常困难的问题:如何才能对一个新应用程序进行足够的测试,以确保不会因为性能问题而破坏生产实现?

你可以模型。你可以进行测试。1然而,你所做的一切都不是完美的。创建模型和测试是非常困难的,在这些模型和测试中,您可以预见所有的生产问题,而不是在生产中实际遇到这些问题。

有些人认为这种观察是徒劳的,因此根本不进行测试。不要陷入那种心态。以下几点是肯定的:

  • 如果您尝试在生产之前发现问题,那么您将发现比不尝试更多的问题。
  • 您永远不可能在生产前测试中发现所有的问题。这就是为什么您需要一种可靠而有效的方法来解决通过生产前测试过程泄漏的问题。

适当的测试量应该介于“不测试”和“完全生产模拟”之间。对于飞机制造商来说,适当的测试量可能比出售棒球帽的公司要多。但是不要完全跳过性能测试。至少,您的性能测试计划将使您在修复生产操作过程中不可避免发生的性能问题时成为更有能力的诊断人员(和更清晰的思考者)。

测量。人们感受吞吐量和响应时间。吞吐量通常很容易测量,而响应时间则要困难得多。(记住,吞吐量和响应时间是倒数)。用秒表为终端用户的操作计时可能并不困难,但要获得真正需要的东西可能非常困难,也就是深入了解为什么给定的响应时间如此之长的能力。

不幸的是,人们倾向于衡量容易衡量的东西,这并不一定是他们应该是测量。这是一个错误。那些不是您所需要的,但很容易获得且似乎与您所需要的相关的度量称为度量代理措施。示例包括子例程调用计数和子例程调用执行持续时间的示例。

我很惭愧,我对自己的母语没有比这样说更好的掌握能力,但这里有一个朗朗上口的现代方式来表达我对替代措施的看法:吸替代措施。

在这里,不幸的是,并不意味着从来没有工作。实际上,如果替代措施从未奏效,情况会更好。那就没人会用了。问题是替代措施有效有时。这激发了人们的信心,认为他们使用的措施应该一直有效,但事实并非如此。替代措施有两个大问题。

  • 当你的系统不好的时候,他们可以告诉你它是好的。这就是统计学家所说的第一类误差假阳性。
  • 他们会告诉你某件事有问题,但实际上并没有。这是一个II型错误假阴性。我见过各种类型的错误浪费了人们多年的时间。

当需要评估一个真实系统的细节时,您的成功取决于您的系统允许您获得的度量有多好。我很幸运能在Oracle细分市场工作,在这个市场中,处于我们宇宙中心的软件供应商积极参与,使以正确的方式度量系统成为可能。让应用软件开发人员使用Oracle提供的工具是另一回事,但至少产品中有这些功能。

回到顶部

性能是一个特性

性能是一种软件应用程序特性,就像识别一个形式为“Case 1234”的字符串可以方便地自动超链接到bug跟踪系统中的Case 1234。(我喜欢使用的FogBugz软件就能做到这一点。)性能和其他特性一样,不是凭空出现的;它必须被设计和建造。为了提高性能,您必须考虑它,研究它,为它编写额外的代码,测试它,并支持它。

然而,与许多其他特性一样,当您仍然在编写、研究、设计和创建应用程序时,您无法确切地知道性能将如何发挥作用。对于许多应用程序(可以说是绝大多数应用程序),直到软件开发生命周期的生产阶段,性能都是完全未知的。这给您留下的是:由于您无法知道您的应用程序将如何在生产环境中执行,所以您需要编写您的应用程序,使其易于执行修复生产性能。

正如大卫·加文(David Garvin)教给我们的,管理容易度量的东西要容易得多。3.编写易于在生产环境中修复的应用程序要从易于在生产环境中度量的应用程序开始。

通常,当我提到生产性能度量的概念时,人们会陷入对性能度量的度量侵入效应的担忧状态。他们立即进入一种数据收集妥协模式,只留下替代措施。带有额外代码路径的软件不会比没有额外代码路径的软件慢吗?

我喜欢Tom Kyte对这个问题的回答。6他估计Oracle广泛的性能检测的测量入侵效应是10%或更少(其中或更少意味着或更好的如20%、30%等)。他继续向一个现在很恼火的提问者解释说,由于甲骨文公司从其性能检测代码中获得的知识,该产品现在至少快了10%,这远远弥补了检测可能造成的任何“开销”。

我认为供应商往往花太多的时间担心如何使他们的度量代码路径有效,而没有先弄清楚如何使它有效。它完全符合Knuth在1974年所写的观点,即“过早优化是万恶之源”。5将性能度量集成到产品中的软件设计人员更有可能创建一个快速的应用程序,而且更重要的应用程序会随着时间的推移而变得更快。

回到顶部

致谢

谢谢你,施瓦茨男爵的邮件对话,你认为我在帮助你,但实际上,你帮助我认识到在我的思想中更突出地引入连贯延迟的必要性。感谢杰夫·霍尔特、罗恩·克里斯科、肯·费利塔和哈罗德·帕拉西奥,感谢你们的日常工作使公司继续运转,感谢你们的午餐交谈使我的想象力不断发展。谢谢你,汤姆·凯特,谢谢你一直以来的鼓励和支持。谢谢你,马克·法纳姆的有益建议。谢谢尼尔·冈瑟在我们持续讨论膝盖问题时的耐心和慷慨。

ACM队列的q戳相关文章
queue.acm.org

你做错了
Poul-Henning坎普
http://queue.acm.org/detail.cfm?id=1814327

性能反模式
巴特Smaalders
http://queue.acm.org/detail.cfm?id=1117403

隐藏在显而易见的地方
布莱恩Cantrill
http://queue.acm.org/detail.cfm?id=1117401

回到顶部

参考文献

1.CMG(计算机测量集团,一个非常非常认真地研究这些问题的专业人员网络);http://www.cmg.org

2.八秒规则;http://en.wikipedia.org/wiki/Network_performance#8-second_rule

3.建立学习型组织。哈佛商业评论(1993年7月)。

4.计算可扩展性的普遍定律(1993);http://en.wikipedia.org/wiki/Neil_J._Gunther#Universal_Law_of_Computational_Scalability

5.Knuth, D.使用Go To语句的结构化编程。ACM计算调查6, 4(1974), 268。

6.Kyte, T.几个链接和一个广告…http://tkyte.blogspot.com/2009/02/couple-of-links-and-advert.html

7.C.米尔萨普和J.霍尔特。优化Oracle的性能。奥莱利,塞瓦斯托波尔,加州,2003年。

8.橡木桌子网络;http://www.oaktable.net

回到顶部

作者

卡里-米尔萨普是Method R公司的创始人及总裁(http://method-r.com),这是一家致力于软件性能的公司。他(与杰夫·霍尔特)是优化Oracle性能(奥莱利),也是甲骨文洞见:橡树桌的故事(然后)。他是Oracle公司系统性能组的前副总裁和他的前公司Hotsos的联合创始人。他也是Oracle ACE总监和Oak Table Network的创始合伙人,Oak Table Network是一个由知名“Oracle科学家”组成的非正式协会。米尔萨普博客http://carymillsap.blogspot.com,并在http://twitter.com/CaryMillsap

回到顶部

脚注

DOI: http://doi.acm.org/10.1145/1831407.1831422

回到顶部

数据

F1图1。这条曲线将响应时间作为M/M/利用率的函数系统= 8个服务通道。

F2图2。膝关节发生在通过原点的一条线与响应时间曲线相切的位置。

回到顶部

T1表1。M / M /膝值为常用值

回到顶部

1.Apdex;http://www.apdex.org

2.米尔萨普,C.绩效管理:神话和事实(1999);http://method-r.com

3.Samson, S. mv表演传奇。在计算机测量小组会议论文集(1988), 148159。

UF1-1数字A.冈瑟最大允许利用值T是否定义为产生平均响应时间的利用率T。

UF1-2数字b .附近T值,平均利用率的微小波动会导致较大的响应时间波动。


©2010 acm 0001-0782/10/1000 $10.00

允许为个人或课堂使用本作品的全部或部分制作数字或硬拷贝,但不得为盈利或商业利益而复制或分发,且副本在首页上附有本通知和完整的引用。以其他方式复制、重新发布、在服务器上发布或重新分发到列表,需要事先获得特定的许可和/或付费。

数字图书馆是由计算机协会出版的。版权所有©2010 ACM, Inc。


没有发现记录

Baidu
map