Who uses Node.js: Trello (Part 2)

Original author: Brett Kiefer
  • Transfer
This is a continuation of the translation of The Trello Tech Stack.

Part 1
  • CoffeeScript
  • Client
    * Backbone.js
    * HTML5 History API
    * Mustache
  • Pushing and Polling
    * Socket.io and WebSockets
    * AJAX Requests

Part 2
  • Server
    * node.js
    * HAProxy
    * Redis
    * MongoDB
  • So, do we like it?


Server


Node.js


The server side of Trello is based on Node.js. We knew that we would need to instantly distribute updates, which means having to keep many connections [to the server] open, so an event-driven, non-blocking server seemed like a good choice. Node.js also proved to be an amazing tool for building a prototype single-page application. The Trello server prototype was actually a simple library of functions that processed arrays of models located in the memory of one Node.js process, and the client application simply called these functions using a small WebSocket wrapper. For us, it was the fastest way to start trying to use Trello and make sure that development is moving in the right direction. We used the prototype version to manage the development of Trello and other Fog Creek internal projects.

By the time we finished the prototype, we had enough experience with Node.js and we were shocked by its capabilities and performance. So we continued to work and made of our Trello-Pinocchio a real boy, we gave him:

Node.js is great and gets better every time an active community releases new and useful libraries. The huge number [and nesting] of callbacks that you are forced to use at first seems like a problem, but after a couple of weeks you get used to it. We use the excellent async library (as well as the brevity of the code that CoffeeScript gives) to maintain control over our code. There are other elegant solutions, but we only need to use async, whose behavior we fully understand.

HAProxy


We use HAProxy to balance the load between our web servers. It distributes TCP connections between the round robin servers, and Node.js. leaves everything else. It keeps connections open long enough to allow WebSockets and reuse connections for AJAX requests.

Redis


Trello uses Redis for short-lived data that is used when exchanging between server processes, but is not saved to disk. Objects such as session activity level or OpenID temporary key are stored in Redis, and the application is built in such a way as to recover normally after a partial (or full) loss of this data. We run [Redis] with the given 'allkeys-lru' key and the working set at least five times larger than required. Thus, Redis automatically deletes data that has not been used for a long time, and restores it if necessary.

One of our most interesting uses of Redis is the alternative use of short queries when sending model changes back to browsers. When an object changes on the server, we send a JSON message to all the relevant WebSockets to notify clients and store this message in a fixed-length list for the involved model, noting how many messages have been added to this list for the whole time. Then, when a client using AJAX requests [rather than a WebSocket connection] pings the server for updates, from the moment of its last request, we can get the whole server response before checking permissions and in most cases checking one Redis value. Redis is so fast that it can handle thousands of such checks per second without a significant sag [performance] on a single CPU.

Also, Redis serves as our publish / subscribe server, and we use it to distribute messages about an object change from the server process that made the initial request to all other server processes. As soon as you have a configured Redis server, you begin to use it for all sorts of things.

Mongodb


MongoDB satisfies most of our database queries. We wanted the [server] Trello to be very fast. One of the coolest and most productive teams we know is the StackExchange affiliate company located next door. One day, while having lunch with their lead developer, David, I found out that although they use the SQL server to store data, in reality they store a lot of data in a de-normalized form to improve performance and normalize it only when necessary.

image
Trello today.

In MongoDB, we refused to use the capabilities of relational databases (that is, arbitrary JOINs) in favor of a very fast write, in most cases faster reading, and better support for de-normalized data - we can store the card properties [Trello element] in one document in the database and still be able to query (and index) nested document fields. Since we have grown rapidly, owning a database with performance that can handle a fair amount of violations in terms of read / write was a very good thing. Also, MongoDB is very easy to replicate, back up and restore (despite the Foursquare fiasco ).

Another benefit of using a repository of incoherent documents is the simple use of different versions of Trello code with the same database, without dancing with a tambourine around database schema migrations. This has many advantages when releasing a new version of Trello - it is very rare (if at all) to block access to the application while we update or fill out the database.

For development, this is also just super - when you use hg bisect (or git bisect) to search for a bug in the sources and a test relational database, then it needs additional steps to roll back or return the database to the tested version (or create a new database with the necessary fields) . This can seriously slow down your work.

So, do we like it?


We like our set of technologies. As Joel remarked, we bled throughout the development, but I have never seen a team making an interesting application without the bloodshed associated with tools and components. And not everyone can say that he really likes what they came to the finish line with. As is true for most applications, there are no components or implementation details necessary by nature. However, we believe that this many excellent open-source projects accelerated our development, gave us a solid and maintained code base, with which we intensively moved forward and made Trello a more responsive and beautiful application. Thanks to everyone who participated in these projects, this is a great time to be a programmer.

Does that sound attractive? Try Trello! It's free.

Still not enough talk? Here is the Trello presentation I made for recent discussions.

Also popular now: