Never change your hashing algorithm. Please.

I'm not the first to say this (http://www.cubik.org/mirrors/taligent/Docs/books/WM/WM_144.html), but it needs to be said again: Please, never change your hashing algorithm. I'm looking at you memcache-client ruby gem...

We have a certain setup (the details of which I will not fully delve into) that shares data across a couple different apps via Memcache. It’s a handy (although, maybe not ideal) setup that provides speed and scalability. Basically, it does a good job of solving the problem we wanted to solve. However, we ran into an issue the other day with one app not being able to reliably retrieve info the other app had set in Memcache. A bunch of debugging later, we realized it came down to the fact that one app was using memcache-client-1.5.0, and one was using memcache-client-1.7.2.

Ideally, we would keep both apps on the same version of gems that are used for communicating information between apps, but, a simple memcache get / set should not break because of minor version differences.

Specifically, our issue came down to this: these two snippets of code are not the same, and that’s not good at all…


# in get_server_for_key method, memcache client 1.5.0
20.times do |try|
  server = @buckets[hkey % @buckets.nitems]
  return server if server.alive?
  hkey += hash_for "#{try}#{key}" 
end

# in get_server_for_key method, memcache-client 1.7.2
20.times do |try|
  entryidx = Continuum.binary_search(@continuum, hkey)
  server = @continuum[entryidx].server
  return server if server.alive?
  break unless failover
  hkey = hash_for "#{try}#{key}" 
end

Please, seriously, don’t change your hashing algorithm.

Posted by Phil Burrows on May 18, 2009

Post a comment