Category Archives: Performance

比较一个系统中两个模块的性能差别:不要同时压这两个模块

要比较一个系统中两个模块的性能差别(比如同一个库中的两个类似的表),有两种压测模式:

1. 一个test plan含两个senario, 执行一次,同时出两个模块的结果。

2. 搞两个test plan, 各带一个senario; 各执行一次,各出一个结果。

第一种模式很有吸引力,因为它可省下很多重复的配置工作;只执行一次,比较省时;像jmeter之类的还会直接给出直方图,以示比较。

然而,我的亲身经历表明,第1种模式由于公共资源占用问题会导致“大锅饭”效应: 同时压测两个模块,慢模块会占用过多公共资源(cpu, 内存,连接池等),导致快模块无法获得足够的资源因而也变慢。 这种模式下比较出来的结果并不准确。

所以,还是应该把两个测试互相隔离起来,搞两个 test plan,各带一个senario吧。

p.s. 如果你用jmeter,可以只写一个test plan,带两个sampler, 然后enable一个,disable另一个,这样每次执行时仍是隔离的。

concurrency并非性能测试的结果,而是测试条件

一个系统能承载多大的concurrency (同一瞬间连接中的tcp连接数,或者同时访问系统的用户数) ?对于http系统来说,这个问题意义不大。

你应该要逐渐增大concurrency, 直到你在合理的rt范围内找到qps的极限。qps和rt才是你关心的东西,当这个极限到来时,concurrency是多少,根本是无所谓的,因为只有qps和rt才能真正代表系统为用户提供服务的能力。

正如  ‘High Performance MySQL’ 所说: concurrency is not a
result, but rather a
property of how you set up the benchmark.

性能测试:rt要看percentile response time

一次性能测试会访问系统很多次,每次的rt都不一样。应该看哪个值?

看max response time并没有意义,因为它可能只是个尖峰(spike),是奇异点。

看average response time会好很多,但如果尖峰太夸张,可能会严重影响平均值。

最合适的值是percentile response time, 比如"95%的请求的rt在5ms以内" 这种。

准备性能测试数据的常见误区

1. 数据库里的数据量太小。

2. 数据或参数均匀分布,忽略了热区(hot spot)的存在。

3. 在循环中使用同样的参数,触发了缓存而不自知。

最好的办法是:

1. 把生产环境现有的数据复制到测试环境中

2. 在生产环境中记录日志,记下所有数据的产生和访问参数,然后在测试环境中重放它们。

一个慢sql可能会成为害群之马

一条sql执行慢,不仅相关业务受影响,其他业务也可能影响。

数据库连接是有限的,一条慢sql执行慢,就意味着它会在较长时间内占用数据库连接; 如果并发执行慢sql, 很容易占用大量的数据库连接,其他的快sql获取不到连接,执行不了,快sql对应的sql也就受影响了,最终导致整个系统的可用性都出问题。

除了数据库连接,慢SQL(或者大规模数据处理如批量数据清理)还会占用数据库的其他资源。
比如过久占用锁、占用过多CPU/内存等,这些都有可能导致其他sql不能立即执行。

解决方案有:

1. 甄别、改进慢sql. 对于高并发的系统,sql rt应该维持在5ms以内

2. 数据库连接池互相隔离,比如让主干业务独享数据库连接池,其他业务若出现慢sql也不影响主业务。

3. 设置sql执行超时,一段时间内没有执行完强制释放数据库连接。