Luke Melia

personal

October 8, 2009

Running REE at EngineYard

At Weplay, we recently switched our Ruby interpreter from MRI 1.8.6 to REE 1.8.6, and have seen dramatically improved response times (reduced by ~40%).

As of now (October, 2009), EngineYard doesn’t support Ruby Enterprise Edition, so we had to go it alone. This blog post documents our configuration.

We run in EngineYard’s cluster environment with nginx -> HAProxy -> mongrel load-balanced across a few app server slices with a utility slice running delayed_job workers. Our ruby processes are managed by monit.

Here’s how we went about things:

Install REE

I installed REE at /opt/ruby-enterprise-1.8.6-20090610. One of my goals was a side-by-side installation with MRI so that I could switch back quickly if something went wrong. (As it’s turned out, REE has been rock-solid for us.)

Note the –auto flag which provides for a non-interactive installation.

Update mongrel_rails script

Our EngineYard slices have MRI installed at /usr/bin/ruby18 with a symlink at /usr/bin/ruby. The shebang line in /usr/bin/mongrel_rails was:

#!/usr/bin/ruby18

Change it to:

#!/usr/bin/ruby

This may not be absolutely necessary based on how your environment starts mongrel, but I’d
recommend doing it anyway.

Prepare a script to update symlinks

So now you’ll have the following setup:

/opt/ruby-enterprise-1.8.6-20090610/bin/ruby

/usr/bin/ruby18

/usr/bin/ruby -> ruby18

To switch to REE, we’re going to switch that symlink to point at the REE ruby binary. You’ll also want to do the same for other binaries like rake, gem, etc. Here’s a script, eyruby_switch.rb, I wrote to switch them all at once:

You will call the script like this: ./eyruby_switch.rb ree or ./eyruby_switch.rb mri. Don’t execute it just yet.

Re-install gems

Before the switch, I wanted to get all our non-vendored gems installed in REE. The REE install has its own gems directory, and you can’t share gems with native extensions between REE and MRI anyway, so you need to reinstall. Here’s an example of installing a gem for REE without needing to have the symlinks pointed to REE:

sudo /opt/ruby-enterprise-1.8.6-20090610/bin/ruby /opt/ruby-enterprise-1.8.6-20090610/bin/gem install --no-rdoc --no-ri nokogiri

Setup GC-tuning wrapper script

For us, the big performance win for REE was the tuneable GC parameters. I’m not going to try to explain the params here. If you made it this far, you’ve probably already ready Evan Weaver’s blog posts on this topic.

Our goal was to apply the GC params to all rails processes, but not necessarily to every ruby process running on the system. So we created a wrapper script called ruby_with_env:

Put it somewhere on your system (ours is at /data/weplay/shared/bin/ruby_with_env) and make sure it’s executable.

Update monit scripts

Examine all the scripts specified by the .monitrc files in /etc/monit.d/. In any script that starts a rails process, replace the call to /usr/bin/ruby with the ruby_with_env wrapper script. This is safe to do even if MRI is still the active ruby on the system, because the environment variables will simply have no effect with MRI — everything else should run properly.

Flip the switch, hero

Update the symlinks:

./eyruby_switch.rb ree

Verify the script worked with ruby -v

Then tell monit to restart your processes and your app is now running on REE.

Feedback

I would love to see EngineYard support REE so I can use their otherwise excellent team to do setup and maintain this stuff for me. Until then, maybe we can help each other out. If you have questions or ideas to improve this configuration, let me know in the comments or on twitter.

One more thing

If you’re in the early stages of exploring REE and you just want to try it out locally, I highly recommend Wayne Seguin’s awesome rvm – Ruby Version Manager. It makes it easy to install REE and switch back in forth in a development environment.

4 Responses to “Running REE at EngineYard”

  1. Benjamin Stein chimed in:

    We switched to REE & Passenger a few months ago. Huge win for us too. Thanks for the detailed write-up!

  2. Josh Knowles chimed in:

    Great writeup, thanks Luke.

    Would be interesting to run REE on one slice, and MRI on another, so you can compare the graphs side-by-side.

  3. Karl chimed in:

    Amazing tutorial. Just installed REE within staging and I am in the process of updating production.

    Couple of quick notes.

    1) Remember to install mongrel and mongrel_cluster gems

    2) In some place /usr/bin/ruby is implied by the interpreter of the script. In order to use ruby_with_env instead, I prefixed the ruby script. For example, within /engineyard/bin/monit_mongrel

    /data/weshop/shared/bin/ruby_with_env /usr/bin/mongrel_rails cluster::start -C /data/$APPLICATION/current/config/mongrel_cluster.yml –clean –only $PORT

  4. Karl chimed in:

    One more addendum. I had to add this to my .bash_profile to get gem to work within staging.

    unset RUBYOPT

Leave a Reply

LukeMelia.com created 1999. ··· Luke Melia created 1976. ··· Live With Passion!