jedis ShardedJedisPool的 HASH一致性算法(一)从String 的hashcode说起
jedis 的shard使用的是MurmurHash算法(一種非加密型哈希函數(shù)),該算法已在nginx,hadoop等開源上使用.
?
回顧String的hashcode()方法
//把char型數(shù)字轉(zhuǎn)換成的int型數(shù)字,因為它們的ASCII碼值恰好相差48char val[] = "111".toCharArray(); int hcode=0;for (int i = 0; i < val.length; i++) {hcode = 31 * hcode + val[i];}?例如業(yè)界最好的字符串hash是times33函數(shù),hash=33*hash+str.charAt(i),不過在JAVA里是把33換成31, 這個是K&R給出的函數(shù)
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,是因為它是一個奇素數(shù)。如果乘數(shù)是偶數(shù),因為與2相乘等價于移位運(yùn)算,并且乘法溢出的話,信息就會丟失。使用素數(shù)的好處并不是很明顯,但習(xí)慣上都是用素數(shù)來計算散列結(jié)果。31有個很好的特性,即用移位和減法來代替乘法,可以得到更好的性能:31*1==(i<<5)-i)。現(xiàn)代VM可以自動完成這個優(yōu)化。
不過……,有人指出這個答案是部分錯誤(The partially wrong answer)在"why do hash functions use prime number" 文章中指真正選擇31的原因是31是質(zhì)數(shù),不是因為它是奇數(shù)(is because it is prime-not because it is odd.)質(zhì)數(shù)是不能被其他數(shù)整除。
為什么采用質(zhì)數(shù)
?
?
?
?
轉(zhuǎn)載于:https://www.cnblogs.com/treeliang/p/3615729.html
《新程序員》:云原生和全面數(shù)字化實踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀總結(jié)
以上是生活随笔為你收集整理的jedis ShardedJedisPool的 HASH一致性算法(一)从String 的hashcode说起的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 变更AD计算机名称和IP地址
- 下一篇: 实例介绍,如何在开发中将各层日志归类输出