【笔记】高性能MySQL(第三版)——第2章:MySQL基准测试

  1. 基准测试(benchmark)是MySQL新手和专家都需要掌握的一项基本技能。简单地说,基准测试是针对系统设计的一种压力测试。通常的目标是为了掌握系统的行为。但也有其他原因,如重现某个系统状态,或者做新硬件的可靠性测试。

2.1 为什么需要基准测试

  1. 基准测试是唯一方便有效的、可以学习系统在给定的工作负载下会发生什么的方法。
  2. 基准测试可以观察系统在不同压力下的行为,评估系统的容量,掌握哪些是重要的变化,或者观察系统如何处理不同的数据。
  3. 基准测试可以在系统实际负载之外创造一些虚构场景进行测试。还可以用于其它目的,比如为应用创建单元测试套件。
  4. 基准测试的一个主要问题在于其不是真实压力的测试。
  5. 基准测试只能进行大概的测试,来确定系统大致的余量有多少。当然也可以做一些真实压力测试(和基准测试有区别),但在构造数据集和压力的时候要特别小心,而且这样就不再是基准测试了。基准测试要尽量简单直接,结果之间容易相互比较,成本低且易于执行。尽管有诸多限制,基准测试还是非常有用的(只要搞清楚测试的原理,并且了解如何分析结果所代表的意义)。

2.2 基准测试的策略

  1. 基准测试有两种主要的策略:一是针对整个系统的整体测试,另外是单独测试MySQL。这两种策略也被称为集成式(full-stack)以及单组件式(single-component)基准测试。

2.2.1 测试何种指标

  1. 在开始执行甚至是在设计基准测试之前,需要先明确测试的目标。测试目标决定了选择什么样的测试工具和技术,以获得精确而有意义的测试结果。

考虑以下指标,选择如何满足测试的需求

  • 吞吐量 
    吞吐量指的是单位时间内的事务处理数。这一直是经典的数据库应用测试指标。这类基准测试主要针对在线事务处理(OLTP)的吞吐量,非常适用于多用户的交互式应用。常用的测试单位是每秒事务数(TPS),有些也采用每分钟事务数(TPM)。

  • 响应时间或者延迟 
    这个指标用于测试任务所需的整体时间。根据具体的应用,测试的时间单位可能是微秒、毫秒、秒或分钟。根据不同的时间单位可以计算出平均响应时间、最小响应时间、最大响应时间和所占百分比。最大响应时间通常意义不大,因为测试时间越长,最大响应时间也可能越大。而且其结果通常不可重复,每次测试都可能得到不同的最大响应时间。因此,通常可以使用百分比响应时间(percentile response time)来替代最大响应时间。

  • 并发性 
    并发性是一个非常重要又经常被误解和误用的指标。例如,它经常被表示成多少用户在同一时间浏览一个Web站点,经常使用的指标是有多少个会话。然而,HTTP协议是无状态的,大多数用户只是简单地读取浏览器上显示的信息,这并不等同于Web服务器的并发性。而且,Web服务器的并发性也不等同于数据库的并发性,而仅仅只表示会话存储机制可以处理多少数据的能力。Web服务器的并发性更准确的度量指标,应该是在任意时间有多少同时发生的并发请求。 
    在应用的不同环节都可以测试响应的并发性。Web服务器的高并发,一般也会导致数据库的高并发,但服务器采用的语言和工具集对此都会有影响。注意不要将创建数据库连接和并发性搞混淆。一个设计良好的应用,同时可以打开成百上千个MySQL数据库服务器连接,但可能同时只有少数连接在执行查询。所以说,一个Web站点“同时有50000个用户”访问,却可能只有10~15个并发请求到MySQL数据库。 
    换句话说,并发性基准测试需要关注的是正在工作中的并发操作,或者是同时工作中的线程数或者连接数。当并发性增加时,需要测试吞吐量是否下降,响应时间是否变长,如果是这样,应用可能就无法处理峰值压力。 
    并发性的测量完全不同于响应时间和吞吐量。它不像是一个结果,而更像是设置基准测试的一种属性。并发性测试通常不是为了测试应用能达到的并发度,而是为了测试应用在不同并发下的性能。当然,数据库的并发性还是需要测量的。可以通过sysbench指定32、64或128个线程的测试,然后在测试期间记录MySQL数据库的Threads_running状态值。

  • 可扩展性 
    在系统的业务压力可能发生变化的情况下,测试可扩展性就非常必要了。简单地说,可扩展性指的是,给系统增加一倍的工作,在理想情况下就能获得两倍的结果(即吞吐量增加一倍)。或者说,给系统增加一倍的资源(比如两倍的CPU数),就可以获得两倍的吞吐量。当然,同时性能(响应时间)也必须在可以接受的范围内。大多数系统是无法做到如此理想的线性扩展的。随着压力的变化,吞吐量和性能都可能越来越差。 
    可扩展性指标对于容量规范非常有用,它可以提供其他测试无法提供的信息,来帮助发现应用的瓶颈。 
    归根结底,应该测试那些对用户来说最重要的指标。因此应该尽可能地去收集一些需求,比如,什么样的响应时间是可以接受的,期待多少的并发性,等等。然后基于这些需求来设计基准测试,避免目光短浅地只关注部分指标,而忽略其他指标。

2.3 基准测试方法

以下常见错误可能导致测试结果无用或者不精确 
1. 使用真实数据的子集而不是全集。 
2. 使用错误的数据分布。 
3. 使用不真实的分布参数。 
4. 在多用户场景中,只做单用户的测试。 
5. 在单服务器上测试分布式应用。 
6. 与真实用户行为不匹配。 
7. 反复执行同一个查询。 
8. 没有检查错误。基准测试完成后,一定要检查一下错误日志,这应该是基本的要求。 
9. 忽略了系统预热(warm up)的过程。 
10. 使用默认的服务器配置。 
11. 测试时间太短。 
如果其他条件相同,就应努力使测试过程尽可能地接近真实应用的情况。

2.3.1 设计和规划基准测试

  1. 规划基准测试的第一步是提出问题并明确目标。然后决定是采用标准的基准测试,还是设计专用的测试。
  2. 如果采用标准的基准测试,应该确认选择了合适的测试方案。
  3. 设计专用的基准测试是很复杂的,往往需要一个迭代的过程。首先需要获得生产数据集的快照,并且该快照很容易还原,以便进行后续的测试。然后,针对数据运行查询。可以建立一个单元测试集作为初步的测试,并运行多遍。但是这和真实的数据库环境还是有差别的。更好的办法是选择一个有代表性的时间段,记录生产系统上的所有查询。如果时间段选得比较小,则可以选择多个时间段。这样有助于覆盖整个系统的活动状态。
  4. 可以在不同级别记录查询。如果是集成式(full-stack)基准测试,可以记录Web服务器上的HTTP请求,也可以打开MySQL的查询日志(Query Log)。倘若要重演这些查询,就要确保创建多线程来并行执行,而不是单个线程线性地执行。对日志中的每个连接都应该创建独立的线程,而不是将所有的查询随机地分配到一些线程中。查询日志中记录了每个查询是在哪个连接中执行的。
  5. 即使不需要创建专用的基准测试,详细地写下测试规划也是必需的。测试可能要多次反复运行,因此需要精确地重现测试过程,而且也要考虑到下次测试不是同一个人的情况。
  6. 应该建立将参数和结果文档化的规范,每一轮测试都必须进行详细记录。需要记住的是,经常要写一些脚本来分析测试结果,因此如果能够不用打开文档等额外操作,当然是更好的。

2.3.2 基准测试应该运行多长时间

  1. 基准测试应该运行足够长的时间,这一点很重要。有时候无法确认测试需要多长的时间才足够,如果这样可以让测试一直运行,持续观察直到确认系统已经稳定。一个简单的测试规则,就是等系统看起来稳定的时间至少等于系统预热的时间。
  2. 一个常见的错误的测试方式是,只执行一系列短期的测试,例如每次60秒的测试,就在此基础上去总结系统的性能。如果不能自己进行长时间的测试,与其用短时间的测试结果来评断,不如参考别人的测试结果。

扩展基准测试的I/O性能图 
扩展基准测试的I/O性能图

2.3.3 获取系统性能和状态

  1. 在执行基准测试时,需要尽可能多地手机被测试系统的信息。使用shell脚本,尽可能多的收集数据,多余一些数据总比缺乏重要的数据要好。需要记录的数据包括系统状态和性能指标。
  2. 先收集所有的原始数据,然后再基于此做分析和过滤是一个好习惯。如果在收集的时候就对数据做预处理,而后续分析发现一些异常的地方需要用到更多的原始数据,就“抓瞎”了。

2.3.4 获得准确的测试结果

  1. 获得准确测试结果的最好办法,是回答一些关于基准测试的基本问题:是否选择了正确的基准测试?是否为问题收集了相关的数据?是否采用了错误的测试标准?
  2. 接着,确认测试结果是否可重复。每次重新测试之前要确保系统状态的一致,甚至有必要重启系统并预热,还需要确保预热的时间足够长,并可重复。如果预热采用的随机查询,那么测试结果可能就是不可重复的。
  3. 每次测试要保证测试数据相同,一个确保物理磁盘数据的分布尽可能一直的办法是,每次都进行快速格式化并进行磁盘分区复制。
  4. 每次测试中,修改的参数应该尽量少,有时参数之间的依赖性会给测试带来复杂性。一般情况下,都是通过迭代逐步地修改基准测试的参数,而避免每次运行都做大量的修改。
  5. 基于MySQL默认配置的测试没有什么意义。
  6. 如果测试中出现异常结果,不要轻易当作坏数据点而丢弃。分析这些异常结果,偶尔也会获得意想不到的收获。

2.3.5 运行基准测试并分析结果

  1. 通常来说,自动化基准测试可以获得更精确的测试结果。要尽可能地使所有测试过程都自动化,包括装载数据、系统预热、执行测试、记录结果等。
  2. 基准测试通常要运行多次,以提高测试结果的准确度。
  3. 获得测试结果后,还需要对结果进行分析,最终目的是回答在设计测试时的问题。
  4. 如何从数据中抽象出有意义的结果,依赖于如何收集数据。通常使用脚本来分析数据,不仅减轻分析的工作量,也易于文档化。

2.3.6 绘图的重要性

  1. 在执行基准测试的时候尽可能地收集更多的细节数据,然后将数据绘制成图形,这样可以帮助快速地发现问题。

2.4 基准测试工具

2.4.1 集成式测试工具

  1. ab:ab是一个Apache HTTP服务器基准测试工具。它可以测试HTTP服务器每秒最多可以处理多少请求。
  2. http_load:这个工具概念上和ab类似,也被设计为对Web服务器进行测试,但比ab要更加灵活。可以通过一个输入文件提供多个URL,http_load在这些URL中随机选择进行测试。
  3. JMeter:JMeter是一个Java应用程序,可以加载其他应用并测试其性能。JMeter比ab和http_load都要复杂得多。

2.4.2 单组件式测试工具

  1. mysqlslap:mysqlslap可以模拟服务器的负载,并输出计时信息。测试时可以执行并发连接数,并指定SQL语句,如果没有指定SQL语句,mysqlslap会自动生成查询schema的SELECT语句。
  2. MySQL Benchmark Suite(sql-bench):可以用于在不同数据库服务器上进行比较测试。它是单线程的,主要用于测试服务器执行查询的速度,结果会显示哪种类型的操作在服务器上执行得更快。
  3. Super Smack:Super Smack是一款用于MySQL和PostgreSQL的基准测试工具,可以提供压力测试和负载生成。这是一个复杂而强大的工具,可以模拟多用户访问,可以加载测试数据到数据库,并支持使用随机数据填充测试表。
  4. Database Test Suite:这是一款类似某些工业标准测试的测试工具集,其中的dbt2就是一款免费的TPC-C OLTP测试工具(未认证)。
  5. Percona’s TPCC-MySQL Tool:一个类似TPC-C的基准测试工具集,其中有部分是专门为MySQL测试开发的。
  6. sysbench:sysbench是一款多线程系统压测工具,它可以根据影响数据库服务器性能的各种因素来评估系统的性能。sysbench是一种全能测试工具,支持MySQL、操作系统和硬件的硬件测试。 
    MySQL的BENCHMARK()函数

2.5 基准测试案例(P52~P65)

2.6 总结

  1. 每个MySQL的使用者都应该了解一些基准测试的知识。
  2. 基准测试不仅仅是用来解决业务问题的一种时间行动,也是一种很好的学习方法。
  3. 如果你还没有做过基准测试,那么建议至少要熟悉sysbench。可以先学习如何使用OLTP和FILEIO测试。OLTP基准测试可以很方便地比较不同系统的性能。另一方面,文件系统和磁盘基准测试,则可以在系统出现问题时有效地诊断和隔离异常的组件。
  4. 如果经常执行基准测试,那么指定一些原则是很有必要的。选择一些合适的测试工具并深入地学习。可以建立一个脚本库,用于配置基准测试,收集输出结果、系统性能和状态信息,以及分析结果。

你可能感兴趣的:(MySQL)