jedis ShardedJedisPool的 HASH一致性算法(一)从String 的hashcode说起

jedis 的shard使用的是MurmurHash算法(一种非加密哈希函数),该算法已在nginx,hadoop等开源上使用.

 

回顾String的hashcode()方法

//把char型数字转换成的int型数字,因为它们的ASCII码值恰好相差48
        char val[] = "111".toCharArray(); 
        int hcode=0;
        for (int i = 0; i < val.length; i++) {
            hcode = 31 * hcode + val[i];
        }

 例如业界最好的字符串hash是times33函数,hash=33*hash+str.charAt(i),不过在JAVA里是把33换成31, 这个是K&R给出的函数

s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]

在《Effective Java》这本书的第三章提到为什么使用31的原因
from Chapter 3, Item 9: Always override hashcode when you override equals, page 48

The value 31 was chosen because it is an odd prime. If it were even and the multiplication overflowed, information would be lost, as multiplication by 2 is equivalent to shifting. The advantage of using a prime is less clear, but it is traditional. A nice property of 31 is that the multiplication can be replaced by a shift and a subtraction for better performance: 31 * i == (i << 5) - i. Modern VMs do this sort of optimization automatically.

(之所以选择31,是因为它是一个奇素数。如果乘数是偶数,因为与2相乘等价于移位运算,并且乘法溢出的话,信息就会丢失。使用素数的好处并不是很明显,但习惯上都是用素数来计算散列结果。31有个很好的特性,即用移位和减法来代替乘法,可以得到更好的性能:31*1==(i<<5)-i)。现代VM可以自动完成这个优化。

不过……,有人指出这个答案是部分错误(The partially wrong answer)在"why do hash functions use prime number" 文章中指真正选择31的原因是31是质数,不是因为它是奇数(is because it is prime-not because it is odd.)质数是不能被其他数整除。

为什么采用质数

 

 

 

 

posted @ 2014-03-21 13:58  tree.liang  阅读(868)  评论(0编辑  收藏  举报