Why EC2 isn’t yet a platform for “normal” web applications

In a previous article, On Grids, the Ambitions of Amazon and Joyent, I made a few premises:

  • The autoprovisioning and account management (and therefore the accessibility) is the improvement over a service like Sun’s Grid
  • There’s no way that Amazon.com is literally coming off of S3 and EC2 (one datacenter and no CDN abilities? I don’t think so).
  • That it’s a PR case study in flipping from real technical reasons (the world could use this) to bogus reasons (selling excess capacity, in which there is no such thing).
  • The webmail.us case study is a perfect use case and people should recognize it as a moment in our industry when someone started using a “true grid service” to augment their own servers (and did so with a credit card).
  • That evangelists beating the same drum again and again is a powerful thing

Let’s be clear, EC2 is fine when you’re doing batch, parallel things on data that’s sitting in S3. In line with the economics favoring compute being by data (Jim Gray’s Distributed Computing Economics), and is definitely an improvement over other publicly available batch systems. I can see why it would be attractive to those working on science grids, one just has to overcome the large data set in proximity to compute issue.

However, the promise of unlimited scalability (at least in the “scale up” direction) for normal web applications has no basis and is not technically possible beyond normal limits with EC2. A “normal” web application is that one that has to always be up and persistent.

And I get a bit irritated when I come across sentences like Jinesh’s at RailsConf: “infinity auto-scalable on-demand computing resource” (here)

I know that is has no basis because it lacks at least one critical thing: real application switches.

Yes, I’m now calling load balancers application switches because I think one has to distinguish software on a general purpose server from dedicated, high-end switching hardware. For example, OpenBSD is a great operating system and has OpenBGPD, and while I could slap it onto a couple of one unit servers to function as my routers, I wouldn’t do that above a certain level.

There is a difference in the horizontal scalability for how many rails processes you can hit in the backend (previous joyeur). The limit is typically <1000 req/second and not that many mongrels, so it’s pretty easy to know that any Rails application on EC2 is not pushing a lot of traffic.

While you might think I’m biased because we do have the Accelerator product line, let me make it clear that we have that product line because we’ve also had to scale some of the oldest Rails applications around, and that constantly feeds back into the design.

I’ve also said what I think is valid about EC2, but let’s be clear about the list of deficiencies for multi-tiered applications:

  • No IP address persistence (they all function as DHCP clients and are assigned an IP). One has to use dynamic DNS services for a given domain.
  • No block storage persistence. When the instance is gone, the data is gone. Yes I know you can send this back regularly to S3, but isn’t that actually a “hack”?
  • No opportunity for hardware-based load balancing (which happens to be the key to scaling a process based framework like Rails and mentioned above).
  • No vertical scaling (you get a 1.7Ghz CPU and 1 GB of RAM, that’s it). So like the block storage problem, this hits databases, we run about 32GB of ours in memory.
  • Can’t run your own kernel or make kernel modifications so there’s no ability for kernel and OS optimizations, and no guarantee that they’ve been done.
  • Images have to be uploaded and then moved around their network to find a launching point. This can take several minutes, if not more. Move 100 GBs around a busy gigabit network sometime and see.

(I’ll leave out ones like having to learn and program against proprietary API and commands like “ec2-run-instances ami-5da964c3 -k websvr-key”, that’s usually what’s called vendor lock-in).

In conclusion, EC2 is fine for batch on S3 data and for interacting with the Simple Queue Service (see the webmail.us example), but I wouldn’t put a multi-tiered web application on it.

Getting Started with JRuby

JRuby is something we’re very excited about as it bridges the gap between the Java and Ruby worlds, bringing a wide range of new advantages to developers.

You can take advantage of the mature JDBC, utilize Java Application Servers such as Glassfish for deployment with simple WAR’s rather than Capistrano, or use existing JavaBeans and business logic written in Java to plug into a much better framework.

We’re pleased to be the first infrastructure company to stand firmly behind JRuby, offering it as part of our standard Accelerator packages.

Getting started is easy. In our Accelerators you will JRuby 1.0.0RC2 in /opt/jruby. JRuby comes complete with the jruby interpreter which is used just like ruby, including friends gem, jirb, and more. Let’s take a look at how to get started:

[z010101CA:~] admin$ export PATH=/opt/jruby/bin:$PATH
[z010101CA:~] admin$ jirb
irb(main):001:0> string = 'JRuby Rules!'
=> "JRuby Rules!"
irb(main):002:0> print string
JRuby Rules!=> nil
irb(main):003:0> string.upcase
irb(main):004:0> quit

It’s really that simple.

Want to do some JRuby on Rails work?

[z010101CA:~] admin$ which gem
gem is /opt/jruby/bin/gem
[z010101CA:~] admin$ gem list --local
*** LOCAL GEMS ***
sources (0.0.1)
    This package provides download sources for remote gem installation
[z010101CA:~] admin$ sudo gem install rails -y
Bulk updating Gem source index for: http://gems.rubyforge.org
Successfully installed rails-1.2.3
Successfully installed rake-0.7.3
Successfully installed activesupport-1.4.2
Successfully installed activerecord-1.15.3
Successfully installed actionpack-1.13.3
Successfully installed actionmailer-1.3.3
Successfully installed actionwebservice-1.2.3
[z010101CA:~] admin$ sudo chmod +r /opt/jruby/bin/*
[z010101CA:~] admin$ which rails
rails is hashed (/opt/jruby/bin/rails)
[z010101CA:~] admin$ rails webstore
      create  app/controllers
      create  app/helpers
[z010101CA:~] admin$ cd webstore/
[z010101CA:~/webstore] admin$ jruby script/server
=> Booting WEBrick...
=> Rails application started on
=> Ctrl-C to shutdown server; call with --help for options
[2007-05-27 07:00:52] INFO  WEBrick 1.3.1
[2007-05-27 07:00:52] INFO  ruby 1.8.5 (2007-05-16) [java]
[2007-05-27 07:00:52] INFO  WEBrick::HTTPServer#start: pid=33409388 port=3000 - - [27/May/2007:07:01:20 GMT] "GET / HTTP/1.1" 200 7552
- -> / - - [27/May/2007:07:01:20 GMT] "GET /javascripts/prototype.js HTTP/1.1" 200 71260 -> /javascripts/prototype.js - - [27/May/2007:07:01:20 GMT] "GET /javascripts/effects.js HTTP/1.1" 200 38200 -> /javascripts/effects.js - - [27/May/2007:07:01:21 GMT] "GET /images/rails.png HTTP/1.1" 200 1787 -> /images/rails.png - - [27/May/2007:07:01:21 GMT] "GET /favicon.ico HTTP/1.1" 200 0
- -> /favicon.ico

There you go. No tricks, no gimmicks. Just start playing.

For those who don’t have a Joyent Accelerator, download JRuby here: JRuby.org.