Consistent Hashing — algorithm for distributing keys across nodes where adding/removing a node moves only ~1/N of keys (not all). Basis of distributed caches (Memcached, Redis Cluster), CDN (Akamai routing), DB sharding. Key insight: hash both nodes and keys onto a circle (ring); key goes to the closest node clockwise. Virtual nodes (vnodes) balance load.
Below: details, example, related terms, FAQ.
Free online tool — HTTP header checker: instant results, no signup.
// Pseudocode
function nodeForKey(key, ring):
h = hash(key)
for node in ring sorted by hash:
if hash(node) >= h: return node
return ring[0] // wrap aroundConsistent hashing is a technique that allows for the efficient distribution of keys across a set of nodes in a distributed system. The primary objective is to minimize the number of keys that need to be relocated when nodes are added or removed. This is achieved through a circular structure known as a hash ring.
In this model, both the keys and the nodes are hashed to produce a numeric value, which is then mapped onto a circular space. Here’s how the process works:
When a node is added to the system, only the keys that lie between the new node and its predecessor on the ring need to be reassigned. This means that, on average, only ~1/N of the keys are affected, where N is the number of nodes. Conversely, when a node is removed, only the keys that were mapped to that node need to be redistributed.
This method scales well and provides a balanced distribution of data, minimizing the impact of node changes on overall system performance.
Implementing consistent hashing in a distributed application can be accomplished using various programming languages and frameworks. Below are practical examples demonstrating how to configure consistent hashing in a basic setup.
For instance, let’s consider a simple implementation using Python with the hashlib library:
import hashlib
class ConsistentHash:
def __init__(self, nodes=None, replicas=3):
self.replicas = replicas
self.keys = []
self.ring = {}
if nodes:
for node in nodes:
self.add_node(node)
def _hash(self, key):
return int(hashlib.md5(key.encode('utf-8')).hexdigest(), 16)
def add_node(self, node):
for i in range(self.replicas):
key = self._hash(f'{node}:{i}')
self.keys.append(key)
self.ring[key] = node
self.keys.sort()
def remove_node(self, node):
for i in range(self.replicas):
key = self._hash(f'{node}:{i}')
del self.ring[key]
self.keys.sort()
def get_node(self, key):
if not self.ring:
return None
hashed_key = self._hash(key)
for node_key in self.keys:
if hashed_key <= node_key:
return self.ring[node_key]
return self.ring[self.keys[0]]
In this example, we define a ConsistentHash class that maintains a hash ring and allows adding or removing nodes. The get_node method retrieves the node responsible for a given key.
Another practical example can be seen in Apache Cassandra, which utilizes consistent hashing for data distribution:
CREATE TABLE users (
user_id UUID PRIMARY KEY,
name TEXT,
email TEXT
);
CREATE KEYSPACE my_keyspace WITH REPLICATION = {
'class': 'SimpleStrategy',
'replication_factor': 3
};This configuration ensures that user data is evenly distributed across nodes, leveraging consistent hashing to maintain performance and reliability.
Consistent hashing offers several advantages that make it a preferred choice for distributed systems, particularly in scenarios where scalability and fault tolerance are critical. Here are the key benefits:
In summary, consistent hashing is an essential algorithm for distributed systems, providing efficiency, scalability, and reliability. Its benefits make it a cornerstone for technologies like distributed caching, content delivery networks (CDNs), and database sharding.
Redis Cluster (16384 slots), Memcached client-side sharding, DynamoDB partitioning, Cassandra, Akamai CDN, any distributed caches.
Range — sorted, easy range queries. Consistent — better balance, auto-reshuffle. For large-scale — consistent.
Rendezvous is simpler, O(n) per lookup vs O(log n). For small N — comparable. For huge clusters — consistent hashing wins.
Free plan — 10 monitors, checks every 5 min, no card required. Upgrade for 1-minute interval and multi-region monitoring.