The internets are all atwitter about comments made by Twitter developer Alex Paynt, which seemed to partially blame Ruby / Rails for scaling problems twitter has been having.
The common wisdom in the Rails community at this time is that scaling
Rails is a matter of cost: just throw more CPUs at it. The problem
is that more instances of Rails (running as part of a Mongrel
cluster, in our case) means more requests to your database. At this
point in time there’s no facility in Rails to talk to more than one
database at a time.
These things are always fun to watch, in part since DHH is so, err, timely in responding to anything that could possibly be perceived as a criticism of Rails. Sure enough, it didn’t take long for his rebuttal to be published.
This conversation has been some time coming, so it’s a good thing that it’s happening now. There’s no doubt that Ruby is slow. Does this mean it doesn’t scale? And is this multi-database thing the bottleneck?
At slideshare we’ve definitely been impacted by our choice of Ruby as a language, and Rails as a platform. Ruby has been a lovely language to develop in, but it IS slow. Everyone agrees about this: it’s not even a controversial statement. But somehow, having to actually slap down your credit card and rent a bunch more servers really drives the disadvantages of this home in a way that just talking about it doesn’t! Another issue is that the more computers you have, the more you have to manage. That means you’re spending more money on system administration earlier, and you’ll need to figure out how to rapidly deploy new machines.
There’s another implication of the “throw CPU at the problem” solution. Small startups like us often pay for load balancing as a service, rather than owning their own $40,000 load balancer. The load balancer services the public IP address and distributes the inbound web traffic to an arbitrary number of servers. The smart thing to do in this case is to put your web servers on different boxes from your app servers. Otherwise you’ll end up spending a lot of money on load balancing just to add more CPU! This is no big deal (it’s actually the clean way to organize your servers), but it’s a good idea to architect your Rails app with the assumption that you’ll have 3 servers (dbase, app, web) from day one.
The other issue, the more serious issue in my opinion, is raw latency. We’re not happy with the page response time of slideshare yet, even when it’s not under load. To be fair, we’ve barely begun the profiling, tuning, and optimization needed. But if it turns out that Ruby is what’s stopping us from getting the sub-second response times we want, it will be a huge bummer. I can’t say (for sure) that Ruby is at fault here though. The fault for the moment lies with us and the fact that we haven’t been able to spend as much time on profiling and tuning as we’d like!
That’s Ruby. Rails brings its own issues of scaling, mainly the fact that it is single-threaded. This means you need to have a bunch of app-server instances running on each box, which means you need a software load balancer, which is just one more piece of software that needs to be maintained, monitored, and occasionally fixed. More complexity! Yuck. But not THAT big a deal.
The database problem that Alex Paynt mentions is more serious. There are two scenarios. One is the fairly simple and common-place scenario of talking to a database cluster that has one master database (for writes) and a bunch of slave databases (for reads). The trickier scenario is when you have multiple databases that have DIFFERENT data in them, and you’re trying to retrieve this information and use it in a web app. This is usually because your web app has too many writes, so you’ve needed to split it into multiple master databases, and shard your database..
I’m unclear which scenario twitter was experiencing, although thinking about the wtitter application, it seems likely that it’s the latter.
Fortunately, the response to this conversation about Ruby and multiple databases has been pretty immediate. A GEM (Magic Multi-Connections) has already been written. Sweet!
We’re really happy that this whole conversation happened BEFORE we faced this problem (we have only one database server at present). Magic Multi-Connections will definitely come in handy when we need to scale up to two or three database machines! That’s the magic of open source (free code!), and also the magic of Rails (rapid development).
I hope that Magic MultiConnections is the solution to connecting to multiple databases with rails. I’ll report back as we start to play around with it!