写点什么

架构师 Week5 作业

用户头像
lggl
关注
发布于: 2020 年 11 月 19 日



  1. 用你熟悉的编程语言实现一致性 hash 算法。

  2. 编写测试用例测试这个算法,测试 100 万 KV 数据,10 个服务器节点的情况下,计算这些 KV 数据在服务器上分布数量的标准差,以评估算法的存储负载不均衡性。



实现hash一致性算法如下:

import datetime
import random
import string
import numpy as np
# 随机生成num长度的字符串,用于测试
def ran_str(num):
salt = ''.join(random.sample(string.ascii_letters + string.digits, num))
return salt
class 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()



评估结果:



用户头像

lggl

关注

还未添加个人签名 2018.08.28 加入

还未添加个人简介

评论

发布
暂无评论
架构师Week5作业