第五周命题作业
发布于: 2020 年 12 月 26 日
1. 用你熟悉的编程语言实现一致性 hash 算法。
1)逻辑图如下:

2)JAVA语言实现如下:
定义正式缓存虚拟机类:
package gaoyong.jaigou.sf;//负载均衡的机器节点信息,name,ip,port,numCachepublic class CacheNode {    private  String name; //机器名称    private  String ip;   //机器IP    private  String port; //机器端口    private  int numCache; //缓存实体数量    public CacheNode(String name, String ip, String port) {        this.name = name;        this.ip = ip;        this.port = port;        this.numCache = 0;    }    public int addNumcache(){        return  numCache++;    }    public int getNumCache() {        return numCache;    }}
定义虚拟缓存机映射虚拟节点类,主要提供两个方法:
2.1 init()初始化hash环,建立虚拟节点和缓存服务器映射关系,为treemap结构
2.2 getShard(String key) 根据传入的key值,一般为hash值,顺时针找到最近一个虚拟节点,并且返回虚拟节点对应真实的虚拟机
package gaoyong.jaigou.sf;import gaoyong.jaigou.sf.tool.HashTool;import java.util.List;import java.util.SortedMap;import java.util.TreeMap;//机器与虚拟机对应的类public class Shard<T> {    private TreeMap<Integer,T>  virNodes; //映射到hash的一组虚拟节点    private List<T> shards; //真实机器节点列表    private int virNodeNumer; //每个机器关联的虚拟节点数    public Shard(List<T> shards, int virNodeNumer) {        this.shards = shards;        this.virNodeNumer = virNodeNumer;        init();    }    /**     * 初始化一致性hash环     */    private  void init(){       virNodes = new TreeMap<Integer,T>();       for(int i =0;i<shards.size();i++){           T shard = shards.get(i);           for (int n =0;n<=virNodeNumer;n++){               virNodes.put(HashTool.hash("SHARD-"+i+"--NODE--")+n,shard);           }       }    }    /**     * 根据key值,得到真实的虚拟机     * @param key     * @return     */    public  T getShard(String key){        SortedMap<Integer,T> tail = virNodes.tailMap(HashTool.hash(key));//沿环的顺时针找到一个虚拟节点        if(tail.size()==0){            return virNodes.get(virNodes.firstKey());        }        return tail.get(tail.firstKey()); //返回该虚拟节点对应的真实机器节点信息    }}2. 编写测试用例测试这个算法,测试 100万KV 数据,10个服务器节点的情况下,计算 这些 KV 数据在服务器上分布数量的标准差,以评估算法的存储负载不均衡性。
写一 个测试类,主要完成以下功能:
1.初始化10台真实缓存虚拟机,返回到List集合
2.初始化Shard<T>类,返回真实缓存虚拟机对应的虚拟节点
3.初始化100KV数据,计算10台缓存虚拟机每台机器缓存对象的个数
4.虚拟节点每次循环步长20递增,直至500,计算标准差
代码如下:
package gaoyong.jaigou.sf;import java.util.ArrayList;import java.util.List;public class HashTest {    public static void main(String[] args) {        final int NUM_CHACHENODE=10; //虚拟机节点        String name; //机器名称        String ip; //机器IP        String port ="8888"; //机器端口        for(int virNodeNum=0;virNodeNum<=500;virNodeNum=virNodeNum+20){ //virNodeNum 需要虚拟在环上的节点数量            //初始化机器节点            List<CacheNode> cacheNodes = new ArrayList<CacheNode>();            for (int i=0;i<=NUM_CHACHENODE;i++){               name=String.format("HashCache_.%d",i);               ip=String.format("192.168.10.%d",i);               CacheNode  cacheNode = new CacheNode(name,ip,port);                cacheNodes.add(cacheNode);            }            long startTime=System.currentTimeMillis(); //程序开始执行时间            //初始化一致性hash环            Shard<CacheNode> virCacheNodes = new Shard<CacheNode>(cacheNodes,virNodeNum);            //初始化100万KV测试数据            for(int n = 0;n<=1000000;n++){                String key = String.format("%f",Math.random());                //System.out.println("随机生成测试数据,编号:"+n+",数据值:"+key);                CacheNode keyHash =  virCacheNodes.getShard(key);                //对应机器node缓存数加1                keyHash.addNumcache();            }            long endTime=System.currentTimeMillis(); //程序开始执行时间            //平均值10w计算标准差            double std=0;            double avg =100000;            for (int i =0;i<NUM_CHACHENODE;i++){                CacheNode node  =cacheNodes.get(i);                //System.out.println(" 每台机器node节点:" + i +"  缓存个数: " + (node.getNumCache()) );                std = std + Math.abs(avg - (double) node.getNumCache()) * Math.abs(avg - (double) node.getNumCache());            }            std = std/NUM_CHACHENODE;            std = Math.sqrt(std);            System.out.println("虚拟节点:"+virNodeNum+" 标准差: "+std);            System.out.println("虚拟节点:"+virNodeNum+" 100万次算法程序运行时间: "+(endTime-startTime) +"ms");            cacheNodes.clear();        }    }}
对应的折线图:

划线
评论
复制
发布于: 2020 年 12 月 26 日阅读数: 13

cc
关注
还未添加个人签名 2018.03.19 加入
还未添加个人简介











 
    
评论