基准测试(benchmarking)是一种测量和评估软件性能指标的活动。你可以在某个时候通过基准测试建立一个已知的性能水平(称为基准线),当系统的软硬件环境发生变化之后再进行一次基准测试以确定那些变化对性能的影响。这是基准测试常见的用途。其他用途包括测定某种负载水平下的性能极限、管理系统或环境的变化、发现可能导致性能问题的条件,等等。

  基准测试的具体做法是:在系统上运行一系列测试程序并把性能计数器的结果保存起来。这些结构称为“性能指标”。性能指标通常都保存或归档,并在系统环境的描述中进行注解。比如说,有经验的数据库专业人员会把基准测试的结果以及当时的系统配置和环境一起存入他们的档案。这可以让他们对系统过去和现在的性能表现进行对照比较,确认系统或环境的所有变化。

  基准测试通常都是些功能测试,即测试系统的某个功能是否达到了预期的要求。有些性能测试工具可以对系统几乎所有的方面(从常见的操作到复杂的操作,从小负载到中等负载到大负载)进行测试。

  大部分程序员只在系统发生了奇怪的事情时才考虑进行基准测试,但我认为定期进行基准测试,尤其是在重大事件(比如系统或环境发生变化)之前和之后进行基准测试更有意义。一定要首先进行一次基准测试以创建基准线。如果没有基准线作为参照物,在事件发生之后进行的基准测试是不会对你有多大帮助的。

  1、基准测试的指导原则

  在进行基准测试的时候,有许多好的实践方法。在这一节里,我将向大家介绍几个我认为对大家有帮助的基准测试原则。

  首先,应该牢记“事前快照”和“事后快照”的概念。不要等到你对服务器做出修改之后才想起应该进行一次基准测试并把测试结果与你在六个月前建立的基准线进行对比。六个月的时间会发生许多事情!你应该在做出修改之前进行一次测试,做出修改,然后再对系统进行一次基准测试。这可以让你对三组性能指标进行对比:系统的预期性能、它在修改前的实测性能以及它在修改后的实测性能。你可以发现所发生的事情让你的改变多少会明显一些。比如说,假设你的基准测试有一项是度量查询时间。你在六个月前为某个特定的测试查询建立的基准线需要花费4.25秒才能完成。现在,你决定修改受测表的某个索引。你在修改之前进行的基准测试得到的结果是15.5秒,而你在修改之后进行的基准测试得到的结果是4.5秒。如果你没有拍摄事前快照,不会知道你的修改让系统的性能有了很大的提高。说不定还会以为你的修改降低了查询的速度--你也许会因此撤消这次修改,结果返回到执行速度慢的查询。

  虽然这是一个假想的例子,但我希望大家能够从中注意到以下几点。首先,如果你是在对某个系统的数据检索性能执行基准测试,而这个系统的数据量会随着时间的推移而增长,你必须更频繁地运行你的基准测试工具才能准确地把握数据量的增长对系统性能的影响。在刚才的例子里,你应该把有关性能指标(比如数据负载量)在事前的测量值当作系统的“正常”指标。

  其次,必须保证你的测试对你测量的东西有效。如果你在对某个表的查询性能进行基准测试,你得到的测试结果只限于应用程序级别,不足以从一般意义上预测系统的性能。一定要把应用程序级别的基准与全局性的性能指标区分开来,这样才能保证不会得出错误的结论。

  另外一个与事前概念和事后概念有关的好的实践方法是,在活动(负载量相对稳定)的有间内尽可能多做几次基准测试,这是为了保证你的测试结果不会受到局部活动(比如临时出现的进程或高资源占用任务)的影响。我发现重复进行几十次同样的基准测试可以把各次测试结果的平均值作为终的性能指标值。有许多技巧可以得到这些统计结果。有条件的话,你甚至可以使用一个统计包或是你喜欢的适用于统计的电子表格应用程序 来得出基本的统计数字。

  注解:有些基准测试工具有自己的统计分析包,但MySQL Benchmark Suite没有。

  我认为有用的建议是每次只修改一个地方。一次修改多个地方并不是不可以,但这样你不能期望从基准测试结果里得出什么有意义的结论。经常会发生这样的事:你修改了6个地方,其中之一产生的负面影响掩盖了另外几个的正面效果,剩下的一两个对性能没有任何影响。只有每次修改一个地方,你才能准确地判断出它对系统性能的影响是负面的、正面的还是没有影响。

  还有,只要有可能,应该使用实际数据来进行基准测试。人工生成的测试数据怎么说也会有一些规律可循,那样得到的测试结果往往不能反映实际情况,某些特定的功能(比如边界值和范围检查等)可能永远也得不到测试。如果你的数据变化很频繁,你应该选择某个时刻为它们“拍摄”一张快照,然后使用这张快照来进行每一次测试。不过,这么做虽然能够保证使用真实的数据来测试性能,可是随着数据量的增长也许无法测试出系统性能的下降。

  后,在解读基准测试结果和管理预期目标时,一定要让你的目标有现实意义。如果你想改善系统在某种特定条件下的性能,在确定目标前首先要把已知的后果弄清楚。比如说,如果你想知道把网络接口的传输速度提高100倍对系统性能会产生哪些影响,必须先弄清楚你的服务器将不能按照比现在快100倍的速度发送和接收数据。在这类场合中,你必须综合考虑硬件的性价比和硬件可能带来的性能改善。换句话说,你的服务器的执行速度应当提高几个百分点,这样为你省了钱(或说增加了收入)。

  如果在做过仔细评估之后预计你的网络性能只要提高10%可以做到收支平衡甚至赢利,那把这个数字作为你的目标好了。如果基准测试结果表明你得到了这么大(或更好)的改善,去找老板谈谈加薪的事吧;如果基准测试结果表明你没有得到这么大的改善,去建议老板把新硬件退回去(也可以顺便谈谈加薪的事,因为你让他省钱了)。不管是哪种情况,你的报告都有充分的依据,即你的基准测试结果。

  2、对数据库系统进行基准测试

  基准测试在很多领域都非常重要。但基准测试与数据库服务器到底有什么关系呢?答案包括很多方面。

  对数据库服务器进行基准测试可以在许多不同的层次上进行。常见的是针对数据库模式的改动而进行的基准测试。专门针对某个表的基准测试比较少见(虽然你可以这么做)。人们更感兴趣的是在改变了数据库的结构之后,其性能会受到什么样的影响。

  人们的这种关心在刚开始使用一个新的应用程序或一个新的数据库时表现得尤为明显。此时,你可以设计好几种数据库模式并填充数据,然后编写一些基准测试程序来模仿所推荐的系统。嘿,这也是一种测试驱动的开发行为!通过创建多个数据库模式并进行基准测试,甚至可能会多次重复这些改动,你很快可以确定哪套模式适合你设计的应用。

  有时候,对数据库系统进行基准测试还有一些特殊的目的。比如说,你想知道数据库系统在不同的负载情况或不同的系统环境下会有怎样的性能表现。那么,除了进行事前和事后的基准测试去了解对环境所做的改变会产生多大的不同,还有什么方法更能证明你新安装的RAID设备将大幅改善系统的性能呢?是的,一切都是围绕成本进行考虑,基准测试工具可以帮助你管理好数据库系统的成本。