
Consistent Hashing is a technique used in distributed systems to distribute data across a dynamic set of nodes (like servers) in such a way that minimizes reorganization when nodes are added or removed. It’s especially useful in scenarios like load balancing, distributed caching (e.g., Memcached), and sharding databases.
2^32 - 1 for a 32-bit hash).Imagine we have three servers: A, B, and C.
hash(A) = 20hash(B) = 50hash(C) = 80K1 with hash(K1) = 30, it will be stored on server B (the next clockwise node).hash(K2) = 70, it will go to server C.hash(K3) = 90, it wraps around to server A.hash(D) = 60.K2 (hash 70) will still go to C, but keys between 50 and 60 will go to D, minimizing data movement.To avoid uneven data distribution when node hash values are clustered, virtual nodes are used. Each physical node is assigned multiple virtual nodes with different hash values, ensuring better load balancing.
Here’s a basic implementation of Consistent Hashing in Python:
import hashlib
import bisect
class ConsistentHashing:
def __init__(self, nodes=None, replicas=3):
self.replicas = replicas
self.ring = {}
self.sorted_keys = []
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.ring[key] = node
bisect.insort(self.sorted_keys, key)
def remove_node(self, node):
for i in range(self.replicas):
key = self._hash(f"{node}:{i}")
del self.ring[key]
self.sorted_keys.remove(key)
def get_node(self, key):
if not self.ring:
return None
hash_val = self._hash(key)
index = bisect.bisect(self.sorted_keys, hash_val) % len(self.sorted_keys)
return self.ring[self.sorted_keys[index]]
# Example usage:
nodes = ["A", "B", "C"]
ch = ConsistentHashing(nodes)
print(ch.get_node("K1")) # e.g., outputs 'B'
print(ch.get_node("K2")) # e.g., outputs 'C'
# Add a new node
ch.add_node("D")
print(ch.get_node("K1")) # Might still be 'B' or changed to 'D' based on hash
Here’s how you might implement Consistent Hashing in Java:
import java.security.MessageDigest;
import java.util.*;
public class ConsistentHashing {
private final int numberOfReplicas;
private final SortedMap<Integer, String> circle = new TreeMap<>();
public ConsistentHashing(List<String> nodes, int numberOfReplicas) {
this.numberOfReplicas = numberOfReplicas;
for (String node : nodes) {
addNode(node);
}
}
private int hash(String key) {
try {
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] digest = md.digest(key.getBytes());
return ByteBuffer.wrap(digest).getInt();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public void addNode(String node) {
for (int i = 0; i < numberOfReplicas; i++) {
circle.put(hash(node + i), node);
}
}
public void removeNode(String node) {
for (int i = 0; i < numberOfReplicas; i++) {
circle.remove(hash(node + i));
}
}
public String getNode(String key) {
if (circle.isEmpty()) {
return null;
}
int hash = hash(key);
if (!circle.containsKey(hash)) {
SortedMap<Integer, String> tailMap = circle.tailMap(hash);
hash = tailMap.isEmpty() ? circle.firstKey() : tailMap.firstKey();
}
return circle.get(hash);
}
public static void main(String[] args) {
List<String> nodes = Arrays.asList("A", "B", "C");
ConsistentHashing ch = new ConsistentHashing(nodes, 3);
System.out.println(ch.getNode("K1")); // e.g., outputs 'B'
System.out.println(ch.getNode("K2")); // e.g., outputs 'C'
ch.addNode("D");
System.out.println(ch.getNode("K1")); // Node might change depending on the hash
}
}
Consistent Hashing is a fundamental concept for scalable, fault-tolerant distributed systems. By using the hash ring and virtual nodes, it ensures minimal disruption during scaling or failure scenarios.
When analyzing a stock, one of the first financial indicators you’ll encounter is EPS, or Earnings Per Share. It’s one… Read More
When you look at a stock’s profile on a financial website, one of the first things you’ll see is its… Read More
In the world of open-source software, simplicity and flexibility are often just as important as legal protection. That’s why the… Read More
If you want your software to be open source, but still compatible with commercial use—and not as restrictive as the… Read More
When it comes to open-source software, developers and businesses alike need licenses that balance freedom, legal clarity, and long-term security.… Read More
If you’re working on open-source projects or choosing third-party libraries for your software, understanding software licenses is essential. Among the… Read More