分布式缓存一致性hash算法,带虚拟节点

本文深入探讨了分布式缓存中一致性Hash算法的工作原理,特别是引入虚拟节点以解决数据不平衡问题。通过详细解释,读者将了解如何通过一致性Hash策略确保在节点动态增减时保持缓存数据的稳定性和分布均匀性。
摘要由CSDN通过智能技术生成
package com.lsl.test.hash;

import java.util.LinkedList;
import java.util.List;
import java.util.SortedMap;
import java.util.TreeMap;
/**
 * 分布式缓存一致性hash算法,带虚拟节点
 * @author lisl
 *
 */
public class HashCacheTest2 {
	
	private static final String [] realServers =
			{"192.168.1.100","192.168.1.101", "192.168.1.102", "192.168.1.103", "192.168.1.104"};
	//真实主机
	private static List<String> realNodeList = new LinkedList<String>();
	//虚拟主机,key表示主机hash值,value为虚拟主机名称
	private static SortedMap<Integer, String> sortMap = new TreeMap<Integer, String>();
	
	private static final Integer virtualNodeNumber = 5;
	
	static{
		for (int i = 0; i < realServers.length; i++) {
			realNodeList.add(realServers[i]);
			
			//每个主机添加对应数量的虚拟节点
			for (int j = 0; j < virtualNodeNumber; j++) {
				String virtualNodeName = realServers[i]+"@v"+j;
				sortMap.put(getHash(virtualNodeName), virtualNodeName);
				System.out.println("虚拟主机初始化:"+virtualNodeName);
			}
		}
		
		
	}
	
	private static String getServer(String keyWord){
		SortedMap<Integer, String> tailMap = sortMap.tailMap(getHash(keyWord));
		String virtualServerName = "";
		if(tailMap != null && tailMap.size() > 0){
			virtualServerName = tailMap.get(tailMap.firstKey());
		}else{
			virtualServerName = sortMap.get(sortMap.firstKey());
		}
		return virtualServerName.substring(0, virtualServerName.indexOf("@"));
	}
	
	private static Integer getHash(String keyWord){
		 final int p = 16777619;
	        int hash = (int)2166136261L;
	        for (int i = 0; i < keyWord.length(); i++)
	            hash = (hash ^ keyWord.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;
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		String [] dataStrs = {"香蕉王", "好人网", "水蜜桃", "苹果纸", "句大的子"};
		
		for (int j = 0; j < dataStrs.length; j++) {
			System.out.println(dataStrs[j]+"被分配到"+getServer(dataStrs[j]));
		}
	}

}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值