一致性哈希在分佈式系統中被不少的使用,好比說memcached就是使用一致性哈希來作的。學習一下這個一致性哈希算法。html
下面這篇博客利用圖解的形式,將一致性哈希算法講述的很是清楚:java
博客:http://blog.codinglabs.org/articles/consistent-hashing.htmlnode
參考代碼,下面我列出了java和c#的兩個代碼實現,能夠經過讀代碼更深入的去理解一下這個算法。 代碼:web
根據上述文章和代碼,仿照着寫了一個粗略版本的一致性哈希算法。算法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
|
public
delegate
int
HashFunction(
string
val);
public
class
ConsistentHash<T>
where
T :
class
{
//this value used for generate virtual nodes
private
int
_replica;
//Hash fuction used to calculate hash code base on a string
private
HashFunction getHashCode;
//image this as a big circle which store the node
private
SortedDictionary<
int
, T> circle =
new
SortedDictionary<
int
, T>();
public
ConsistentHash(HashFunction hashFunc, ICollection<T> nodes,
int
replicaNum = 100)
{
_replica = replicaNum;
getHashCode = hashFunc;
Init(nodes);
}
public
void
Add(T node)
{
for
(
int
i = 0; i < _replica; i++)
{
int
hash = getHashCode(node.GetHashCode().ToString() + i);
circle[hash] = node;
}
}
public
void
Remove(T node)
{
for
(
int
i = 0; i < _replica; i++)
{
int
hash = getHashCode(node.GetHashCode().ToString() + i);
circle.Remove(hash);
}
}
public
T GetNode(
object
key)
{
if
(key ==
null
)
return
null
;
int
hashcode = getHashCode(key.GetHashCode().ToString());
int
firstNode = GetFirst(circle.Keys.ToArray() , hashcode);
return
circle[firstNode];
}
/// <summary>
/// use binary search to search the first value in keys array
/// which bigger than hashcode
/// if not exist return first key in keys array
/// </summary>
/// <param name="keys">key array</param>
/// <param name="hashcode"></param>
/// <returns></returns>
private
int
GetFirst(
int
[] keys,
int
hashcode)
{
int
beg = 0, end = keys.Length - 1;
circle.Keys.CopyTo(keys, keys.Length);
if
(hashcode < keys[beg] || hashcode > keys[end])
return
keys[0];
while
(end > beg)
{
int
mid = (end + beg) / 2;
if
(keys[mid] >= hashcode)
end = mid;
else
beg = mid;
}
return
keys[end];
}
private
void
Init(ICollection<T> nodes)
{
foreach
(T node
in
nodes)
{
Add(node);
}
}
}
|