算法

hash一致性算法的Python实现

2019-10-26  本文已影响0人  李白开水

田田田

实现思路

代码实现

# coding=utf-8
import hashlib


class Hash_consistency():
    def __init__(self, nodes=None, virtual_node=4):
        """

        :param nodes: 一共有多少个节点
        :param virtual_node: 每个节点有多少个虚拟节点

        """
        self.virtual_node = virtual_node  # 每个节点有几个虚拟节点
        self.node_dict = dict()  # 用于将虚拟节点的hash值与node的对应关系
        self.virtual_ring = []  # 用于存放所有的虚拟节点的hash值,这里需要保持排序
        if nodes:
            for node in nodes:
                self.add_node(node)

    def add_node(self, node):
        """
        添加node节点,首先要根据虚拟节点的数目,计算出节点的虚拟节点,将node节点与4个虚拟节点对应
        将虚拟节点的hash值存在virtual_ring[]中,保持排序

        :param node:
        :return:
        """
        for i in xrange(0, self.virtual_node):
            key = self.get_key(node)
            self.node_dict['node'] = key
            self.virtual_ring.append(key)

        self.virtual_ring.sort()

    def remove_node(self, node):
        """
        删除node节点的所有虚拟节点
        首先根据node_dict中节点与虚拟节点的对应关系,找到虚拟节点
        将虚拟节点的所有数据根据virtual_ring,找到下一个虚拟节点,并存储在这个找到的虚拟节点上
        删除所有的虚拟节点
        :param node:
        :return:
        """
        for i in xrange(0, self.virtual_node):
            key = self.get_key(node)
            self.node_dict[node] = 0  #没有真正删除,只是把key对应的值替换了
            self.virtual_ring.remove(key)

    def get_node(self, str):
        """
        返回这个字符串对应的node,先求出字符串的hash值,然后找到第一个小于等于的虚拟节点,
        然后返回node
        如果hash值大于所有的节点,那么用第一个虚拟节点
        :param :
        :return:
        """

        if self.virtual_ring:
            key = self.get_key(str)
            for node_key in self.virtual_ring:
                if key <= node_key:
                    return self.node_dict[node_key]
                else:
                    return self.virtual_ring[0]
        else:
            return None



    @staticmethod
    def get_key(node):
        key = hashlib.md5(node).hexdigest()
        return long(key, 16)


def main():
    h = Hash_consistency()
    h.add_node("node1")
    print h.get_key("node1")
    print h.get_node("hello")
    print h.virtual_ring
    h.remove_node("node1")
    print h.virtual_ring



if __name__ == '__main__':
    main()

参考
上一篇下一篇

猜你喜欢

热点阅读