分享

一致性hash算法java代码实现

 昵称23016082 2015-05-06
package hashring;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.List;
import java.util.SortedMap;
import java.util.TreeMap;

import redis.clients.jedis.Jedis;

public class Shard  { // S类封装了机器节点的信息 ,如name、password、ip、port等

    private TreeMap<Long, Server> nodes; // 虚拟节点
    private List<Server> shards; // 真实机器节点
    private final int NODE_NUM = 100; // 每个机器节点关联的虚拟节点个数

    public Shard(List<Server> shards) {
        super();
        this.shards = shards;
        init();
    }

    private void init() { // 初始化一致性hash环
        nodes = new TreeMap<Long, Server>();
        for (int i = 0; i<shards.size(); ++i) { // 每个真实机器节点都需要关联虚拟节点
            final Server shardInfo = shards.get(i);

            for (int n = 0; n < NODE_NUM; n++){
                // 一个真实机器节点关联NODE_NUM个虚拟节点
                nodes.put(hash("SHARD-" + i + "-NODE-" + n), shardInfo);
            }

        }
    }

    public Server getShardInfo(String key) {
        SortedMap<Long, Server> tail = nodes.tailMap(hash(key)); // 沿环的顺时针找到一个虚拟节点
        if (tail.size() == 0) {
            return nodes.get(nodes.firstKey());
        }
        return tail.get(tail.firstKey()); // 返回该虚拟节点对应的真实机器节点的信息
    }

    /**
     * hash ring
     *  MurMurHash算法,是非加密HASH算法,性能很高,
     *  比传统的CRC32,MD5,SHA-1(这两个算法都是加密HASH算法,复杂度本身就很高,带来的性能上的损害也不可避免)
     *  等HASH算法要快很多,而且据说这个算法的碰撞率很低.
     *  http://murmurhash./
     */
    private Long hash(String key) {
        
        ByteBuffer buf = ByteBuffer.wrap(key.getBytes());
        int seed = 0x1234ABCD;
        
        ByteOrder byteOrder = buf.order();
        buf.order(ByteOrder.LITTLE_ENDIAN);

        long m = 0xc6a4a7935bd1e995L;
        int r = 47;

        long h = seed ^ (buf.remaining() * m);

        long k;
        while (buf.remaining() >= 8) {
            k = buf.getLong();

            k *= m;
            k ^= k >>> r;
            k *= m;

            h ^= k;
            h *= m;
        }

        if (buf.remaining() > 0) {
            ByteBuffer finish = ByteBuffer.allocate(8).order(
                    ByteOrder.LITTLE_ENDIAN);
            // for big-endian version, do this first:
            // finish.position(8-buf.remaining());
            finish.put(buf).rewind();
            h ^= finish.getLong();
            h *= m;
        }

        h ^= h >>> r;
        h *= m;
        h ^= h >>> r;

        buf.order(byteOrder);
        return h;
    }

    
    public static void main(String[] args) {
        List<Server> shards = new ArrayList<Server>();
        Server s1  = new Server("192.168.1.81",6379);
        Server s2  = new Server("192.168.1.82", 6379);
        shards.add(s1);
        shards.add(s2);

        Shard shard = new Shard (shards);
        
//        shard.save("bjsxt","asdfsdfsdf");
        
//        shard.get("bjsxt");

        System.out.println(shard.getShardInfo("bjsxtlxasdsdf"));
        
//        new Jedis(sha)
        
    }
}
================================bean======================================
package hashring;

public class Server {
    private String ip;
    private int port;
    private String name;
    private String pwd;
   
   
    public String getIp() {
        return ip;
    }
    public void setIp(String ip) {
        this.ip = ip;
    }
    public int getPort() {
        return port;
    }
    public void setPort(int port) {
        this.port = port;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getPwd() {
        return pwd;
    }
    public void setPwd(String pwd) {
        this.pwd = pwd;
    }
    public Server(String ip, int port) {
        super();
        this.ip = ip;
        this.port = port;
    }
    public Server() {
        super();
    }
   
   
    @Override
    public String toString() {
        // TODO Auto-generated method stub
        return this.ip+"--"+this.port;
    }
   
}


    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约