当并发请求运行rails 3.0.0 + passenger + apache + Ruby 1.9.2时,可怕的性能基准测试

时间:2012-03-16 01:20:10

标签: ruby-on-rails-3 performance passenger

我在ec2实例上使用Rails 3.0.0 + passenger + apache2在Ruby 1.9.2p290上运行。

相关的乘客设置(我对它们进行了大量的混乱而没有效果):

PassengerMaxPoolSize 30 PassengerPoolIdleTime 0 PassengerMinInstances 10

另外,我已经确认我不是内存或CPU绑定...

我已经运行了一些基准测试,结果很困惑。我调用了一个相当复杂的查询,将5个不同的.where()子句链接在一起。 (换句话说,它使用AREL很多。)

当我在没有CONCURRENCY的情况下运行具有1000个呼叫的Apache Bench时(例如,ab -n 1000 -c 1),我得到以下内容:

 Concurrency Level:      1
 Time taken for tests:   222.799 seconds
 Complete requests:      1000
 Failed requests:        0
 Write errors:           0
 Total transferred:      489000 bytes
 HTML transferred:       16000 bytes
 Requests per second:    4.49 [#/sec] (mean)
 Time per request:       222.799 [ms] (mean)
 Time per request:       222.799 [ms] (mean, across all concurrent requests)
 Transfer rate:          2.14 [Kbytes/sec] received

现在,当我将并发设置为10(例如,ab -n 1000 -c 10)运行时,我得到以下内容:

 Concurrency Level:      10
 Time taken for tests:   213.957 seconds
 Complete requests:      1000
 Failed requests:        0
 Write errors:           0
 Total transferred:      489001 bytes
 HTML transferred:       16000 bytes
 Requests per second:    4.67 [#/sec] (mean)
 Time per request:       2139.567 [ms] (mean)
 Time per request:       213.957 [ms] (mean, across all concurrent requests)
 Transfer rate:          2.23 [Kbytes/sec] received

并发请求绝对没有任何好处!每秒请求仍为~4.5。就好像服务器正在连续处理请求一样。

现在真的很奇怪。如果我从ActiveRecord查询接口查看输出的SQL查询,而只是使用find_by_sql,我得到的没有并发:

 Concurrency Level:      1
 Time taken for tests:   49.547 seconds
 Complete requests:      1000
 Failed requests:        0
 Write errors:           0
 Total transferred:      489000 bytes
 HTML transferred:       16000 bytes
 Requests per second:    20.18 [#/sec] (mean)
 Time per request:       49.547 [ms] (mean)
 Time per request:       49.547 [ms] (mean, across all concurrent requests)
 Transfer rate:          9.64 [Kbytes/sec] received

这里没有惊喜。 find_by_sql比使用ActiveRecord和AREL构建查询更快。但是,如果我将并发设置为10运行前一个,我得到:

 Concurrency Level:      10
 Time taken for tests:   17.859 seconds
 Complete requests:      1000
 Failed requests:        0
 Write errors:           0
 Total transferred:      489000 bytes
 HTML transferred:       16000 bytes
 Requests per second:    55.99 [#/sec] (mean)
 Time per request:       178.587 [ms] (mean)
 Time per request:       17.859 [ms] (mean, across all concurrent requests)
 Transfer rate:          26.74 [Kbytes/sec] received

请注意每秒请求数如何跳跃3倍。所以我的问题是:

如何/为什么使用ActiveRecord(和AREL)构建查询会导致并发请求响应如此糟糕? ActiveRecord真的可以用CPU吗?

1 个答案:

答案 0 :(得分:1)

如果没有看到您的实际代码,我猜想AREL会为您提供的查询生成不太理想的SQL,从而导致数据库陷入困境。

将AREL生成的SQL语句与您自己的SQL进行比较。还可以尝试直接在数据库中运行AREL查询,以查看其性能与SQL的对比情况。尝试对两个查询进行EXPLAIN。请记住,一些数据库在优化SQL时会变得更糟,因为它会变得更复杂。