InfoQ

InfoQ

News

My Bookmarks

Login or Register to enable bookmarks for unlimited time.

The content has been bookmarked!

There was an error bookmarking this content! Please retry.

Lessons from building Oracle Mix on JRuby on Rails

Posted by Werner Schuster on Nov 22, 2007

Sections
Development,
Architecture & Design
Topics
Ruby ,
Ruby on Rails ,
JRuby ,
Performance & Scalability
Tags
JRuby ,
Oracle ,
Ruby on Rails
Oracle Labs recently released Oracle Mix, a JRuby on Rails based social networking application. Rich Manalang now posted his experiences working on the project.  While the project is now running on JRuby, the initial work was done with MRI:
We built most of Mix using the standard Ruby interpreter (aka, MRI — Matz’ Ruby Interpreter) on Oracle DB XE using Ruby-OCI. Developing Rails apps is still much easier using MRI because jRuby takes a while to startup.
As it turns out, the Rails plugin system proved to be very useful in making Mix work with Oracle's internal systems - in this case the Single Sign On (SSO) policy:
One critical part of the project was to support Oracle’s SSO policy. Meaning every web app that we deploy has to support SSO using the Oracle SSO service. It took me a few days to figure out how all this worked but once we did, it wasn’t difficult to plug it into the acts_as_authenticated Rails plugin that we were using.
With these issues out of the way, the team encountered another problem when deploying to JRuby on Rails: Performance:
After I had the boxes primed, we started doing early deploys on jRuby. The performance was terrible. About 20-40 reqs/sec on a single app server. Turns out that I didn’t have some of the production settings configured properly (i.e., not caching ruby classes, etc.) Once I modified a few environment settings (standard rails prod settings), I got about 80 reqs/sec on a single app server… better but not enough.
Long story short, after a flurry of investigations into the performance problems, performance figures improved:
Ola and the jRuby team found some interesting bottlenecks in the jRuby code. Within in a day or two, Ola and team had them patched up and we were beginning to see around 150-200 reqs/sec. After the app server warmed up, things got real interesting… the numbers went way up (400-600 reqs/sec).
This is only the beginning, as the post states, as these numbers are taken on a system that doesn't do any caching. So what caused the increase in performance? The JRuby team investigated a list of problems, discovering old problems such as regular expression performance:
But the discovery I made was when I looked at the performance of the regular expressions used in Rails. There are exactly 50 of them for each request, so I did a script that checked the performance of each of them against MRI. And I found that there was one in particular that had really interesting performance when comparing MRI to JRuby. In fact, it was between 200 and a 1000 times slower. What's worse, the performance wasn't linear.
This problem actually occurred in the each_line implementation of JRuby and not in the Rails code. With performance problems as this, and some others, discovered and fixed, JRuby speed in general improved considerably..

Next to bottlenecks in the JRuby implementation, some other reasons can slow down a JRuby application. Nick Sieger points out a few tricks JRuby users can do to improve the speed of their applications. The most important steps to take seem to be:
  • Switching off ObjectSpace.
    ObjectSpace is a feature that allows to iterate over all objects on the heap. Few libraries actually make use of this, so turning it off doesn't have consequences. JRuby 1.1, actually, turns this off by default. The increase in performance is considerable: because to provide the ObjectSpace functionality, every created object needs to be registered in a separate list structure, thus increasing costs for object creation.
  • Ensure the "server" VM is used
    The "server" VM can be used with a simple command switch, and ensures more aggressive performance optimizations.
  • Waiting for the JVM to warm up
    This is not really an optimization, but ensures that the right performance is measured. The way the JVM works, the bytecode is initially interpreted, and incrementally optimized and compiled to native code by a dynamic compiler. Only code that is actually used a lot is compiled and optimized, and this takes some time. This means, measuring performance, such as requests/second, on a freshly launched JVM will yield worse performance than on a JVM that has been running for some time.
  • Switching from a stable JRuby (like JRuby 1.0.x) to the development version
    This works particularly for JRuby 1.1 (the current development version), since this is the first JRuby with a complete JIT. However, since the development version can change quite a lot, this also means that using the latest version can mean newly introduced, unreported bugs. These can break an application in unexpected ways. Of course a proper test suite can help with keeping the effects of this low. Whether the overhead of keeping up with JRuby development is worth the extra performance must be decided on a case to case basis.
JRuby and Performance by Geoffrey Wiseman Posted
Performance by Ola Bini Posted
Question by Alex Popescu Posted
Re: Question by d taye Posted
Re: Question by Rich Manalang Posted
  1. Back to top

    JRuby and Performance

    by Geoffrey Wiseman

    It's good to see JRuby performance picking up; in some of our early work with Ruby and JRuby, we hit a few performance snags, so I'm glad to see these improving before I have to face these again.

  2. Back to top

    Performance

    by Ola Bini

    Of course, the points you listed we have obviously done for Mix. ObjectSpace and -server made most of the largest jumps in numbers possible. It's on the application layer we haven't done much of any optimization.

  3. Back to top

    Question

    by Alex Popescu

    Developing Rails apps is still much easier using MRI because jRuby takes a while to startup.


    Can somebody clarify the above statement? Is the statement made in terms of startup time, or something else?

    thanks,

    ./alex
    --
    .w( the_mindstorm )p.
    Alexandru Popescu
    Senior Software Eng.
    InfoQ Techlead/Co-founder

  4. Back to top

    Re: Question

    by d taye

    Developing Rails apps is still much easier using MRI because jRuby takes a while to startup.

    Any attempts to run this on the tiered VM? I think 1.7 has that enabled by default nowadays.
    It would also be interesting to try this on IBM's 1.6 and (why not) BEA's 1.6. IBM has some sort of 'extended' support for class data sharing that includes app classes, and BEA still rocks on x86...

  5. Back to top

    Re: Question

    by Rich Manalang

    Yes, I was referring to the starting up jruby in general. When developing a rails app, you will have to make use of CLI tools like rake, script/console, etc... using those tools on JRuby is much slower than on MRI.

Educational Content

10 tips on how to prevent business value risk

One category of risk that project teams need to ensure they address is business value failure – delivering a product that fails to provide value for the business investor.

Interview: Software Systems Architecture: Working With Stakeholders Using Viewpoints and Perspectives

InfoQ spoke to the authors of Software Systems Architecture on a couple of new topics, the System Context viewpoint and Agile, which have been added to the second edition.

Beauty Is in the Eye of the Beholder

Alex Papadimoulis discusses ugly code, where it comes from, how to avoid it, and how to get rid of it.

Architecting Visa for Massive Scale and Continuous Innovation

John Davies examines Visa’s architecture and shows how enterprises have architected complex integrations incorporating Hadoop, memcached, Ruby on Rails, and others to deliver innovative solutions.

Max Protect: Scalability and Caching at ESPN.com

Sean Comerford unveils ESPN.com’s architecture, what components are used and why, and the current changes the website goes through.

The Seven Deadly Sins of Enterprise Agile Adoption

Are there repeated patterns of failure on Enterprise Agile Enablement efforts? Sanjiv and Arlen discuss Seven Deadly Sins to avoid when adopting Agile in an enterprise.

Questions for an Enterprise Architect

Erik Dörnenburg answers: What is Enterprise and Evolutionary Architecture?, discussing 4 issues: Turning strategy into execution, Ensuring conformance, Where do the architects sit? Buying or building?

Wrap Your SQL Head Around Riak MapReduce

Sean Cribbs explains what Map-Reduce and Riak are, why and how to use Map-Reduce with Riak, and how to convert SQL queries into their Map-Reduce equivalents.