Java实现一致性hash算法

来源:互联网 发布:淘宝商城运营主管 编辑:程序博客网 时间:2024/04/23 23:21

    做个记录 防止老了忘掉    

   1)实现代码:

        思路:

           1)使用md5 加密节点名 得到byte[]  

           2)将byte[] 转换为整数  得到节点位置

           3)使用TreeMap 记录 所有的  节点名  和节点对应的位置(一个节点对应多个虚拟位置)节点位置为key 节点名为value

                     格式为:

        // 节点键值集合private TreeMap<Integer, String> nodes = new TreeMap<Integer, String>();

           4)使用 HashMap 记录 单个节点 和 其对应的所有虚假节点 (方便移除节点等其他操作)

            格式为:

       // 记录每个node 对应的 虚拟节点集合private Map<String, List<Integer>> nodeposition = new HashMap<String, List<Integer>>();

  2)完整代码:    

package yuan;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;import java.util.Set;import java.util.TreeMap;/** * 一致性hash 算法 *  * @author Yuan *  */public class ConsistentHash {// 节点键值集合private TreeMap<Integer, String> nodes = new TreeMap<Integer, String>();// 记录每个node 对应的 虚拟节点集合private Map<String, List<Integer>> nodeposition = new HashMap<String, List<Integer>>();// 一个节点的虚拟节点数private int nodeMul = 64;// publicpublic void addNode(String nodeName) {// 无虚拟节点写法// Integer position = MD5Utils.GetMD5CodeToInt(nodeName);// nodes.put(position, nodeName);// positions = nodes.keySet();// 引入虚拟节点List<Integer> nodeposi = new ArrayList<Integer>();for (int i = 0; i < nodeMul; i++) {Integer posi = MD5Utils.GetMD5CodeToInt(nodeName + "-" + i);nodeposi.add(posi);nodes.put(posi, nodeName);}nodeposition.put(nodeName, nodeposi);}public void removeNode(String nodeName) {List<Integer> nodepos = nodeposition.get(nodeName);for (Integer posi : nodepos) {nodes.remove(posi);}}public String lookup(String key) {Integer keyPos = MD5Utils.GetMD5CodeToInt(key);Set<Integer> positions =nodes.keySet();System.out.println("keyMd5Pos     " + keyPos);// 默认先获取第一个节点String nodeName = nodes.get(nodes.firstKey());for (Integer posi : positions) {if (keyPos <= posi) {nodeName = nodes.get(posi);break;}}return nodeName;}public void printNodes() {Set<Integer> positions = nodes.keySet();for (Integer posi : positions) {System.out.println(nodes.get(posi) + "      " + posi);}}}

package yuan;import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;/* * MD5 算法 */public class MD5Utils {public MD5Utils() {}// 返回形式只为数字private static int byteToInt(byte[] bByte) {int value = 0;// 由高位到低位for (int i = 0; i < 4; i++) {int shift = (4 - 1 - i) * 8;value += (bByte[i] & 0x000000FF) << shift;// 往高位游}return value;}public static int GetMD5CodeToInt(String strObj) {int result = 0;try {MessageDigest md = MessageDigest.getInstance("MD5");// md.digest() 该函数返回值为存放哈希值结果的byte数组result = byteToInt(md.digest(strObj.getBytes()));} catch (NoSuchAlgorithmException ex) {ex.printStackTrace();}return result;}}

 3)简单调用:

   

package yuan;public class Test {public static void main(String[] args) {ConsistentHash hash = new ConsistentHash();// 添加节点hash.addNode("a");hash.addNode("b");hash.addNode("c");// 打印所有的节点信息hash.printNodes();// 获取某个 key 的落点 即命中 那个节点String nodeName = hash.lookup("name");System.out.println(nodeName);System.out.println("==================================");// 移除节点hash.removeNode("a");hash.printNodes();}}

  

0 0
原创粉丝点击