二、MySQL基准测试
基准测试(benchmark):是针对系统设计的一种压力测试。通常的目标是为了掌握系统的行为。但也有其他原因,如重现某个系统状态,或者是做新硬件的可靠性测试。
2.1 为什么需要基准测试
- 验证基于系统的一些假设,确认这些假设是否符合实际情况
- 重现系统中的某些异常行为,以解决这些异常
- 测试系统当前的运行情况。
- 模拟比当前系统更高的负载
- 规划未来的业务增长
- 测试应用适应可变环境的能力
- 测试不同的硬件、软件和操作系统配置
- 证明新采购的设备是否配置正确(永远不要相信主机提供商或者硬件供应商的所谓系统已经安装好)
基准测试的一个主要问题在于其不是真实压力的测试,基准测试施加给系统的压力相对真实压力来说,通常比较简单。
基准测试的压力和真实压力在哪些方面不同?有很多因素会影响基准测试,比如数据量数据和查询的分布。但最重要的一点还是基准测试通常要求尽可能快地执行完成,所以经常给系统造成过大的压力。
大部分压力测试工具不支持对压力进行复杂的控制。务必要记住,测试工具的自身的局限性也会影响到结果的有效性。
使用基准测试进行容量规划也要掌握技巧,不能只根据测试结果做简单的推断
结论:我们只能进行大概的测试,来确定系统大致的余量有多少。当然也可以做一些真实压力测试,但在工作数据集和压力的时候要特别小心。基准测试要尽量简单直接,结果之间容易相互比较,成本低且易于执行。尽管有诸多限制,基准测试还是非常有用的(只要搞清楚测试的原理,并且了解如何分析结果所代表的意义)
2.2 基准测试的策略
基准测试有两种主要的策略:一是针对整个系统的整体测试,另外是单独测试MySQL。这两种策略也被称为集成式(full-stack)以及单组件式(single-component)基准测试。
- 测试整个应用系统,包括web服务器、应用代码、网络和数据库是非常有用的,因为用户关注的并不仅仅是MySQL本身的性能,而是应用整体的性能。
- MySQL并非总是应用的瓶颈,通过整体的测试可以揭示这一点
- 只有对应用做整体测试,才能发现各部分之间的缓存带来的影响
- 整体应用的集成式测试更能揭示应用的真实表现,而单独组件的测试很难做到这一点
另一方面,应用的整体基准测试很难建立,甚至很难正确设置。如果基准测试的设计有问题,那么结果就无法反映真实的情况,从而基于此做的决策也可能是错误的。
不过,有时候不需要了解整个应用的情况,而只需关注MySQL的性能,至少在项目初期可以这样做。基于以下情况,可以选择只测试MySQL:
- 需要比较不同的 schema 或查询的性能
- 针对应用中某个具体问题的测试
- 为了避免漫长的基准测试,可以通过一个短期的基准测试,做快速的 "周期循环" 来检测出某些调整后的效果
另外,如果能够在真实的数据集上执行重复的查询,那么针对MySQL的基准测试也是有用的,但是数据本身和数据集的大小都应该是真实的。如果可能,可以采用生产环境的数据快照。
1)测试何种指标
在开始执行甚至是在设计基准测试之前,需要先明确测试的目标。测试目标决定了选择什么样的测试工具和技术,以获得精确而有意义的测试结果。可以将测试目标细化为一系列的问题。
有时候需要用不同的方法测试不同的指标。比如,针对延迟(latency)和吞吐量(throughput)就需要不同的测试方法。
吞吐量
吞吐量指的是单位时间内的事务处理数。常用的测试单位是每秒事务数(TPS)
响应时间
用于测试任务所需的整体时间。根据不同的时间单位可以计算出平均响应时间、最小响应时间、最大响应时间和所占百分比。
使用图表有助于理解测试结果。可以将测试结果绘制成折线图或者散点图。
并发性
并发性是一个非常重要又经常被误解和误用的指标。例如,它经常被表示成多少用户在同一时间浏览一个web站点,经常使用的指标是有多少个会话。然而,HTTP协议是无状态的,大多数用户只是简单地读取浏览器上显示的信息,这并不等同于web服务器的并发性。而且,web服务器的并发性也不等同于数据库的并发性,而仅仅只表示会话存储机制可以处理多少数据的能力。web服务器的并发性更准确的度量指标,应该是在任意时间有多少同时发生的并发请求。
在应用的不同环节都可以测量相应的并发性。web服务器的高并发,一般也会导致数据库的高并发,但服务器采用的预言和工具集对此都会有影响。注意不要将创建数据库连接和并发性搞混淆。一个设计良好的应用,同事可以打开成百上千个MySQL数据库服务器连接,但可能同时只有少数连接在执行查询。所以说,一个吻站点 “同时有 50 000个用户" 访问,却可能只有 10~15个并发请求到数据库。
换句话说,并发性基准测试需要关注的是正在工作中的并发操作,或者是同时工作中的线程数或者连接数。当并发性增加时,需要测量吞吐量是否下降,响应时间是否变长,如果是这样,应用可能就无法处理峰值压力。
并发性的测量完全不同于响应时间和吞吐量。它不像是一个结果,而更像是设置基准测试的一种属性。
可扩展性
可扩展性指的是,给系统增加一倍的工作,在理想情况下就能获得两倍的结果(即吞吐量增加一倍)。或者说,给系统增加一倍的资源(比如两倍的CPU数),就可以获得两倍的吞吐量。当然,同时性能也必须在可以接受的范围内。大多数系统是无法做到如此理想的线性扩展的。
归根到底,应该测试那些对用户来说最重要的指标。因此应该尽可能地去收集一些需求,比如,什么样的响应时间是可以接受的,期待多少的并发性,等等。然后基于这些需求来设计基准测试,避免目光短浅地只关注部分指标,而忽略其他指标。
2.3 基准测试方法
在讨论如何设计好的基准测试之前,先来看一下如何避免一些常见的错误,这些错误可能导致测试结果无用或者不精确。
- 使用真实数据的子集而不是全集
- 使用错误的数据分布
- 使用不真实的分布参数,例如假定所有用户的个人信息都会被平均地读取
- 在多用户场景中,只做单用户的测试
- 在单服务上测试分布式应用
- 与真实用户行为不匹配。例如web页面中的 ”思考时间" 。真实用户在请求到一个页面后会阅读一段时间,而不是不停顿地一个接一个点击相关链接
- 反复执行同一个查询
- 没有检查错误。比如一个本应该很慢的查询突然变快了,就应检查是否有错误产生。
- 忽略了系统预热(warm up)的过程
- 使用默认的服务器配置
- 测试时间太短
1)设计和规划基准测试
规划基准测试的第一步是提出问题并明确目标。然后觉得是采用标准的基准测试,还是设计专用的测试。
设计专用的基准测试是很复杂的,往往需要一个迭代的过程。首先需要获得生产数据集的快照,并且该快照很容易还原,以便进行后续的测试。
然后,针对数据运行查询,可以建立一个单元测试集作为初步的测试,并运行多变。但是这和真实的数据库环境还是有差别的。更好的办法是选择一个有代表性的时间段,比如高峰期的一个小时,或者一整天,记录生产系统上的所有查询。如果时间段选得比较小,啧可以选择多个时间段。这样有助于覆盖整个系统的活动状态。例如每周报表的查询、或者非峰值时间运行的批处理作业。
即使不需要创建专用的基准测试,详细地写下测试规划也是必需的。测试可能要多次反复运行,因此需要精确地重现测试过程。而且也应该考虑到未来,执行下一轮测试时可能已经不是同一个人了。即使还是同一个人,也有可能不会确切地记得初次运行时的情况。测试规划应该记录测试数据、系统配置的步骤、如何测量和分析结果,以及预热的方案等。
应该建立将参数和结果文档化的规范,每一轮测试都必须进行详细记录。文档规范可以很简单,比如采用excel或记事本,也可以是复杂的自定义的数据库。需要记住的是,经常要写一些脚本来分析测试结果。
2)基准测试应该运行多长时间
基准测试应该运行足够长的时间,这一点很重要。如果没有时间去完成准确完成的基准测试,那么已经花费的所有时间都是一种浪费。
3)获取系统性能和状态
在执行基准测试时,需要尽可能多地收集被测试系统的信息。最好为基准测试建立一个目录,并且每执行一轮测试都创建单独的子目录,将测试结果、配置文件、测试目标、脚本和其他相关说明都保存在其中。即使有些结果不是目前需要的,也应该先保存下来。多余一些数据总比缺乏重要的数据要好,而且多余的数据以后也许会用得着。需要记录的数据包括系统状态和性能指标,诸如CPU使用率、磁盘I/O、网络流量统计、SHOW GROBAL STATUS 计数器等。
4)获得准确的测试结果
获得准确测试结果的最好办法,是回答一些关于基准测试的基本问题:是否选择了正确的基准测试?是否为问题收集了相关的数据?是否采用了错误的测试标准?例如,是否对一个I/O密集型的应用,采用了CPU密集型的测试标准来评估性能。
接着,确认测试结果是否可重复。每次重新测试之前要确保系统的状态是一致的。如果是非常重要的测试,甚至有必要每次测试都重启系统。一般情况下,需要测试的是经过预热的系统,还需要确保预热的时间足够长、是否可重复。如果预热采用的是随机查询,那么测试结果可能就是不可重复的。
如果测试的过程会修改数据或者 schema,那么每次测试前,需要利用快照还原数据。
数据的碎片和在磁盘上的分布,都可能导致测试是不可重叠的。一个确保物理磁盘数据的分布尽可能的一致的办法是,每次都进行快速格式化并进行磁盘分区复制。
要注意很多因素,包括外部的压力、性能分析和监控系统、详细的日志记录、周期性作业,以及其他一些因素,都会影响到测试结果。一个典型的案例,就是测试过程中突然有cron定时作业启动,或者正处于一个巡查读取周期(patrol read cycle),抑或RAID卡启动了定时的一致性检查等。
每次测试中,修改的参数应该尽量少。如果必须要一次修改多个参数,那么可能会丢失一些信息。
5)运行基准测试并分析结果
自动化基准测试:防止测试人员偶尔遗漏某些步骤,或者误操作。另外也有助于归档整个整个测试过程。
要尽可能地使所有测试过程都自动化,包括装载数据系统预热、执行测试、记录结果等。
获得测试结果后,还需要对结果进行分析,也就是说,要把 "数字" 变成 "知识" 。最终的目的是回答在设计测试时的问题。
如何从数据中抽象出有意义的结果,依赖于如何收集数据。通常需要写一些脚本来分析数据,这不仅能减轻分析的工作量,而且和自动化基准测试一样可以重复运行,并易于文档化。
6)绘图的重要性
最简单有效的图形,就是将性能指标按照时间顺序绘制。通过图形可以立刻发现一些问题。
2.4 基准测试工具(略)
sysbench
JMeter