Misconceptioned Memcached

You’ve heard of memcached, haven’t you?
Made by Livejournal to sustain millions of angst-ridden teen diaries, now used by web giants like Slashdot, Digg, Wikipedia, Facebook, Youtube, and countless more. Even this very Wordpress blog supports it.
The same misconception seems to haunt all those unfamiliar with the memcached: it’s some sort of magical layer that sits between your database and your application layer, and somehow it makes things faster. The magic is scary. How would something know what it needs to speed up from the database? It must require all sorts of nasty configuration, all sorts of nasty corner cases to cover?
Admit it. The thought of using memcached terrifies you. Well, I have good news for you: That’s not what memcached is. Are you read for it?
Memcached is a hash table.
No, seriously. It’s that simple. It’s a hash table that sits in memory, that can scale between multiple servers. All you do is launch the memcached daemon on your server with memcachedand you can use it!
“Well obviously that’s not all there is…” you say. It is! As far as the server is concerned, that’s all the configuration it needs.
Now, the client side…
How does the hash table work? It’s just like a dictionary. To save data: you send it a key/value pair, and it saves it. To retrieve data: you send it a key, and it gives you the value. Explicit. Simple. Efficient. It supports a handful of simple operations like set, get, and replace.
Here’s how to use 3 distributed memcached servers to cache a huge query in Python:
import memcache ... cache = memcache.Client(['192.168.1.100:11211', '192.168.1.101:11211', '192.168.1.102:11211']) ... def get_post(post_id): "Return data associated with post with given post_id" result = cache.get(post_id) if not result: # No cache, perform potentially costly SQL query result = model.Post.get_post(post_id) # Save result in cache for next time cache.set(post_id, result) return result
Do you see what they did there?
Yes, it’s not magic. Yes, you have to cache things explicitly. Yes, this is incredibly powerful. Now go. Go make a Slashdotting-proof web service, that’ll show them.
1 commentGentoo, Rockband, Code, and Music

Today, you’ll get to hear about what I’ve been up to! This wont be on the exam.
- After a year and a half stint with Ubuntu, I’m back to my true love Gentoo. That is, with a
shinymatte new quad core beast of a machine. - Bought Rockband for my PS3 couple of weeks ago. Drums are ridiculously hard. Been rocking out. Good fun is being had by all those who dare rock. Can’t wait for Still Alive to be released for free. It shall be a triumph!
- What started out as pretty code is now a bonafide open source Python module: workerpool. People are using it. No, really.
- muxtape.com: A super simple music sharing web app launched last week. Its been enriching my life — doing what Pandora once did. Here’s my muxtape. Be right back, there’s someone at the door.
Code storytelling
It’s fun writing code that tells a story. Hopefully it’s also fun reading it.
class TerminationNotice(Exception): "Exception raised inside a thread when it's time for it to die." pass class SuicideJob(QueryJob): "A worker receiving this job will commit suicide." def run(self): raise TerminationNotice() class QueryWorker(Thread): "Devoted worker who will pull jobs from the `jobs` queue and perform them." def __init__(self, jobs): self.jobs = jobs Thread.__init__(self) def run(self): "Get jobs from the queue and perform them." while 1: job = self.jobs.get() if not isinstance(job, QueryJob): debug.error("%r ate a job that wasn't a edible: %r" % (self, job)) continue try: job.run() except TerminationNotice: # Nice knowing you :( break

