架构师 Week5 作业
发布于: 2020 年 11 月 19 日
用你熟悉的编程语言实现一致性 hash 算法。
编写测试用例测试这个算法,测试 100 万 KV 数据,10 个服务器节点的情况下,计算这些 KV 数据在服务器上分布数量的标准差,以评估算法的存储负载不均衡性。
实现hash一致性算法如下:
import datetimeimport randomimport stringimport numpy as np# 随机生成num长度的字符串,用于测试def ran_str(num): salt = ''.join(random.sample(string.ascii_letters + string.digits, num)) return saltclass HashManager: # 物理节点 node_ip_list = [] # 虚拟节点到物理节点映射 virtual_to_node_map = {} # 排序好的虚拟节点 circle_sort_list = [] # 统计每个物理节点上插入的数据数量 node_insert_counts_map = {} def __init__(self, node_ip_list, virtual_num=32): self.virtual_num = virtual_num self.node_ip_list = node_ip_list for node_ip in node_ip_list: for index in range (virtual_num): node_ip_key = node_ip + "#" + str(index) # 在环上取值,用于虚节点 key = abs(hash(node_ip_key)) % (2 ** 32) self.circle_sort_list.append(key) # 建立虚节点和物理节点映射 self.virtual_to_node_map[key] = node_ip # 初始化物理节点的统计个数 self.node_insert_counts_map[node_ip] = 0 # 虚节点排序 self.circle_sort_list.sort() def add_node(self, ip): if ip in self.node_ip_list: return for index in range(self.virtual_num): node_ip_key = ip + "#" + str(index) # 在环上取值,用于虚节点 key = abs(hash(node_ip_key)) % (2 ** 32) self.circle_sort_list.append(key) # 建立虚节点和物理节点映射 self.virtual_to_node_map[key] = ip # 初始化物理节点的统计个数 self.node_insert_counts_map[ip] = 0 def del_node(self, ip): if ip in self.node_ip_list is False: return self.node_ip_list.remove(ip) for index in range(self.virtual_num): node_ip_key = ip + "#" + str(index) # 在环上取值,用于虚节点 key = abs(hash(node_ip_key)) % (2 ** 32) self.circle_sort_list.remove(key) self.virtual_to_node_map.pop(key) self.node_insert_counts_map.pop(ip) def insert(self, str_key): # 计算带插入数据的hash值 tmp = abs(hash(str_key)) % (2 ** 32) # 查找环上最小的落点 for num in self.circle_sort_list: if tmp <= num: self.node_insert_counts_map[self.virtual_to_node_map[num]] += 1 return # 找不到,意味着属于第0个落点 self.node_insert_counts_map[self.virtual_to_node_map[self.circle_sort_list[0]]] += 1 def analyze(self): count = 0 array_count = [] for _, ip in self.virtual_to_node_map.items(): array_count.append(self.node_insert_counts_map[ip]) print("数据落盘情况:") for ip, value in self.node_insert_counts_map.items(): count += value print(ip + ":" + str(value)) print("插入数据总体个数: " + str(count)) print("标准差:" + str(np.std(array_count)))if __name__ == '__main__': server_ip_list = ['10.1.1.10', '10.1.1.11', '10.1.1.12', '10.1.1.13', '10.1.1.14', '10.1.1.15', '10.1.1.16', '10.1.1.17', '10.1.1.18', '10.1.1.19'] # 10个服务器ip,每个服务器150个虚拟节点 hashManager = HashManager(server_ip_list, 150) print('服务器数量:{0}, 虚拟节点数: {1}'.format(len(server_ip_list), 150)) start_time = datetime.datetime.now() for i in range(1000000): s = ran_str(random.randint(1, 16)) # print(s) hashManager.insert(s) over_time = datetime.datetime.now() print("插入数据耗时:{0}".format((over_time - start_time).total_seconds())) hashManager.analyze()
评估结果:
划线
评论
复制
发布于: 2020 年 11 月 19 日阅读数: 23
lggl
关注
还未添加个人签名 2018.08.28 加入
还未添加个人简介
评论