1
wee5 技术选型(一) 作业
发布于: 2020 年 11 月 22 日
5.6 第五周课后练习
作业一(2 选 1):
用你熟悉的编程语言实现一致性 hash 算法。
编写测试用例测试这个算法,测试 100 万 KV 数据,10 个服务器节点的情况下,计算这些 KV 数据在服务器上分布数量的标准差,以评估算法的存储负载不均衡性。
作业二:
根据当周学习情况,完成一篇学习总结
"""对一致性hash进行学习,构造没有vnode的hash,增加和删除节点以进行观察,会产生对应的雪崩效应"""from zlib import crc32 class conhashnorep(object): def __init__(self,nodes=None,replicas=5): """此处nodes代表需要初始化的node列表,为进行对比先提供虚拟节点副本数,ring是存储hash-node的字典,key是存储所有hash值的列表""" self.nodes=nodes self.replicas=replicas self.ring={} self._sorted_keys=[] self.add_nodes(nodes) def _add_node(self,node): for i in range(self.replicas): bnode="%s_vnode%s" % (node,i) bnode = bytes(bnode, encoding="utf8") nodehash = abs(crc32(bnode)) self.ring[nodehash] = node self._sorted_keys.append(nodehash) self._sorted_keys.sort() def add_nodes(self,nodes): if nodes: for node in nodes: self._add_node(node) def remove_nodes(self,nodes): """对于remove的操作,如果直接操作已经产生的ring字典,会比较麻烦,因为ring是{hashnode:node}的键值对形式, 直接处理涉及到字典直接查找值ring.values()/ring.keys(),以及通过值来remove(key)的操作,太麻烦""" if nodes: for node in nodes: for i in range(self.replicas): bnode = "%s_vnode%s" % (node, i) bnode = bytes(bnode, encoding="utf8") nodehash = abs(crc32(bnode)) del self.ring[nodehash] self._sorted_keys.remove(nodehash) def get_node(self,key): bkey=bytes(key,encoding="utf8") keyhash=abs(crc32(bkey)) i=0 for nodehash in self._sorted_keys: i += 1 if keyhash < nodehash: #print("%d Keyhash:%s Nodehash:%s" % (i,keyhash,nodehash)) return self.ring[nodehash] else: continue if i==len(self._sorted_keys): #print("None Keyhash:%s Nodehash:%s" % (keyhash,self._sorted_keys[0])) return self.ring[self._sorted_keys[0]] def count_server(self,number): '''server_list用于存放重复出现的server,server_counnt用于统计出现频数''' server_list = [] server_count = {} for i in range(number): kei = "key_%s" % i server = self.get_node(kei) server_list.append(server) for m in set(server_list): server_count[m] = server_list.count(m) '''根据字典的键进行排序,如果需要逆序则添加 reverse=True''' server_count=dict(sorted(server_count.items(), key=lambda e: e[1],reverse=True)) print("ServerCount:", server_count) ini_servers = [ '127.0.0.1:1', '127.0.0.1:2', '127.0.0.1:3', '127.0.0.1:4', #'127.0.0.1:7005',]h=conhashnorep(ini_servers)print(h.ring) """构建一些object来观察会分配到哪一个节点"""#for i in range(20):part_servers=['127.0.0.2:1','127.0.0.2:2']h.count_server(200)h.add_nodes(part_servers)h.count_server(200)h.remove_nodes(['127.0.0.1:1','127.0.0.1:2'])h.count_server(200)复制代码
由于代码功底不深厚,本周作业暂时为复制网络代码进行研究。(python 版本)
"""对一致性hash进行学习,构造没有vnode的hash,增加和删除节点以进行观察,会产生对应的雪崩效应"""from zlib import crc32# import memcached class conhashnorep(object): def __init__(self,nodes=None): """此处nodes代表需要初始化的node列表,为进行对比先提供虚拟节点副本数,ring是存储hash-node的字典,key是存储所有hash值的列表""" self.nodes=nodes self.ring={} self._sorted_keys=[] self.add_nodes(nodes) def _add_node(self,node): bnode=bytes(node,encoding="utf8") nodehash=abs(crc32(bnode)) self.ring[nodehash]=node self._sorted_keys.append(nodehash) self._sorted_keys.sort() def add_nodes(self,nodes): if nodes: for node in nodes: self._add_node(node) def remove_nodes(self,nodes): """对于remove的操作,如果直接操作已经产生的ring字典,会比较麻烦,因为ring是{hashnode:node}的键值对形式, 直接处理涉及到字典直接查找值ring.values()/ring.keys(),以及通过值来remove(key)的操作,太麻烦""" if nodes: for node in nodes: bnode = bytes(node, encoding="utf8") nodehash = abs(crc32(bnode)) del self.ring[nodehash] self._sorted_keys.remove(nodehash) def get_node(self,key): bkey=bytes(key,encoding="utf8") keyhash=abs(crc32(bkey)) i=0 for nodehash in self._sorted_keys: i += 1 if keyhash < nodehash: #print("%d Keyhash:%s Nodehash:%s" % (i,keyhash,nodehash)) return self.ring[nodehash] else: continue if i==len(self._sorted_keys): #print("None Keyhash:%s Nodehash:%s" % (keyhash,self._sorted_keys[0])) return self.ring[self._sorted_keys[0]] def count_server(self,number): '''server_list用于存放重复出现的server,server_counnt用于统计出现频数''' server_list = [] server_count = {} for i in range(number): kei = "key_%s" % i server = self.get_node(kei) server_list.append(server) for m in set(server_list): server_count[m] = server_list.count(m) '''根据字典的键进行排序,如果需要逆序则添加 reverse=True''' server_count=dict(sorted(server_count.items(), key=lambda e: e[0])) print("ServerCount:", server_count) ini_servers = [ '127.0.0.1:1', '127.0.0.1:2', '127.0.0.1:3', '127.0.0.1:4', #'127.0.0.1:7005',]h=conhashnorep(ini_servers)print(h.ring) """构建一些object来观察会分配到哪一个节点"""#for i in range(20):part_servers=['127.0.0.2:1','127.0.0.2:2']h.count_server(200)h.add_nodes(part_servers)h.count_server(200)h.remove_nodes(['127.0.0.1:1','127.0.0.1:2'])h.count_server(200)复制代码
划线
评论
复制
发布于: 2020 年 11 月 22 日阅读数: 24
杨斌
关注
还未添加个人签名 2020.03.17 加入
还未添加个人简介











评论 (1 条评论)