public class LoadBalanceManager {
private static TreeMap<Long, Node> nodes; // 虚拟节点到真实节点的映射
private static TreeMap<Long, Node> treeKey; // key到真实节点的映射
private static final int NODE_NUM = 10; // 每个机器节点关联的虚拟节点个数
/**
* 初始化方法,将作为节点的机器List传入作为参数
* @param nodeList
*/
public LoadBalanceManager(List<Node> nodeList) {
nodes = new TreeMap<Long, Node>();
treeKey = new TreeMap<Long, Node>();
for (Node node : nodeList) {
for (int n = 0; n < NODE_NUM; n++) {
// 一个真实机器节点关联NODE_NUM个虚拟节点
nodes.put(hash("SHARD-" + node.getIp() + "-NODE-" + n), node);
}
}
}
/**
* 映射key到真实节点
* @param ip
*/
public void loadBalance(String ip) {
SortedMap<Long, Node> tail = nodes.tailMap(hash(ip)); // 沿环的顺时针找到一个虚拟节点
if (tail.size() == 0) {
// 如果此ip的hash值比任何一个节点的值都大,则取第一个节点
Node first = nodes.firstEntry().getValue();
treeKey.put(hash(ip), first);
System.out.println(ip + "(hash: " + hash(ip) + ")连接到主机->" + first);
return;
}
treeKey.put(hash(ip), tail.get(tail.firstKey()));
System.out.println(ip + "(hash: " + hash(ip) + ")连接到主机->"
+ tail.get(tail.firstKey()));
}
/**
* 增加一个主机
*
* @param node
*/
public void addNode(Node node) {
System.out.println("增加主机" + node + "的变化:");
for (int n = 0; n < NODE_NUM; n++) {
Long key = hash("SHARD-" + node.getIp() + "-NODE-" + n);
addS(key, node);
}
}
/**
* 删除真实节点
*
* @param node
*/
public void deleteNode(Node node) {
if (node == null) {
return;
}
System.out.println("删除主机" + node + "的变化:");
for (int i = 0; i < NODE_NUM; i++) {
// 定位s节点的第i的虚拟节点的位置
Long key = hash("SHARD-" + node.getIp() + "-NODE-" + i);
SortedMap<Long, Node> tail = nodes.tailMap(key);
SortedMap<Long, Node> head = nodes.headMap(key);
Long begin = 0L;
Long end = 0L;
SortedMap<Long, Node> between;
if (head.size() == 0) {
between = treeKey.headMap(nodes.firstKey());
end = tail.firstKey();
tail.remove(end);
// nodes.remove(end);// 从nodes中删除s节点的第i个虚拟节点
} else {
begin = head.lastKey();
end = tail.firstKey();
tail.remove(end);
between = treeKey.subMap(begin, end);// 在s节点的第i个虚拟节点的所有key的集合
}
for (Iterator<Long> it = between.keySet().iterator(); it.hasNext();) {
Long lo = it.next();
treeKey.put(lo, tail.get(tail.firstKey()));
System.out.println("hash(" + lo + ")改变到->"
+ tail.get(tail.firstKey()));
}
}
}
/**
* 添加一个虚拟节点进环形结构,lg为虚拟节点的hash值
*
* @param hashKey
* @param node
*/
private void addS(Long hashKey, Node node) {
SortedMap<Long, Node> tail = nodes.tailMap(hashKey);
SortedMap<Long, Node> head = nodes.headMap(hashKey);
Long begin = 0L;
SortedMap<Long, Node> between;
if (head.size() == 0) {
between = treeKey.headMap(hashKey);
} else {
begin = head.lastKey();
between = treeKey.subMap(begin, hashKey);
}
nodes.put(hashKey, node);
for (Iterator<Long> it = between.keySet().iterator(); it.hasNext();) {
Long lo = it.next();
treeKey.put(lo, nodes.get(hashKey));
System.out.println("hash(" + lo + ")改变到->"
+ tail.get(tail.firstKey()));
}
}
/**
* MurMurHash算法,是非加密HASH算法,性能很高,
* 比传统的CRC32,MD5,SHA-1(这两个算法都是加密HASH算法,复杂度本身就很高,带来的性能上的损害也不可避免)
* 等HASH算法要快很多,而且据说这个算法的碰撞率很低.
*/
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);
finish.put(buf).rewind();
h ^= finish.getLong();
h *= m;
}
h ^= h >>> r;
h *= m;
h ^= h >>> r;
buf.order(byteOrder);
return h;
}
}
分享到:
相关推荐
一致性hash应用于负载均衡算法,本实现由C++语言开发。 一致性hash算法提出了在动态变化的Cache环境中,判定哈希算法好坏的四个定义: 1、平衡性(Balance)2、单调性(Monotonicity) 3、分散性(Spread)4、负载(Load)
一致性哈希算法是一种分布式哈希(Distributed Hash Table, DHT)技术,旨在解决在分布式环境中数据分布不均匀的问题。Ketama算法是基于一致性哈希的一种优化实现,由Last.fm公司的Simon Willison提出,其目标是在...
### 一致性Hash算法的原理及实现 #### 一、引言 一致性Hash算法是一种用于解决分布式环境下数据存储和检索问题的重要技术。它最初由David Karger等人在1997年的论文《Consistent Hashing and Random Trees: ...
【一致性Hash算法】是一种分布式系统中用于负载均衡的哈希算法。它的主要目的是解决当服务节点增加或减少时,能够尽量少地改变已有的请求分配,以保持系统的稳定性。在传统的哈希算法中,增加或删除一个服务器可能...
一致性哈希算法是一种分布式哈希(Distributed Hash Table, DHT)技术,它在处理大量数据分布到多个节点上时,能保持较好的均衡性和可扩展性。在C/C++编程中,一致性哈希通常用于构建分布式系统,如负载均衡、缓存...
一致性hash算法简介
一致性hash算法简介加C++实现
基于sentinel的redis集群的客户端,支持自动主从切换,采用ketama一致性hash算法哨兵客户端介绍sentinel-client使用Redis做单节点的数据存储,Sentinel做高可用服务的K-V存储集群。 高爾夫方案高可用方案是基于Redis...
基于go语言实现的分布式缓存系统源码+项目说明(以键值对的形式存储数据,一致性hash算法选择存储节点,Protobuf通信协议编解码。用户输入查询请求后,会优先在缓存系统查询,查不到则使用回调函数去源数据库查询,...
一致性哈希算法(Consistent Hashing)是一种在分布式系统中平衡数据分布的策略,尤其适用于缓存服务如Memcached或Redis。它的核心思想是通过哈希函数将对象映射到一个固定大小的环形空间中,然后将服务器也映射到这个...
为了解决这个问题,可以采用跳数法(Jump Consistent Hash)或者更高级的一致性哈希变体,如Ketama或libketama。哈希冲突则可以通过开放寻址、链地址法等方法来解决。 此外,一致性哈希算法在分布式缓存如Memcached...
一致性Hash算法,易于扩容;添加了 单元测试,使用Spring提供的RestTemplate调用RestFul风格的API接口;整合了 quartz 定时任务框架 ,并进行了封装,只需在构建完定时任务Job类后,在 application-quartz....
主要介绍了PHP实现的一致性Hash算法,结合实例形式详细分析了php一致性Hash算法的概念、原理及相关实现与使用技巧,需要的朋友可以参考下
一致性哈希算法(Consistent Hashing)是一种特殊的哈希算法,设计目的是为了在分布式缓存系统中解决节点动态增减时导致的数据分布不均问题。该算法最早在1997年的论文《Consistent Hashing and Random Trees》中被...
一致性哈希算法(Consistent Hashing)是一种特殊的哈希算法,设计目的是为了在分布式缓存系统中解决节点动态增减时导致的键值映射大量变更的问题。它最早在1997年的论文《Consistent hashing and random trees》中被...
一致性哈希算法是一种分布式哈希技术,用于解决在分布式缓存、负载均衡系统等场景下节点动态增减时,数据分布的稳定性和效率问题。它最初由麻省理工学院在1997年提出,目的是解决分布式缓存系统中如何均匀分配数据的...