博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
一致性哈希
阅读量:5763 次
发布时间:2019-06-18

本文共 2708 字,大约阅读时间需要 9 分钟。

hot3.png

一致性哈希已经是被写烂了的题目了,所以我这也不想再赘述他的原理。这个随便一搜一大把。下面给出一个我的简单实现,需要用到的时候改改就能用了。需要注意的地方以及思路都在代码里了。
package me.elf.consistent.hashing;import org.apache.commons.codec.digest.DigestUtils;import java.util.*;/** * 一致性hash路由算法 * * @author laichendong * @since 14-6-10 */public class ConsistentHashing
{ /** * 节点集合 */ private Set
nodes = new HashSet
(); /** * 节点环,用treeMap模拟实现 */ private TreeMap
ring = new TreeMap
(); public ConsistentHashing() { } public ConsistentHashing(Set
nodes) { if (nodes == null) { throw new NullPointerException("nodes must not be null"); } this.nodes = nodes; for (T node : nodes) { ring.put(hash(node), node); } } /** * 添加节点 * * @param node 节点 * @return 节点添加是否成功 */ public boolean addNode(T node) { ring.put(hash(node), node); return nodes.add(node); } /** * 移除节点 * * @param node 节点 * @return 节点移除是否成功 */ public boolean removeNode(T node) { ring.remove(hash(node)); return nodes.remove(node); } /** * 计算路由 * * @param key 需要计算路由的key * @return key落到的节点上 */ public T route(Object key) { int h = hash(key); // 找到离key最近的节点 Map.Entry
entry = ring.floorEntry(h); if (entry == null) { // 如果没有找到,可能时到最前面了,返回最后一个节点,形成环 entry = ring.lastEntry(); } if (entry == null) { return null; } else { return entry.getValue(); } } /** * 采用的hash算法 * 这个可以根据需要进行修改 * * @param key hash key * @return hash 值 */ public static int hash(Object key) { // 这个md5挺重要的,可以将相似的key的hash值打散,使节点在环上散布开来,当然,也可以使用其他方法 int h = DigestUtils.md5Hex(key.toString()).hashCode(); // 然后再copy了以下HashMap的hash算法~~ h ^= (h >>> 20) ^ (h >>> 12); return h ^ (h >>> 7) ^ (h >>> 4); } /** * 测试 */ public static void main(String[] args) { // 初始化 ConsistentHashing
consistentHashing = new ConsistentHashing
(); consistentHashing.addNode("node0"); consistentHashing.addNode("node1"); consistentHashing.addNode("node2"); consistentHashing.addNode("node3"); // 对每一个key进行路由计算 看看分布情况 String[] keys = {"key0", "key1", "key2", "key3", "key4", "key5", "key6", "key7"}; for (String key : keys) { System.out.println(key + " -> " + consistentHashing.route(key)); } System.out.println("================="); // 减掉一个节点,再对每一个key进行路由计算 看漂移结果 consistentHashing.removeNode("node3"); for (String key : keys) { System.out.println(key + " -> " + consistentHashing.route(key)); } }}
输出是这样的:
key0 -> node1key1 -> node1key2 -> node3key3 -> node1key4 -> node2key5 -> node1key6 -> node1key7 -> node3=================key0 -> node1key1 -> node1key2 -> node2key3 -> node1key4 -> node2key5 -> node1key6 -> node1key7 -> node2
可以看到,在移除了节点3之后,原来落到节点3上的key都落到了节点2。而原来落到其他节点的key都还在原地。满足了“一致性”的要求。

转载于:https://my.oschina.net/laichendong/blog/283801

你可能感兴趣的文章
C++ 模板学习 函数模板、类模板、迭代器模板
查看>>
C#编程(二十七)----------创建泛型类
查看>>
2806 红与黑 个人博客:doubleq.win
查看>>
迅雷中几个概念
查看>>
DDD架构Sample
查看>>
数据恢复:AMDU数据抽取恢复
查看>>
jstl fn:replace替换换行符
查看>>
安卓getSystemService
查看>>
qsort函数以及sort函数使用方法
查看>>
转python版本的curl工具pycurl学习
查看>>
关于跨平台的理解以及Unity的由来--Unity学习
查看>>
打印杨辉三角 --JS
查看>>
Graph Automata Player
查看>>
MAC COCOA一个简单的多线程程序
查看>>
Maven出现User setting file does not exist ...\.m2\setting.xml的问题解决(同时也解决用户.m2目录下无setting.xml文件)...
查看>>
Maven生成项目文档
查看>>
最近一次登录记录
查看>>
nodeJS中的包
查看>>
Spring基于构造函数的依赖注入(DI)
查看>>
Windows 驱动开发 - 7
查看>>