19 Feb

Scaling a Rails app (Part 3 of 3)

This the third and last part for a summary about solutions to help better computing of your rails app

Some home made benchmarks

NB: Following benchmarks have been made to a quick look study and not for a proof of concept.

The test machine (dedibox, ubuntu 6.10) is 1 core cpu @2Ghz – 1024 Mo memory. In each case the http server uses 10 processes on a real world application (not just ‘hello world!’). Sending 500 rq with 1 or 10 concurrency req:

conc. req. 1 10
apache
mongrel 39.4s – 12.7 r/s 21.9s – 22.8 r/s
thin 37.6s – 13.3 r/s 17.7s – 28,15 r/s
nginx
mongrel 39.2s – 12.8 r/s 22.2s – 22.5 r/s
thin 0.5.4 39.8s – 12.6 r/s 17.7s – 28.15 r/s
thin 0.6.1 socket x2 37.6s – 13.3 r/s 17.8s – 28.1 r/s


Since last time, Rails world has a new nice app server: thin. Replacement of mongrel, based on rack interface, it’s also recently added a unix socket connector where usually we use IP connector. For better performance, avoid longest stuff as scripts (google analytics). Other scripts/images/css are keys in http performances also, usage of assets in recommended.

As we can see in equivalent configuration there is no major difference for http server. Thin seems to be definitly faster than mongrel when you need to server more than 1 request at a time. And of course on a 1 core cpu, having more than one app server doesnt make the content served really faster.

Memory usage

Mongrel (48 Mo) → Thin (40 Mo) less 15%

Apache (10 Mo) → Nginx (1.4 Mo) less 85%

Finally I decided to move to a nginx / thin on socket configuration because of the memory usage and the fair performances. I even moved my PHP stuff with an fcgi connector.

Other ideas of tests: Varnish, Nginx and memcached. Maybe next time :)

[update]

Please find a good benchmark about nginx vs apache on Joe’s blog

Overall conclusion

I think when we need to compare two framework, about which one is faster, we should keep in mind all these levels of optimisation to scale an application, and then the raw performance is a secondary issue.

tags: railsconf (3) scaling (5) ruby (22) rails (32) proxy (3) frontend (3) nginx (6) apache (5) jruby (3) glassfish (3) mysql (3) haproxy (2) freebsd (3)
14 Oct

Scaling a Rails app (Part 2 of 3)

This the second part for a summary about solutions to help better computing of your rails app (1st part).

Application

To help your application to focus on replying fast to user, you can use a distributed queueing to give the job to other processes:

And second thing, you can cache things you don’t need to compute for each request, this can incredibly increase the response of your server, but need to modify your code and it s recommend for very big sites:

Back end

DB

For your database you can find some sql proxy, but I haven’t tried it yet. You have also the way to replicate your databse and serve data from several servers.

  • sql relay
  • use jruby with a jdbc pool connection and caching

Important things you have to check about your databse is if you have the right indexed fields. You should find some tools on mysql helping you to find where indexes missing. Check about cache too.

A last way is to serialize some of your data in a single object.

Mysql

Otherwise you can configure your mysql with some optimized configuration (mysql.ini):

  • skip-name-resolve
  • query_cache_size = 52428800;
  • query_cache_type = 1

And in your ActiveRecord object you can use the :include parameter.

Filesystem

Optimizing the filesystem, in other sense than choose a good OS, can been done with not overloading the management of files by using some rules:

  • max 10K files / subdir
  • 16 top level / 256 sub / 10K per sub dir
  • use a hasher to manage files

OS

As we have seen, file and memory management are keys of good performances. And these are managed by OS. The two best OSs mentionned are

  • Sunsolaris
  • FreeBSD (can be use for a all in one stack), avoid the version 5

And upcoming, last part of this article, some home made benchmarks for my own purpose.

tags: railsconf (3) scaling (5) ruby (22) rails (32) proxy (3) frontend (3) nginx (6) apache (5) jruby (3) glassfish (3) mysql (3) haproxy (2) freebsd (3)