Now that my code is on its way to a GlassFish build near you, I thought that I would take a bit of time to explain what it is that my code actually does. In a nutshell, it allows GlassFish Rails apps to automagically configure their resource use to their current load.

 Previously, GlassFish used a static pool of Ruby runtimes to handle incoming requests. If, at deployment time, you asked for 3 runtimes, it would initiate three runtimes and those would be used to handle all incoming requests. This was simple, reliable, and easy to debug. Unfortunately, it was also remarkably inflexible. The only way to change the number of runtimes in the pool was to take the application down and edit the files. Improperly configured apps had long response times or wasted memory with extra runtimes, and in some cases the "proper" configuration changed while the app was running, making it impossible to properly configure.

 My code has been focusing on making the size of the runtime pool dynamic. The pool object now keeps track of all kinds of statistics about the size of the pool relative to the current load on the app and the resources of the machine that it's running on. Then, it tries to adjust the number of runtimes in the pool to deliver maximum performance and minimum resource usage. Under heavy traffic, it will create additional runtimes to try to service more requests, and under light traffic it will allow runtimes to be garbage-collected to try to keep resource usage down. In general, it will try to keep the number of runtimes that it has available as low as possible while still serving all requests as quickly as possible.

 So, how does this affect you? The short answer is that it takes the guesswork out of configuring the number of runtimes to allocate to your apps, especially in situations where you have multiple apps sharing the same machine and they can't all be allocated as many runtimes as they might need at deployment.

 The long answer comes with sample results from the Apache Benchmark, run on a 4-core machine with concurrency = 4:

Without Warmup
With Warmup
Existing pool, 1 runtime
 17  22
Existing pool, 4 runtimes
 22  36
Dynamic pool
 22  36

 These numbers are requests served per second, so higher is better. The "warmup" was running the benchmark once to ensure that everything had loaded correctly, and then running a second time and recording the results.

This shows two important things. Firstly, that there isn't performance degradation from the old version to the new version. Always a good thing. Secondly, this shows the performance boost that the dynamic pool will give over an app that hasn't been allowed to consume as many resources as it would like to. On the other side of this, though harder to show, is the memory footprint reduction that an app that has been assigned enough runtimes that many of them are usually sitting idle. An app that sometimes needs four runtimes but usually only needs one will use three runtimes less memory under the dynamic pool than if you just assigned it the four runtimes that it sometimes needed.

 As I said in my previous blog post, hopefully this will just sit down at the bottom of GlassFish and you'll never really be aware of its existence. But you should still know that it is down there, using the bit of AI that it has to make things more efficient and make your applications figure out their configurations on their own rather than require you to carefully adjust your settings until you find the ones that work best at the moment.


Comments:

Nice! Is there any scope for capping apps to a maximum number of runtimes?

Posted by Dick Davies on August 28, 2008 at 01:46 AM PDT #

By default, runtime creation is capped based on the number of processors in the machine, but I've also included a constructor to set both the maximum and minimum values manually.

Posted by Jacob Kessler on August 28, 2008 at 12:50 PM PDT #

[Trackback] Last day of Rails Conf Europe 2008 (Day 1 & Day 2), and it's finally over! David Black's opening session talked about Ruby and Rails Symposium: Versions, Implementations, and the Future. Here is a brief summary of MRI Ruby...

Posted by Arun Gupta's Blog on September 05, 2008 at 10:19 PM PDT #

Post a Comment:
  • HTML Syntax: NOT allowed

This blog copyright 2009 by Jacob Kessler