一致性哈希算法 简单的 python 实现
原理以及应用
一致性哈希算法现在主要用于分布式系统中负载均衡,比如分布式 cache, 防止某些节点突然 down 掉,或者增加新节点时,大量的 cache 失效。具体介绍原理之类的文章非常多,比如: 这篇文章 ,在这里不再赘述。
Python 实现
这里有个关于一致性哈希算法 python 简单实现
# coding: utf-8
import md5
class HashRing(object):
def __init__(self, nodes=None, replicas=3):
""" nodes 是字符串的列表
replicas 表示有多少个虚拟节点
"""
self.replicas = replicas
self.ring = dict()
self._sorted_keys = [] # 有序的 hash node 队列
if nodes:
for node in nodes:
self.add_node(node)
def add_node(self, node):
"""将 node 节点加入到哈希环中
"""
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):
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):
"""根据 string_key 找到相应的 node 节点
"""
return self.get_node_pos(string_key)[0]
def get_node_pos(self, string_key):
"""根据 string key 找到 node ,如果没找到,则返回第一个节点
"""
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):
""" 获取 所有可用的 nodes 节点
"""
if not self.ring:
yield None, None
node, pos = self.get_node_pos(string_key)
# 先返回 string_key pos 节点后的 nodes
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):
"""生成 key
"""
m = md5.new()
m.update(key)
return long(m.hexdigest(), 16)
在 python shell 试下
In [22]: servers = ['192.168.0.1:6379',
'192.168.0.2:6379',
'192.168.0.3:6379'
]
In [23]: ring = HashRing(servers)
In [24]: server = ring.get_node('key1')
In [25]: server
Out[25]: '192.168.0.1:6379'
In [26]: server = ring.get_nodes('key1')
Out[27]: <generator object get_nodes at 0x1055cea00>
In [28]: server.next()
Out[28]: '192.168.0.1:6379'
In [29]: server.next()
Out[29]: '192.168.0.1:6379'
In [30]: server.next()
Out[30]: '192.168.0.2:6379'
hash 算法并不是保证绝对的平衡,如果 cache 较少的话,对象并不能被均匀的映射到 cache 上。
如果节点少的话, cache 对于每个 node 的负载肯定不均匀,所以代码中引入了 replicas 这个参数,也就是每个 node 能够映射多个 hash 节点,称为虚拟节点,均匀分布在环中,就能保持相对的平衡。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
上一篇: python 与 数据结构 第三章 线性表 (中)
下一篇: VSCode C++ 环境配置
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论