一致性Hash代码

关于一致性hash介绍

public class Instance {
    private String ip;
    private String port;

    public Instance(String ip, String port) {
        this.ip = ip;
        this.port = port;
    }

    public String getIp() {
        return ip;
    }

    public void setIp(String ip) {
        this.ip = ip;
    }

    public String getPort() {
        return port;
    }

    public void setPort(String port) {
        this.port = port;
    }
}

public interface LoadBalancer {
	/**
     *
     * @param instances zk拉取的服务地址列表
     * @param address 本地客户端的服务地址ip
     * @return 调用的远程服务器的ip+port
     */
    Instance select(List<Instance> instances , String address);
}

随机算法

public class RandomLoadBalancer implements LoadBalancer{
    @Override
    public Instance select(List<Instance> instances , String address) {
        return instances.get(new Random().nextInt(instances.size()));
    }
}

轮询算法

public class RoundRobinLoadBalancer implements LoadBalancer{
    private int index = 0;
    @Override
    public Instance select(List<Instance> instances , String address) {
        return index < instances.size() ? instances.get(index++) : instances.get(0);
    }
}

一致性hash算法
用于rpc项目中:
当客户端拉取到服务地址列表时进行一致性hash负载均衡实现
两个map进行映射
TreeMap(虚拟节点:真实节点的ip)
HashMap (真实节点的ip:真实节点的实例)
参数VIRTUAL_NODES:自定义虚拟节点的个数

public class IpHashLoadBalancer implements LoadBalancer{
    @Override
    public Instance select(List<Instance> instances , String address) {
        ConsistentHash consistentHash = new ConsistentHash(instances, 100);
        HashMap<String, Instance> map = consistentHash.map;
        return map.get(consistentHash.getServerIp(address));
    }
}

class ConsistentHash{
    //key:虚拟节点的hash 
    //value:真实的服务地址ip
    private static TreeMap<Integer,String> vnodeToIpMap = new TreeMap<>();
    //key:真实的服务地址ip 
    //value:服务器实例 Instance(IP+PORT)
    public static HashMap<String,Instance> map = new HashMap<>();
    
    private static int VIRTUAL_NODES = 160;//虚拟节点个数默认160
    private static List<Instance> instances;//服务地址列表
    private static Set<Integer> set = new HashSet<>();//hash去重set

    public ConsistentHash(List<Instance> instances , int VIRTUAL_NODES) {
        instances = instances;
        VIRTUAL_NODES = VIRTUAL_NODES;
    }
    
    static {
        for(Instance instance : instances){
            String ip = instance.getIp();
            map.put(ip,instance);
            for (int i = 0; i < VIRTUAL_NODES; i++) {
                int hash = getHash(ip + "#" + i);
                while (set.contains(hash)){//防止小概率事件
                    hash = getHash(ip + "#" + i + new Random().nextInt(100));
                }
                set.add(hash);
                vnodeToIpMap.put(hash,ip);
            }
        }
    }

    //获取ip地址
    public String getServerIp(String clientInfo){
        int hash = getHash(clientInfo);
        //key > hash 的 TreeMap
        SortedMap<Integer, String> subMap = vnodeToIpMap.tailMap(hash);
        Integer nodeIndex = subMap.firstKey();
        return nodeIndex == null ? 
                vnodeToIpMap.get(vnodeToIpMap.firstKey())
                : vnodeToIpMap.get(nodeIndex);
    }


    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;
            hash = Math.abs(hash);
        }
        return hash;
    }

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
一致性哈希是一种常见的分布式哈希算法,主要用于解决缓存、负载均衡、分布式数据库等领域的问题。下面是一个简单的 Java 代码实现一致性哈希算法的示例: ```java import java.util.*; public class ConsistentHash { private final SortedMap<Integer, String> circle = new TreeMap<>(); private final int virtualNodes; public ConsistentHash(int virtualNodes, Collection<String> nodes) { this.virtualNodes = virtualNodes; for (String node : nodes) { addNode(node); } } public void addNode(String node) { for (int i = 0; i < virtualNodes; i++) { String virtualNode = node + "#" + i; int hash = getHash(virtualNode); circle.put(hash, node); } } public void removeNode(String node) { for (int i = 0; i < virtualNodes; i++) { String virtualNode = node + "#" + i; int hash = getHash(virtualNode); circle.remove(hash); } } public String getNode(String key) { if (circle.isEmpty()) { return null; } int hash = getHash(key); if (!circle.containsKey(hash)) { SortedMap<Integer, String> tailMap = circle.tailMap(hash); hash = tailMap.isEmpty() ? circle.firstKey() : tailMap.firstKey(); } return circle.get(hash); } private int getHash(String key) { // TODO: 实现自己的哈希算法 return key.hashCode(); } } ``` 上述代码中,我们通过 `SortedMap` 维护了一个环形空间,并将每个节点对应的虚拟节点散落在这个空间上。在查找节点时,首先计算出键值的哈希值,然后查找距离这个哈希值最近的节点。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值