ketama一致性hash算法(含java代码)_一致性Hash算法(KetamaHash)的c#实现

Consistent Hashing最大限度地抑制了hash键的重新分布。另外要取得比较好的负载均衡的效果,往往在服务器数量比较少的时候需要增加虚拟节点来保证服务器能均匀的分布在圆环上。因为使用一般的hash方法,服务器的映射地点的分布非常不均匀。使用虚拟节点的思想,为每个物理节点(服务器)在圆上分配100~200个点。这样就能抑制分布不均匀,最大限度地减小服务器增减时的缓存重新分布。用户数据映射在虚拟节点上,就表示用户数据真正存储位置是在该虚拟节点代表的实际物理服务器上。

public class KetamaNodeLocator

{

//原文中的JAVA类TreeMap实现了Comparator方法,这里我图省事,直接用了net下的SortedList,其中Comparer接口方法)

private SortedList ketamaNodes = new SortedList();

private HashAlgorithm hashAlg;

private int numReps = 160;

//此处参数与JAVA版中有区别,因为使用的静态方法,所以不再传递HashAlgorithm alg参数

public KetamaNodeLocator(List nodes, int nodeCopies)

{

ketamaNodes = new SortedList();

numReps = nodeCopies;

//对所有节点,生成nCopies个虚拟结点

foreach (string node in nodes)

{

//每四个虚拟结点为一组

for (int i = 0; i < numReps / 4; i++)

{

//getKeyForNode方法为这组虚拟结点得到惟一名称

byte[] digest = HashAlgorithm.computeMd5(node + i);

/** Md5是一个16字节长度的数组,将16字节的数组每四个字节一组,分别对应一个虚拟结点,这就是为什么上面把虚拟结点四个划分一组的原因*/

for (int h = 0; h < 4; h++)

{

long m = HashAlgorithm.hash(digest, h);

ketamaNodes[m] = node;

}

}

}

}

public string GetPrimary(string k)

{

byte[] digest = HashAlgorithm.computeMd5(k);

string rv = GetNodeForKey(HashAlgorithm.hash(digest, 0));

return rv;

}

string GetNodeForKey(long hash)

{

string rv;

long key = hash;

//如果找到这个节点,直接取节点,返回

if (!ketamaNodes.ContainsKey(key))

{

//得到大于当前key的那个子Map,然后从中取出第一个key,就是大于且离它最近的那个key 说明详见: http://www.javaeye.com/topic/684087

var tailMap = from coll in ketamaNodes

where coll.Key > hash

select new { coll.Key };

if (tailMap == null || tailMap.Count() == 0)

key = ketamaNodes.FirstOrDefault().Key;

else

key = tailMap.FirstOrDefault().Key;

}

rv = ketamaNodes[key];

return rv;

}

}

总结一致性哈希(Consistent Hashing)  http://www.iteye.com/topic/611976

Ketama一致性Hash算法学习(含Java代码) http://www.iteye.com/topic/684087

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值