Apache的ab基准测试工具的结果应该如何解释?

44

好的,我已经到处搜索过了,但似乎找不到关于如何解释Apache的ab服务器基准测试工具结果的详细资源。我已经运行了几个测试,使用我认为完全不同的参数,但是看到非常相似的结果(我很难想象这意味着我的站点完美地扩展)。如果有人能够指向一个详细资源,让我能够理解测试结果,或者如果有人愿意在这里创建一个,我认为那对我和其他人都会非常有用。

5个回答

32

很让人沮丧,对吧?我正在尝试做同样的事情,看看我的新配置和配置完成的专用服务器与其他服务器相比如何。

我最终要做的是将我的当前生产服务器(双核4GB RAM)与新服务器(四核8GB RAM)进行比较。

我需要在进行并排比较时“友好相处”,因为生产服务器是实时运行的,我不想破坏我的用户的正常使用。

使用以下命令在一个只调用phpinfo()的php页面上将当前和新的服务器进行比较:ab -kc 20 -t 60

在我的当前生产服务器上,我看到类似下面的东西,它无法在给定的时间内完成任务:

Time taken for tests:   60.1234 seconds
Complete requests:  24538
Failed requests:    58
(Connect: 0, Length:    58, Exceptions: 0)
Requests per second:    408.96 [#/sec] (mean)
Time per request:   48.905 [ms] (mean)
Time per request:   2.445 [ms] (mean, across all concurrent requests)

与旧服务器相比,新服务器完成所有测试所需的时间减少了一半:

Time taken for tests:   29.838791 seconds
Complete requests:  50000
Failed requests:    11
(Connect: 0, Length:    11, Exceptions: 0)
Requests per second:    1675.67 [#/sec] (mean)
Time per request:   11.936 [ms] (mean)
Time per request:   0.597 [ms] (mean, across all concurrent requests)

现在,这并不是一个“公平”的测试,因为当前服务器除了基准测试外还处理着20个网站。此外,它只是在测试Apache和PHP。

如果将同样的测试运行在我更复杂的主页上,即在当前服务器上感觉比较慢的主页上,我会看到以下结果: 当前服务器:

Time taken for tests:   60.14170 seconds
Complete requests:  510
Requests per second:    8.50 [#/sec] (mean)
Time per request:   2353.497 [ms] (mean)
Time per request:   117.675 [ms] (mean, across all concurrent requests)

新服务器:

Time taken for tests:   60.18651 seconds
Complete requests:  1974
Requests per second:    32.89 [#/sec] (mean)
Time per request:   608.092 [ms] (mean)
Time per request:   30.405 [ms] (mean, across all concurrent requests)

这个测试正在加载一个由Joomla CMS动态生成的页面,它更像是一个“真实世界”的测试。同样,由于新服务器没有处理当前网站流量,因此无法进行苹果对苹果的比较。我不想进行更难的测试,否则会冒险影响我的站点终端用户的体验。

将站点迁移到新服务器后,我计划再次进行上述测试,以便了解我的常规站点流量对基准测试的影响。相同的机器生产与空闲基准测试结果。

现在,我还在考虑如何压力测试新服务器并确保它反应良好。 使用命令 ab -n 50000 -c 200,我观察 top 命令,看看CPU和内存的使用情况,并在浏览器中对该页面进行 *f5* 刷新,以查看是否有任何错误,并获取服务器响应所需的时间感觉。

我的第一次测试结果如下:

Concurrency Level:  200
Time taken for tests:   692.160011 seconds
Complete requests:  50000
Failed requests:    30102
(Connect: 0, Length:    30102, Exceptions: 0)
Write errors:   0
Non-2xx responses:  30102
Total transferred:  456568770 bytes
HTML transferred:   442928962 bytes
Requests per second:    72.24 [#/sec] (mean)
Time per request:   2768.640 [ms] (mean)
Time per request:   13.843 [ms] (mean, across all concurrent requests)
Transfer rate:  644.17 [Kbytes/sec] received
注意高的失败请求率。我的Apache设置为最多250个同时请求,但是MySQL只有175个。MySQL是故障点。它无法处理来自Apache的所有请求。我的网页在许多页面刷新时都显示了一个MySQL连接错误页面。
因此,我提高了MySQL的最大同时请求数为300(我已经这样做了,但忘记重新启动MySQL,所以这次结果很好 - 我确定了需要更改,并意外地进行了实证测试验证了更改的必要性)。
下一步运行给了我以下结果:
Concurrency Level:      200
Time taken for tests:   1399.999463 seconds
Complete requests:      50000
Failed requests:        5054
   (Connect: 0, Length: 5054, Exceptions: 0)
Write errors:           0
Non-2xx responses:      5054
Total transferred:      1016767290 bytes
HTML transferred:       995713274 bytes
Requests per second:    35.71 [#/sec] (mean)
Time per request:       5599.998 [ms] (mean)
Time per request:       28.000 [ms] (mean, across all concurrent requests)
Transfer rate:          709.24 [Kbytes/sec] received

这次花费的时间是之前的两倍多,但失败的请求率要低得多。基本上,服务器现在已经配置为能够处理至少200个页面同时访问我网站首页的请求,但每个页面的响应时间为5秒。虽然不是很好,但比之前我遇到的MySQL错误要好得多。

在此期间,我的服务器CPU使用率一直保持在100%,'load average'一直上升到180左右。MySQL使用了大约8-9%的CPU,并且并没有使用我分配给它的很多内存,因为我只是不断地访问同一个页面,所以它只涉及到单个数据库。它只使用了4GB+配置中的400MB,top显示缓存和已缓存的内存使用量约占总可用RAM的50%。因此,虽然我在进行这个测试时将机器的负载提高了,但它并没有接近过载点。在实际的数据库使用中,MySQL应该会占用我已分配给它的更多内存,因此在那时,服务器应该会接近满负载状态。

接下来,我的下一个测试是测试Apache在“满负载”250个连接的情况下 ab -n 50000 -c 250

Concurrency Level:      250
Time taken for tests:   1442.515514 seconds
Complete requests:      50000
Failed requests:        3509
   (Connect: 0, Length: 3509, Exceptions: 0)
Write errors:           0
Non-2xx responses:      3509
Total transferred:      1051321215 bytes
HTML transferred:       1029809879 bytes
Requests per second:    34.66 [#/sec] (mean)
Time per request:       7212.577 [ms] (mean)
Time per request:       28.850 [ms] (mean, across all concurrent requests)
Transfer rate:          711.73 [Kbytes/sec] received

这显示了与适当的MySQL连接限制进行的200个连接测试相似的结果。我认为这对我很好。我不喜欢返回页面需要7秒钟,但我认为我可以通过在Joomla中启用缓存来改善它,可以使用已安装但尚未被Joomla利用的APC或Memcache。

为了挑战自己的极限,我尝试了300个并发连接。ab -n 50000 -c 300 浏览器显示长时间等待才能快速加载页面。除此之外,结果没有太大变化。

Concurrency Level:      300
Time taken for tests:   1478.35890 seconds
Complete requests:      50000
Failed requests:        2266
   (Connect: 0, Length: 2266, Exceptions: 0)
Write errors:           0
Non-2xx responses:      2266
Total transferred:      1079120910 bytes
HTML transferred:       1057241646 bytes
Requests per second:    33.83 [#/sec] (mean)
Time per request:       8868.215 [ms] (mean)
Time per request:       29.561 [ms] (mean, across all concurrent requests)
Transfer rate:          712.99 [Kbytes/sec] received

我不知道我对这些结果的解释是否“正确”,或者是否遗漏了一些有价值的东西,但是在我找不到指导的情况下,这就是我得出的结论。

我只是利用这些结果来确保我获得了良好的响应率-完美响应率的缺失让我感到担忧,但我不知道如何以一种可以检查它们的方式查看或重现失败。

每个请求的慢速时间也让我感到担忧,但我认为我可以在应用程序层面解决其中大部分问题。

我有信心,在服务器减速的情况下,它可以处理重负载情况。

在进行基准测试后,查看其他性能调整工具(如MonYog)也向我展示了我的当前配置已足够好。

我希望有一个地方,人们可以发布带有硬件描述和软件配置的测试结果,以便我知道自己是否“有竞争力”,或者是否还有很多工作要做才能最大程度地利用我的设备。这就是为什么我发布我的结果的原因。


3
我认为你可能误解了失败的请求行,参见我的回答。 - amarillion
感谢您的澄清,amarillion。 - creuzerm
你是在本地机器上测试AB吗?也就是说,你正在同一台机器上进行Web服务器的AB测试。只有当我在自己的计算机上进行Apache基准测试时,我才能获得每秒超过1k的请求。 - David
我倾向于在本地使用AB进行调优。确实,这不是一个真正的测试,但通常情况下,人们很难对互联网连接进行“调优”(虽然有些事情可以做,但超出了本问题的范围)。如果网络是限制因素,并且您可以进行超越网络提供的调整,则基本上已经将系统优化到所需的最佳状态。 - creuzerm

9
请注意,“失败请求”行是通过将连续请求的长度相互比较来确定失败请求的。对于动态网站,这并不意味着请求完全失败!因此,请勿担心“失败请求”行。
另请参阅:http://www.celebrazio.net/tech/unix/apache_bench.html

7

3
Time per request:       7.303 [ms] (mean)
Time per request:       0.730 [ms] (mean, across all concurrent requests)

第一个和并发用户相关的指标是每个并发用户请求的平均时间。如果你正在进行1000个请求和200个并发用户的测试,第一个指标将是每200个请求的平均时间。 第二个指标与整个1000个请求的平均请求时间有关。


2

顺带一提,AB是单线程的(对于像2001年的Pentium 4这样的旧单核CPU来说,这是可以接受的)。

要测试托管Web服务器的多核CPU(使用多个进程的Nginx/Lighty,使用多个线程的Apache),您应该使用与AB兼容的Weighttp。

“Weighttp -t 6”将运行6个客户端线程(相比之下,“AB -t 6”将运行6秒钟的测试)。

通过使用几个客户端线程(与Web服务器工作器数量相同的数量-应匹配服务器框的CPU核心数量),您将获得更相关的结果。


6
AB允许您指定并发级别。我认为这意味着它是多线程的,就像您在此处使用的那样。例如,ab -n 1000 -c 10 http://myserver/将从10个并发请求者运行100个请求,总共产生1000个命中。 - Rick-777
@Rick-777 看起来 ab 在发送第二批请求之前会等待第一批请求完成。所以它不是多线程的,不能同时发出请求?另外,你所说的“requester”是什么意思? - revo
我还没有研究过ab的源代码,所以我只报告它的选项。在请求方面,我仅仅指的是线程在非常一般的意义上(并非所有线程都相同)。 - Rick-777

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接