一致性哈希 - 通过代码实际了解一致性哈希原理

概述:python 实现一致性哈希的功能,然后通过使用功能来了解原理

我在其他博客中看了很多关于一致性hash的原理,很详细。没有实际的例子,感觉这个理论的应用无从下手。这里我就从实际的例子分析下一致性hash

先上代码

import md5
class HashRing(object):
    def __init__(self, nodes=None, replicas=3):
        """
        nodes: 节点数
        replicas: 虚拟节点个数
        """
        self.replicas = replicas
        self.ring = dict()
        self._sorted_keys = []
        if nodes:
            for node in nodes:
                self.add_node(node)
    def add_node(self, node):
        """添加一个节点到 hash 环中, 包括所有的虚拟节点"""
        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):
        """从 hash 环上移除一个节点, 包括所有的虚拟节点一并移除"""
        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):
        """
        根据关键字获取所属节点
        注意: 此处关键字即为需要计算的字符串
        """
        return self.get_node_pos(string_key)[0]
    def get_node_pos(self, string_key):
        """计算虚拟节点"""
        if not self.ring:
            return None, None
        key = self.gen_key(string_key)
        nodes = self._sorted_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 string key it returns the nodes as a generator that 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 in 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,
        this long value 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)
    def print_all(self):
        """打印 hash 环所有节点信息"""
        if not self.ring:
            return None, None
        p = dict()
        for k in list(set(self.ring.values())):
            p[k] = 0
        print p
        for i, v in enumerate(self._sorted_keys):
            p[self.ring[v]] += 1
            # print "ring slot %d is node %s, hash vale is %s" % (i, self.ring[i], v)
            print "[{0}] node:{1}#{2} value:{3}".format(i, self.ring[v], p[self.ring[v]], v)

第一步: 创建2个节点的环,每个节点包含3个虚拟节点

猜你喜欢

转载自www.cnblogs.com/newguy/p/9163032.html