Skip to content

Instantly share code, notes, and snippets.

@VeerpalBrar
Last active February 3, 2023 09:38
Show Gist options
  • Save VeerpalBrar/10293df1299d7a897f5305c3c9ecfbef to your computer and use it in GitHub Desktop.
Save VeerpalBrar/10293df1299d7a897f5305c3c9ecfbef to your computer and use it in GitHub Desktop.
A consistent hashing implementation in ruby
require 'digest'
class ConsistentHashing
def initialize(nodes)
nodes.map { |node| add_node(node) }
end
def find_cache(key)
puts
hash = hash_value(key)
puts "#{key} hashes to #{hash}"
node_hash = closest_node_hash(hash)
node = hash_to_node[node_hash]
puts "#{key} maps to #{node}"
end
def add_node(node)
hash = hash_value(node)
hash_to_node[hash] = node
puts "Nodes map to #{@hash_to_node}"
end
def remove_node(node)
hash = hash_value(node)
@hash_to_node = @hash_to_node.select{|node| node != hash}
puts "Nodes map to #{@hash_to_node}"
end
private
def hash_value(key)
Digest::SHA256.digest(key).sum % 360
end
def hash_to_node
@hash_to_node ||= {}
end
def closest_node_hash(key)
@hash_to_node.keys.sort.bsearch { |server| server >= key } || @hash_to_node.keys.sort.first
end
end
servers = ["server:A", "server:B", "server:C"]
hasher = ConsistentHashing.new(servers)
hasher.find_cache("a")
hasher.find_cache("b")
hasher.find_cache("z")
hasher.find_cache("hello")
hasher.add_node("server:B1")
hasher.find_cache("a")
hasher.find_cache("b")
hasher.find_cache("z")
hasher.find_cache("hello")
hasher.remove_node("server:B")
hasher.find_cache("a")
hasher.find_cache("b")
hasher.find_cache("z")
hasher.find_cache("hello")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment