我正在尝试编写代码,以便为每个哈希生成唯一的分数。基本上,如果他们要求相同的内容,我想将同一个节点返回给多个用户。
这是我的代码:
import hashlib
#define nodes
nodes = ["192.168.20.2", "192.168.20.3", "192.168.20.4", "192.168.20.5", "192.168.20.6", "192.168.20.7"]
def selectNodes(clientIP,request):
hash_list = []
for node_ips in nodes:
score = 0
ready_hash = str(request) + str(node_ips)
m = hashlib.md5((ready_hash).encode("utf-8"))
hashed_node = m.hexdigest()
for char in hashed_node:
score += int(char, 16)
hash_list.append((node_ips, score))
sorted_by_score = sorted(hash_list, key=lambda tup:tup[1], reverse=True)
(node_ip, score) = sorted_by_score[0]
return (node_ip, sorted_by_score)
如果我打电话:
selectNodes("10.10.10.20", "movie1")
假设它为movie1返回192.168.20.2。下次相同或其他用户请求“ movie1”时。它应该返回相同的节点192.168.20.2。我不想将{电影移动到节点}。它应该在运行时进行计算并给出正确的结果。
上面的代码对我来说很好用,但是有时节点的计算分数变得相同。
我该怎么做,以便为每个哈希计算唯一的分数。
始终向同一请求分配相同节点的解决方案是仅使用请求的哈希值(以列表的长度为模)来索引节点列表。
#define nodes
nodes = ["192.168.20.2", "192.168.20.3", "192.168.20.4", "192.168.20.5", "192.168.20.6", "192.168.20.7"]
def selectNodes(request):
return nodes[hash(str(request)) % len(nodes)]
此解决方案不依赖于节点顺序,但是如果将新节点添加到列表中,则可能会更改输出。
import random
def compute_hash(a, b):
return hash("%s:%s" % (a, b))
def select_node(request, nodes):
hashes = [
[compute_hash(request, x), x]
for x in nodes
]
return max(hashes)[-1]
def test_select_node():
nodes = [
"192.168.20.2",
"192.168.20.3",
"192.168.20.4",
"192.168.20.5",
"192.168.20.6",
"192.168.20.7",
]
request = "movie1"
# remember the first result
node = select_node(request, nodes)
for _ in range(3):
# the order changes, but the result remains the same
random.shuffle(nodes)
assert select_node(request, nodes) == node