Import Md5class hashring (object): Def __init__ (self, Nodes=none, replicas=3): "" "manages a hash ring. ' Nodes ' is a list of objects that has a proper __str__ representation. ' Replicas ' indicates how many virtual points should is used pr. node, replicas is required to improve the Distribu tion. "" "Self.replicas = Replicas self.ring = Dict () Self._sorted_keys = [] If NODES:FO R node in Nodes:self.add_node (node) def add_node (Self, Node): "" "Adds a ' node ' to the hash ring (including a number of replicas). "" For I in xrange (0, Self.replicas): key = Self.gen_key ('%s:%s '% (node, i)) Self.ring[key] = node Self._sorted_keys.append (key) Self._sorted_keys.sort () def remove_node (Self, Node): "" "Removes ' node ' from the hash ring and its replicas. "" For I in xrange (0, Self.replicas): key = Self.gen_key ('%s:%s '% (node, i)) del Self.ring[key] Self._sorted_keys.remove (key) def get_node (self, String_key ): "" "Given a string key a corresponding node in the hash ring is returned. If the hash ring is empty, ' None ' is returned. "" "Return Self.get_node_pos (String_key) [0] def get_node_pos (self, String_key):" "" Given a string key a C Orresponding node in the hash ring was returned along with it's position in the ring. If the hash ring is empty, (' none ', ' none ') is returned. "" "If not self.ring:return none, none key = Self.gen_key (string_key) nodes = Self._sorte D_keys for I in xrange (0, Len (nodes)): node = nodes[i] If key <= node: Return Self.ring[node], I return self.ring[nodes[0]], 0 def get_nodes (self, String_key): "" "Given a Strin G Key It returns the nodes as a generator so can hold the key. The GeneratOr is never ending and iterates through the ring starting at the correct position. "" "If not self.ring:yield none, none node, pos = Self.get_node_pos (string_key) for key I N self._sorted_keys[pos:]: Yield Self.ring[key] while true:for key in Self._sorted_keys: Yield Self.ring[key] def gen_key (self, Key): "" "Given a string key it returns a Long value, t His long value is represents a place on the hash ring. MD5 is currently used because it mixes well. "" "M = Md5.new () m.update (key) return Long (M.hexdigest (), 16)
From hash_ring Import *memcache_servers = [' 192.168.0.246:11212 ', ' 192.168.0.247:11212 ', ' 192.168.0.249:11212 ']ring = hashring (memcache_servers) server = Ring.get_node (' My_key ') print Serverserver = ring.get_ Node (' MY_KEYSDFSDF ') print server
with a consistent hash, you can minimize the amount of cache miss because of increased or reduced server-generated
consistent Hashing algorithm is used in memcached, Key-value Store, Bittorrent DHT and LVs, so consistent Hashing is the preferred algorithm for load balancing of distributed systems.
Using hashring to implement a consistent hash under Python