我想在多个服务器之间分发文件,并且只需很少的开销就可以使用它们。所以我在考虑以下天真的算法:
假设每个文件都有唯一的ID号:120151
我正在考虑使用modulo (%)
运算符对文件进行分段。如果我事先知道服务器的数量,这是有效的:
有2台服务器(代表n台服务器)的示例:
server 1 : ID % 2 = 0 (contains even IDs)
server 2 : ID % 2 = 1 (contains odd IDs)
然而,当我需要扩展它并添加更多服务器时,我将不得不重新洗牌文件以遵守新的算法规则,我们不希望这样。
示例:
假设我将服务器3添加到混音中,因为我无法处理负载。服务器3将包含符合以下条件的文件:
server 3 : ID%3 = 2
步骤1是从服务器1和服务器2移动文件ID%3 = 2
。
但是,我必须在服务器1和服务器2之间移动一些文件,以便发生以下情况:
server 1 : ID%3 = 0
server 2 : ID%3 = 1
实现这一目标的最佳方法是什么?
答案 0 :(得分:3)
我的方法是使用一致的散列。来自维基百科:
一致哈希是一种特殊的哈希,当哈希时 调整表的大小并使用一致的散列,只需要K / n键 平均重新映射,其中K是键的数量,n是 插槽数量。
一般的想法是:
server_id
server_id = SHA(node_name)
。 file_id = SHA(ID)
,其中ID
在您的示例中给出。 server_id > file_id
(开始选择最小的server_id)。 注意:只要对服务器和文件使用相同的哈希函数,就可以使用生成均匀分布哈希的任何哈希函数。
这样,您可以保持O(1)访问权限,并且添加/删除是直接的,不需要重新调整所有文件:
a)添加新服务器,新节点从环上的下一个节点获取所有文件,其中ID低于新服务器
b)删除服务器,将其所有文件提供给环上的下一个节点
汤姆怀特的graphically illustrated overview更详细地解释。
答案 1 :(得分:1)
总结您的要求:
添加第3台服务器时的策略(x是文件的ID):
x%6 Old New
0 0 0
1 1 1
2 0 --> 2
3 1 --> 0
4 0 --> 1
5 1 --> 2
替代策略:
x%6 Old New
0 0 0
1 1 1
2 0 0
3 1 1
4 0 --> 2
5 1 --> 2
要在更改后找到服务器:
0: x%6 in [0,2]
1: x%6 in [1,3]
2: x%6 in [4,5]
添加第4台服务器:
x%12 Old New
0 0 0
1 1 1
2 0 0
3 1 1
4 2 2
5 2 2
6 0 0
7 1 1
8 0 --> 3
9 1 --> 3
10 2 2
11 2 --> 3
要在更改后找到服务器:
0: x%12 in [0,2, 6]
1: x%12 in [1,3, 7]
2: x%12 in [4,5,10]
3: x%12 in [8,9,11]
添加服务器时,您始终可以构建一个新功能(实际上是几个替代功能)。 n个服务器的除数值等于lcm(1,2,...,n),所以it grows very fast。
请注意,您没有提及是否删除了文件,以及您是否打算处理该文件。