一致性hash算法
2016-03-11 22:22
399 查看
一致性hash算法
一、算法介绍
在1997年由麻省理工学院提出的一种分布式哈希(DHT)实现算法,设计目标是为了解决因特网中的热点(Hot spot)问题
① 解决因特网中的热点问题;
② 基于分布式一致性算法,实现P2P架构;(无单点)
1.1 普通hash算法
hash(object)%N算法;
如果有机器添加或者删除后,原有的数据就会找不到了;
1.2 分布式一致性hash算法
环形空间,[ 0 , 2^32 - 1];(将这些数字头尾相连,形成一个闭环)
例如:
Hash(NODE1) = KEY1; Hash(NODE2) = KEY2; Hash(NODE3) = KEY3;
将object1、object2、object3、object4四个对象通过特定的Hash函数计算出对应的key值
Hash(object1) = key1; Hash(object2) = key2; Hash(object3) = key3; Hash(object4) = key4;这样按顺时针转动object1存储到了NODE1中; object3存储到了NODE2中; object2、object4存储到了NODE3中; 在这样的部署环境中,hash环是不会变更的,因此,通过算出对象的hash值就能快速的定位到对应的机器中,这样就能找到对象真正的存储位置了;
二、算法实现
2.1 ketama算法
/** * 1.对所有50个节点,生成160个虚拟结点; * 2.每四个虚拟结点为一组; * 3.Md5是一个16字节长度的数组,将16字节的数组每四个字节一组,分别对应一个虚拟结点,这就是为什么上面把虚拟结点四个划分一组的原因; * 4.对于每四个字节,组成一个long值数值,做为这个虚拟节点的在环中的惟一key; * * @param nodes * @param algorithm * @param virtualNodeCount */ public KetamaNodeLocator(List<Node> nodes, HashAlgorithm algorithm, int virtualNodeCount) { this.virtualNodeCount = virtualNodeCount; ketamaNodes = new TreeMap<Long, Node>(); hashAlgorithm = algorithm; //构造一致性hash环 for (Node node : nodes) { for (int i = 0; i < this.virtualNodeCount / 4; i++) { byte[] digest = hashAlgorithm.computeMd5(node.getName() + i); for (int h = 0; h < 4; h++) { long m = hashAlgorithm.hash(digest, h); ketamaNodes.put(m, node); } } } } /** * 返回hash对应的节点 * * @param hash * @return */ private Node getNodeForKey(long hash) { final Node node; Long key = hash; if (!ketamaNodes.containsKey(key)) { SortedMap<Long, Node> tailMap = ketamaNodes.tailMap(key); if (tailMap.isEmpty()) { key = ketamaNodes.firstKey(); } else { key = tailMap.firstKey(); } } node = ketamaNodes.get(key); return node; }
2.2 节点node1,划分为160个虚拟节点
2.3 节点node2,划分为160个虚拟节点
2.4 获取key对应的节点
① key="mengka_bb";
② 获取16位的hash值,[ 0~4 , 5~8 , 9~12 , 13~16 ]
[ 0~4 ] = k1 (long值,2^32范围内)
③ treeMap.get(k1);
④ 返回key对应存储数据的node节点;
/** * 节点个数 */ private static final Integer NODE_COUNT = 50; /** * 虚拟节点的个数 */ private static final Integer VIRTUAL_NODE_COUNT = 160; public static void main(String[] args){ String key = "mengka_bb"; //返回node列表,[node1,node50] List<Node> allNodes = NodeUtil.getNodes(NODE_COUNT); //获取ketamaLocator KetamaNodeLocator ketamaLocator = new KetamaNodeLocator(allNodes, HashAlgorithm.KETAMA_HASH, VIRTUAL_NODE_COUNT); //返回key对应的节点 Node node = ketamaLocator.getPrimary(key); if (node != null) { System.out.println("-----------, node = "+node.getName()); } }
阅读更多
相关文章推荐
- [速成]了解一致性hash算法
- 一致性HASH算法详解
- [转]一致性hash算法 - consistent hashing
- 编程艺术第十六~第二十章:全排列/跳台阶/奇偶调序,及一致性hash算法
- 编程艺术第十六~第二十章:全排列/跳台阶/奇偶调序/第一个只出现一次的字符,及一致性hash算法
- 一致性hash算法(consistent hashing)
- 基于一致性hash算法 C++语言的实现详解
- 一致性hash算法(二)
- (转) 一致性Hash算法在Memcached中的应用
- memcache分布式 [一致性hash算法] 的php实现
- 对一致性Hash算法,Java代码实现的深入研究
- 一致性Hash算法
- 一致性hash算法
- 一致性HASH算法详解
- 编程艺术第十六~第二十章:全排列/跳台阶/奇偶调序,及一致性Hash算法
- 一致性Hash算法(转)
- 【C#|.NET】跳出一致性Hash算法 打造更高效的分布式缓存
- 一致性hash算法 - consistent hashing
- 一致性hash算法(JAVA)
- 源码分析Memcached-Java-Client一致性hash算法