Consistent Hashing
mediumConsistent hashing is a partitioning technique that minimizes how many keys move when nodes join or leave a cluster. It's the default for caches, KV stores, service-mesh routing, and any system that has to deal with elastic membership.
Key Concepts
shard = hash(key) mod N) sends almost every key to a new shard when N changes. In a 10-node cache, adding an 11th node remaps roughly all keys — instant cache cold-start, DB stampede.1/N of total).Approach
- Hash node identifiers (with V vnodes each) onto a ring of size 2^32 or 2^64.
- Hash each data key onto the same ring.
- The owner of a key is the next vnode clockwise. Lookup: sorted ring + binary search → O(log V).
- For replication factor R, the next R distinct physical nodes (skipping vnodes belonging to nodes already chosen) hold replicas.
- Rack-aware variant: skip nodes in already-used racks to keep replicas across failure domains.
- Adding a node: assign V random tokens, transfer keys from neighbors' arcs.
- Removing a node: clockwise neighbor absorbs each vnode's arc; data moves to it.
- For hot keys, layer bounded-load: cap any node at C × average load; overflow goes to the next node.
Algorithm details
Ring representation: sorted array of tokens or a TreeMap; lookup via binary search / ceilingEntry.
Hash function: needs uniform distribution. MD5 is classic. MurmurHash3 / xxHash are faster.
Vnode tokens: random per physical node (Cassandra default), or pre-allocated for deterministic placement.
Replica walk: starting at primary, advance clockwise, take the first vnode whose physical node hasn't been used yet, continue until R replicas chosen.
Bounded-load (Google 2017): pick the closest node, but if it's already over 1+ε times average load, fall through to the next available.
Components
- Ring data structure (sorted token list / TreeMap).
- Token assignment policy (random, hashed-id, weighted, manual).
- Replica placement strategy (simple-walk, rack-aware, datacenter-aware).
- Bootstrap / decommission protocol to migrate keys.
- Gossip / membership service to keep nodes' rings in sync.
- Hot-key handling — bounded loads, key replication, or local in-process cache.
Trade-offs
Too few vnodes: ring is imbalanced; one node owns much more data than another.
Too many vnodes: memory overhead per node grows linearly; lookups slightly slower; failure recovery slower because one dead node has many tokens.
Consistent hashing solves placement skew. It does not solve workload skew — one hot key still saturates one node. You need additional mitigation for that (key replication, sharded counters, client-side cache).
Rendezvous (HRW) hashing has no ring, optimal balance, deterministic. Lookup is O(N) but for small N (a few hundred) that's not a problem and the code is much simpler.
Real-world systems
- Memcached client libraries (libketama, dalli): consistent hashing for partitioning the cache fleet client-side.
- Cassandra: virtual nodes (vnodes=256 default); rack-aware replica placement; gossip-based membership.
- DynamoDB: consistent hashing partitions, with bounded-load to handle hot partitions.
- Akamai: invented the technique for web caching; modern CDN routing builds on it.
- Envoy / Maglev: bounded-load consistent hashing for service-mesh routing.
- Discord: rendezvous hashing to map voice channels to media nodes.