[Ruby] Scalability tests

Eric Hodel drbrain at segment7.net
Mon Mar 19 21:24:20 PST 2007


On Mar 19, 2007, at 14:31, ben wiseley wrote:
> We'd basically like to run load tests that mimic X users doing various
> scenarios and then try to improve the numbers through tweaking code  
> based on
> some combination of httperf and RailsBench output.  Is this the  
> general
> idea?

It depends on what you're looking to optimize.  Trying to optimize  
Rails from the HTTP level may not give you the information you need  
to make proper decisions.  (Yes, this is slow, but why?)  I find the  
log files much, much more informative, for example I found a 25MB  
memory leak in 43 Things due to sloppy coding through additional  
logging that no amount of GET requests could illuminate.

> Or is there a better way to go about this?

There's no sense trying to figure out what to optimize by mimicking  
usage when all that information is easily extractable from your logs.

Use the production_log_analyzer gem to figure out what pages get hit  
the most and how much they cost and look at where they spend their time.

pl_analyze will tell you if time is spent waiting for the DB,  
processing a view or elsewhere (controller/model before render), and  
then help you figure out if you need to change DB queries or add  
indexes, cache renders, or optimize some code respectively.

Here's trimmed output from 43 Things from about a year ago:

Request Times Summary:     Count    Avg    Std Dev  Min    Max
ALL REQUESTS:              2035035  0.521  1.218    0.000  1387.964

ThingsController#view:     420323   0.974  0.803    0.000  55.557
PeopleController#view:     302102   0.466  0.527    0.000  46.119
PeopleController#progress: 254735   0.710  0.422    0.000  42.280

The above shows that ThingsController#view is dog slow, and needs  
some work.  Looking below you'll see that half the time is spend  
rendering, and the DB times for all three actions are close.

I doubt DB work could improve things here.

DB Times Summary:          Count    Avg    Std Dev  Min    Max
ALL REQUESTS:              2035035  0.106  1.034    0.000  1387.940

ThingsController#view:     420323   0.136  0.417    0.000  52.436
PeopleController#view:     302102   0.183  0.363    0.000  44.985
PeopleController#progress: 254735   0.154  0.225    0.000  41.713

Render Times Summary:      Count    Avg    Std Dev  Min    Max
ALL REQUESTS:              2035035  0.211  0.401    0.000  17.207

ThingsController#view:     420323   0.535  0.522    0.000  5.996
PeopleController#view:     302102   0.230  0.263    0.000  8.691
PeopleController#progress: 254735   0.129  0.172    0.000  8.491

Here we see that PeopleController#progress renders really fast  
compared to the other three, but takes .7 seconds overall, so the  
controller is either doing too much work or needs optimization.

> We're running multiple mongrels on multiple web servers against a  
> single
> PostgreSQL db right now but would be testing probably on a single  
> box and
> coming up with a scale to let us know how that relates to  
> production.  Or
> isn't that such a great idea?

There are many, many factors to tune.  pl_analyze will tell you if  
your DB is overloaded and needs tuning (indexes or memory), or if  
your code is crappy.  It won't tell you if you don't have enough web  
servers or if you're running too much load on your web server.  (I've  
found that Rails seems to have a sweet spot around 3 processes per  
CPU, and adding more processes has diminishing returns.)

pl_analyze won't tell you if you're losing speed by proxying requests  
through some other web server rather than handing them straight off  
to mongrel (when experimenting on 43 Things, Apache 1.3's mod_proxy  
gave a 20% slowdown when proxying to localhost).  You'll need to use  
something like httperf or railsbench or ab to find this out.  If you  
need to load balance, get some hardware.  Its less painful in the  
long run, you should be able to get your hosting company to take care  
of it for you.

Neither pl_analyze nor any benchmark tool will tell you if your  
processes are churning rapidly.  Starting up a Rails app on a loaded  
system is an expensive operation, check your logs and make sure they  
don't die until they've run for a couple hours.


More information about the Ruby mailing list