Monday, April 30, 2007

memcached as a distributed session solution

It's moderately common these days to write web applications using sessions. When a user turns up, they're given a unique session ID, generally fed to them in the form of a cookie. The programmer can then store any old junk that they like in the session, which generally looks like a hashtable, and is stored server-side somewhere. This is handy for maintaining state and so forth.

Now, there are a few ways that the session can be stored. With things like PHP (and Ruby on Rails, and mod_python, and...), it's typically stored in a temporary directory, as a file. With Hunchentoot, the Common Lisp webserver that I use, it's stored in memory, in a real hash table.

A problem emerges when you look at having more than one machine handling HTTP requests. Suddenly, locally stored sessions won't necessarily work; user X's first request might be handled by server A, but then their next request might be handled by server B. One way to get around this is to redirect them to a specific server on entry, and keep them there. Hotmail used to to this, for instance. Another is to store the session data somewhere accessible to all servers. A MySQL database is occasionally used, especially by PHP-y people, but a better solution is memcached. Memcached is essentially a giant in-memory network-accessible hash table. It automatically manages data, deleting things as it runs out of space or they expire or so on. RoR, for instance, can use Memcached for sessions.

I was recently wondering about how one would go about creating a distributed application using Hunchentoot. This is particularly important since, while multi-core servers are becoming more common, most Lisp implementations, AIUI, do not do SMP (SBCL and OpenMCL do). Therefore to fully utilise a server it might be necessary to run more than one webserver on the same machine. Memcached seems like an ideal solution; the one issue is that there currently isn't a Lisp client for it. I'm writing one at the moment, as I get a chance; I will make it available when it's in a decent state.

1 comment:

  1. An even better solution is to put all the session data into the cookie and append an HMAC to that. This way the session can last forever (or as long as the user's browser is instructed to keep the cookie for) without using any resources on the server.

    When using memcached to store changing data some fun problems emerge. What happens if a machine in memcached cluster stops answering requests for awhile, updated session information is written to a new one, and the old machine comes back up with all the stale data on it?

    ReplyDelete