一致性哈希算法学习及JAVA代码实现分析

1,对于待存储的海量数据,如何将它们分配到各个机器中去?---数据分片与路由

当数据量很大时,通过改善单机硬件资源的纵向扩充方式来存储数据变得越来越不适用,而通过增加机器数目来获得水平横向扩展的方式则越来越流行。因此,就有个问题,如何将这些海量的数据分配到各个机器中?数据分布到各个机器存储之后,又如何进行查找?这里主要记录一致性Hash算法如何将数据分配到各个机器中去。

2,衡量一致性哈希算法好处的四个标准:

①平衡性:平衡性是指哈希的结果能够尽可能分布到所有的缓冲中去,这样可以使得所有的缓冲空间都得到利用。②单调性:单调性是指如果已经有一些数据通过哈希分配到了相应的机器上,又有新的机器加入到系统中。哈希的结果应能够保证原有已分配的内容可以被映射到原有的或者新的机器中去,而不会被映射到旧的机器集合中的其他机器上。

这里再解释一下:就是原有的数据要么还是呆在它所在的机器上不动,要么被迁移到新的机器上,而不会迁移到旧的其他机器上。

③分散性④负载:参考这里

 

3,一致性哈希的原理:

由于一般的哈希函数返回一个int(32bit)型的hashCode。因此,可以将该哈希函数能够返回的hashCode表示成一个范围为0---(2^32)-1 环。

将机器的标识(如:IP地址)作为哈希函数的Key映射到环上。如:

hash(Node1) =Key1      hash(Node2) = Key2,借用一张图如下:

一致性哈希算法学习及JAVA代码实现分析

 同样,数据也通过相同的哈希函数映射到环上。这样,按照顺时针方向,数据存放在它所在的顺时针方向上的那个机器上。这就是一致性哈希算法分配数据的方式!

4,JAVA实现一致性哈希算法的代码分析:

❶设计哈希函数

这里采用了MD5算法,主要是用来保证平衡性,即能够将机器均衡地映射到环上。貌似用Jdk中String类的hashCode并不能很好的保证平衡性。

1 import java.security.MessageDigest; 2 import java.security.NoSuchAlgorithmException; 3 4 /* 5 * 实现一致性哈希算法中使用的哈希函数,使用MD5算法来保证一致性哈希的平衡性 6 */ 7 public class HashFunction { 8 private MessageDigest md5 = null; 9 10 public long hash(String key) { 11 if (md5 == null) { 12 try { 13 md5 = MessageDigest.getInstance("MD5"); 14 } catch (NoSuchAlgorithmException e) { 15 throw new IllegalStateException("no md5 algrithm found"); 16 } 17 } 18 19 md5.reset(); 20 md5.update(key.getBytes()); 21 byte[] bKey = md5.digest(); 22 //具体的哈希函数实现细节--每个字节 & 0xFF 再移位 23 long result = ((long) (bKey[3] & 0xFF) << 24) 24 | ((long) (bKey[2] & 0xFF) << 16 25 | ((long) (bKey[1] & 0xFF) << 8) | (long) (bKey[0] & 0xFF)); 26 return result & 0xffffffffL; 27 } 28 }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zzfsdy.html