论坛首页 综合技术论坛

Ketama一致性Hash算法(含Java代码)

浏览 40740 次
精华帖 (11) :: 良好帖 (0) :: 新手帖 (4) :: 隐藏帖 (0)
作者 正文
   发表时间:2010-10-29  
pandonix 写道
呵呵,就是因为Long型实现了Comparator接口。
-------
难道Integer就没有实现Comparator接口了么?

呀,被挑出来了,厉害。上面说过,这个模型是由TreeMap搭起来的,TreeMap需要它的key必须实现Comparator接口。
从算法实现上看,它的确应当选择Integer,而不是Long。
每个md5是16个字节,四个一组划分,这样每组四个字节。将一组四个字节从高字节到低字节依次移位,这四个字节就重新组成Integer,但是算法将它提升到了long型,这里的Long型只有低四字节有值,高四字节全是0。附件代码中有个方法HashAlgorithm.hash(),也是选择了md5的低四位组成一个Integer,又把它提升到Long了,用于从TreeMap中选择合适的虚拟节点。
你的疑问很对的。
我查看了Spy-Memcached client,由一个key去选择合适虚拟节点时它有这样的代码:
case KETAMA_HASH:
	byte[] bKey=computeMd5(k);
	rv = ((long) (bKey[3] & 0xFF) << 24)
		| ((long) (bKey[2] & 0xFF) << 16)
		| ((long) (bKey[1] & 0xFF) << 8)
		| (bKey[0] & 0xFF);
break;

这里可以看出,只是将Integer提升到Long了。至于是否有其它考量,暂时还看不出来。
0 请登录后投票
   发表时间:2010-12-08  
langyu 写道
pandonix 写道
呵呵,就是因为Long型实现了Comparator接口。
-------
难道Integer就没有实现Comparator接口了么?

呀,被挑出来了,厉害。上面说过,这个模型是由TreeMap搭起来的,TreeMap需要它的key必须实现Comparator接口。
从算法实现上看,它的确应当选择Integer,而不是Long。
每个md5是16个字节,四个一组划分,这样每组四个字节。将一组四个字节从高字节到低字节依次移位,这四个字节就重新组成Integer,但是算法将它提升到了long型,这里的Long型只有低四字节有值,高四字节全是0。附件代码中有个方法HashAlgorithm.hash(),也是选择了md5的低四位组成一个Integer,又把它提升到Long了,用于从TreeMap中选择合适的虚拟节点。
你的疑问很对的。
我查看了Spy-Memcached client,由一个key去选择合适虚拟节点时它有这样的代码:
case KETAMA_HASH:
	byte[] bKey=computeMd5(k);
	rv = ((long) (bKey[3] & 0xFF) << 24)
		| ((long) (bKey[2] & 0xFF) << 16)
		| ((long) (bKey[1] & 0xFF) << 8)
		| (bKey[0] & 0xFF);
break;

这里可以看出,只是将Integer提升到Long了。至于是否有其它考量,暂时还看不出来。

用long不用integer是为了避免出现负数值。
0 请登录后投票
   发表时间:2010-12-08  
flynofry 写道
用long不用integer是为了避免出现负数值。

最高字节是这样生成的:
bKey[3] & 0xFF) << 24
,&后它的最高符号位是0,不会出现负数

0 请登录后投票
   发表时间:2010-12-16  
langyu:
   代码中Node类是在哪里呢?
0 请登录后投票
   发表时间:2010-12-17  
capaccino 写道
langyu:
   代码中Node类是在哪里呢?

不好意思哈,主要是让大家看算法实现呢,就把Node类忽略了。它大致如此:
public class Node {

	private String nodeName;
	
	Node(String name) {
		this.nodeName = name;
	}
	
	public String getName() {
		return this.nodeName;
	}
	
	public String toString() {
		return this.nodeName;
	}
	
	public boolean equals(Object obj) {
		if (obj instanceof Node) {
			return ((Node) obj).nodeName.equals(this.nodeName);
		}
		
		return false;
	}
	
	public int hashCode() {
		return this.nodeName.hashCode();
	}
}

0 请登录后投票
   发表时间:2010-12-22  
前提是我用在了数据库中,有个问题想问下,如果由于机房拆迁,你的node更换了IP地址,此时所有隐射都会改变,除了在隐射一次新地址和老地址之外,还有别的方法么
0 请登录后投票
   发表时间:2011-04-19  
楼主 给力
可以参考下了 真需要
0 请登录后投票
   发表时间:2011-04-19  
楼主,为什么测试用的key不用ketama hash算法处理呢?
0 请登录后投票
   发表时间:2011-04-20  
wanrue 写道
楼主,为什么测试用的key不用ketama hash算法处理呢?

Ketama 算法是产生众多虚拟节点的过程,以便key在选择时可以更随机。而key的目的单纯,只是为了选择某个虚拟节点,除了hash就不需要更多的处理。不知道这样解释可能解决你的疑惑?
0 请登录后投票
   发表时间:2011-04-20  
我有一个问题: 虚拟节点的多少应该如何设置呢!或者说和物理节点的多少有什么倍数关系吗
0 请登录后投票
论坛首页 综合技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics