zoukankan      html  css  js  c++  java
  • 哈希

    hash取模算法

    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("192.168.1.1");
        list.add("192.168.1.2");
        list.add("192.168.1.3");
    
        //String topic = "aaaaaaaaaaaaaaaa";
        //String topic = "bbbbbbbbbbbbbbbb";
        String topic = "cccccccccccccccc";
        int abs = Math.abs(topic.hashCode());
        int result = abs % list.size();
        System.out.println(list.get(result));
    }

    一致性hash算法

    import java.util.LinkedList;
    import java.util.List;
    import java.util.SortedMap;
    import java.util.TreeMap;
    
    /**
     * @author zfang
     * @date 2021/9/9 16:12
     */
    public class ConsistencyHashing {
        // 虚拟节点的个数
        private static final int VIRTUAL_NUM = 5;
        // 虚拟节点分配,key是hash值,value是虚拟节点服务器名称
        private static final SortedMap<Integer, String> shards = new TreeMap<>();
        // 真实节点列表
        private static final List<String> realNodes = new LinkedList<>();
        //模拟初始服务器
        private static final String[] servers = {"192.168.1.1", "192.168.1.2", "192.168.1.3", "192.168.1.5", "192.168.1.6"};
    
        static {
            for (String server : servers) {
                realNodes.add(server);
                System.out.println("真实节点[" + server + "] 被添加");
                for (int i = 0; i < VIRTUAL_NUM; i++) {
                    String virtualNode = server + "&&VN" + i;
                    int hash = getHash(virtualNode);
                    shards.put(hash, virtualNode);
                    System.out.println("虚拟节点[" + virtualNode + "] hash:" + hash + ",被添加");
                }
            }
        }
    
    
        /**
         * 获取被分配的节点名
         *
         * @param node
         * @return
         */
        public static String getServer(String node) {
            int hash = getHash(node);
            Integer key = null;
            SortedMap<Integer, String> subMap = shards.tailMap(hash);
            if (subMap.isEmpty()) {
                key = shards.lastKey();
            } else {
                key = subMap.firstKey();
            }
            String virtualNode = shards.get(key);
            return virtualNode.substring(0, virtualNode.indexOf("&&"));
        }
    
    
        /**
         * 添加节点
         *
         * @param node
         */
        public static void addNode(String node) {
            if (!realNodes.contains(node)) {
                realNodes.add(node);
                System.out.println("真实节点[" + node + "] 上线添加");
                for (int i = 0; i < VIRTUAL_NUM; i++) {
                    String virtualNode = node + "&&VN" + i;
                    int hash = getHash(virtualNode);
                    shards.put(hash, virtualNode);
                    System.out.println("虚拟节点[" + virtualNode + "] hash:" + hash + ",被添加");
                }
            }
        }
    
    
        /**
         * 删除节点
         *
         * @param node
         */
        public static void delNode(String node) {
            if (realNodes.contains(node)) {
                realNodes.remove(node);
                System.out.println("真实节点[" + node + "] 下线移除");
                for (int i = 0; i < VIRTUAL_NUM; i++) {
                    String virtualNode = node + "&&VN" + i;
                    int hash = getHash(virtualNode);
                    shards.remove(hash);
                    System.out.println("虚拟节点[" + virtualNode + "] hash:" + hash + ",被移除");
                }
            }
        }
    
        /**
         * FNV1_32_HASH算法
         */
        private static int getHash(String str) {
            final int p = 16777619;
            int hash = (int) 2166136261L;
            for (int i = 0; i < str.length(); i++)
                hash = (hash ^ str.charAt(i)) * p;
            hash += hash << 13;
            hash ^= hash >> 7;
            hash += hash << 3;
            hash ^= hash >> 17;
            hash += hash << 5;
            // 如果算出来的值为负数则取其绝对值
            if (hash < 0)
                hash = Math.abs(hash);
            return hash;
        }
    
        public static void main(String[] args) {
    
            //模拟客户端的请求
            String[] nodes = {"127.0.0.1", "10.9.3.253", "192.168.10.1"};
    
            for (String node : nodes) {
                System.out.println("[" + node + "]的hash值为" + getHash(node) + ", 被路由到结点[" + getServer(node) + "]");
            }
    
            // 添加一个节点(模拟服务器上线)
            addNode("192.168.1.7");
            // 删除一个节点(模拟服务器下线)
            delNode("192.168.1.2");
    
            for (String node : nodes) {
                System.out.println("[" + node + "]的hash值为" + getHash(node) + ", 被路由到结点[" + getServer(node) + "]");
            }
        }
    }
  • 相关阅读:
    PHP的轻量消息队列php-resque使用说明
    Laravel 5.1 事件、事件监听的简单应用
    Ubuntu常用命令
    Mysql 主从数据库
    MySQL日志
    两条比较实用的mysql导入导出命令
    Linux下mysql定时自动备份并FTP到远程脚本
    观察者模式范例
    devexpress gridControl1导出为pdf文件时出现 中文乱码的解决方案
    devexpress打印gridControl
  • 原文地址:https://www.cnblogs.com/xiaomaoyvtou/p/15247389.html
Copyright © 2011-2022 走看看