负载均衡之缓存路由(一致性Hash)算法Java实现
分布式系统中负载均衡的问题时候可以使用Hash算法让固定的一部分请求落到同一台服务器上,这样每台服务器固定处理一部分请求(并维护这些请求的信息),起到负载均衡的作用。比如说分布式缓存,既然是缓存,就没有必要去做一个所有机器上的数据都完全一样的缓存集群,而是应该设计一套好的缓存路由工具类,所以一致性Hash算法就因此而诞生了。
衡量一个一致性Hash算法最重要的两个特征:
①平衡性:平衡性是指哈希的结果能够尽可能分布到所有的缓冲中去,这样可以使得所有的缓冲空间都得到利用。
②单调性:单调性是指如果已经有一些数据通过哈希分配到了相应的机器上,又有新的机器加入到系统中。哈希的结果应能够保证原有的数据要么还是呆在它所在的机器上不动,要么被迁移到新的机器上,而不会迁移到旧的其他机器上。
业界常用的两种一致性Hash算法,一种是不带虚拟节点的Hash算法,另外一种是带虚拟节点的Hash算法。
下面的代码就是不带虚拟节点的一致性Hash算法,原理稍后分析:
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.UUID;
import org.apache.commons.lang.StringUtils;
/**
* 一致性Hash算法
* */
public class ConsistentHashWithoutVirtualNode {
/**
* 服务器节点信息
* */
private static SortedMap<Integer, String> nodeMap = new TreeMap<>();
//服务器配置信息(可配置)
private static String[] servers = {"192.168.56.120:6379",
"192.168.56.121:6379",
"192.168.56.122:6379",
"192.168.56.123:6379",
"192.168.56.124:6379"};
/**
* 初始化
* */
static{
for(int i=0; i< servers.length; i++){
nodeMap.put(getHash(servers[i]), serve