【分布式】load balance 03-一致性哈希算法 java 实现
负载均衡系列专题
本节我们来看一下如何实现一个一致性 hash 框架。
源码
普通 hash
我们首先定义一下 hash 接口,以及最简单的 jdk 实现:
- IHash
public interface IHash {
/**
* 计算 hash 值
* @param text 文本
* @return 结果
* @since 0.0.1
*/
int hash(String text);
}
- HashJdk.java
public class HashJdk implements IHash {
@Override
public int hash(String text) {
return text.hashCode();
}
}
Node 定义
用来定义一个节点:
此处省略了一些方法。
public class Node {
/**
* 节点名称
* @since 0.0.1
*/
private String name;
/**
* 节点 ip
* @since 0.0.1
*/
private String ip;
public Node(String name, String ip) {
this.name = name;
this.ip = ip;
}
public Node(String ip) {
this(ip, ip);
}
//Getter & Setter & toString()
// equals && hashCode
}
核心实现
- IConsistentHashing.java
一致性 hash 的接口定义。
public interface IConsistentHashing {
/**
* 获取对应的节点
* @param key key
* @return 节点
* @since 0.0.1
*/
Node get(final String key);
/**
* 添加节点
* @param node 节点
* @return this
* @since 0.0.1
*/
IConsistentHashing add(final Node node);
/**
* 移除节点
* @param node 节点
* @return this
* @since 0.0.1
*/
IConsistentHashing remove(final Node node);
/**
* 获取节点信息
* @return 节点
* @since 0.0.1
*/
Map<Integer, Node> nodeMap();
}
- 默认实现
public class ConsistentHashing implements IConsistentHashing {
/**
* 虚拟节点数量
* @since 0.0.1
*/
private final int virtualNum;
/**
* hash 策略
* @since 0.0.1
*/
private final IHash hash;
/**
* node map 节点信息
*
* key: 节点 hash
* Node: 节点
* @since 0.0.1
*/
private final TreeMap<Integer, Node> nodeMap = new TreeMap<>();
public ConsistentHashing(int virtualNum, IHash hash) {
this.virtualNum = virtualNum;
this.hash = hash;
}
/**
* 沿环的顺时针找到虚拟节点
* @param key key
* @return 结果
* @since 0.0.1
*/
@Override
public Node get(String key) {
final int hashCode = hash.hash(key);
Integer target = hashCode;
// 不包含时候的处理
if (!nodeMap.containsKey(hashCode)) {
target = nodeMap.ceilingKey(hashCode);
if (target == null && !nodeMap.isEmpty()) {
target = nodeMap.firstKey();
}
}
return nodeMap.get(target);
}
@Override
public IConsistentHashing add(Node node) {
// 初始化虚拟节点
for (int i = 0; i < virtualNum; i++) {
int nodeKey = hash.hash(node.toString() + "-" + i);
nodeMap.put(nodeKey, node);
}
return this;
}
@Override
public IConsistentHashing remove(Node node) {
// 移除虚拟节点
// 其实这里有一个问题,如果存在 hash 冲突,直接移除会不会不够严谨?
for (int i = 0; i < virtualNum; i++) {
int nodeKey = hash.hash(node.toString() + "-" + i);
nodeMap.remove(nodeKey);
}
return this;
}
@Override
public Map<Integer, Node> nodeMap() {
return Collections.unmodifiableMap(this.nodeMap);
}
}
完整代码
其他还有一些引导类等辅助工具。
完整代码参见 github

参考资料
【分布式】load balance 03-一致性哈希算法 java 实现的更多相关文章
- 分布式_理论_08_Consistent Hash(一致性哈希算法)
一.前言 五.参考资料 1.分布式理论(八)—— Consistent Hash(一致性哈希算法)
- memcached分布式一致性哈希算法
<span style="font-family: FangSong_GB2312; background-color: rgb(255, 255, 255);">如果 ...
- 一致性哈希算法(Consistent Hashing) .
应用场景 这里我先描述一个极其简单的业务场景:用4台Cache服务器缓存所有Object. 那么我将如何把一个Object映射至对应的Cache服务器呢?最简单的方法设置缓存规则:object.has ...
- 五分钟理解一致性哈希算法(consistent hashing)
转载请说明出处:http://blog.csdn.net/cywosp/article/details/23397179 一致性哈希算法在1997年由麻省理工学院提出的一种分布式哈希(DHT)实现算法 ...
- 每天进步一点点——五分钟理解一致性哈希算法(consistent hashing)
转载请说明出处:http://blog.csdn.net/cywosp/article/details/23397179 一致性哈希算法在1997年由麻省理工学院提出的一种分布式哈希(DHT) ...
- 一致性哈希算法(consistent hashing)【转】
一致性哈希算法 来自:http://blog.csdn.net/cywosp/article/details/23397179 一致性哈希算法在1997年由麻省理工学院提出的一种分布式哈希 ...
- 一致性哈希算法原理及Java实现
一致性哈希算法在1997年由麻省理工学院提出的一种分布式哈希(DHT)实现算法,设计目标是为了解决因特网中的热点(Hot spot)问题,初衷和CARP十分类似.一致性哈希修正了CARP使用的简 单 ...
- 一致性哈希算法(consistent hashing)(转)
原文链接:每天进步一点点——五分钟理解一致性哈希算法(consistent hashing) 一致性哈希算法在1997年由麻省理工学院提出的一种分布式哈希(DHT)实现算法,设计目标是为了解决因特网 ...
- hash环/consistent hashing一致性哈希算法
一致性哈希算法在1997年由麻省理工学院提出的一种分布式哈希(DHT)实现算法,设计目标是为了解决因特网中的热点(Hot spot)问题,初衷和CARP十分类似.一致性哈希修正了CARP使用的 ...
- 一致性哈希算法(consistent hashing)(转载)
转载请说明出处:http://blog.csdn.net/cywosp/article/details/23397179 一致性哈希算法在1997年由麻省理工学院提出的一种分布式哈希(DHT) ...
随机推荐
- CSS : object-fit 和 object-position实现 图片或视频自适应
img { width: 100%; height: 300px; object-fit: cover; ...
- MySQL-多表查询练习
首先创建练习所需要的数据表 储备:建表操作: CREATE TABLE `t_dept` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `deptName` VARC ...
- 查看正在运行容器的环境变量-寻找容器运行mysql的root密码
查看正在运行容器的环境变量-寻找容器运行mysql的root密码 背景 有一个服务器上面运行着一个长达两年的mysql数据库实例. 因为当时root密码是通过环境变量注入进去的. 现在我想重新连接一下 ...
- [转帖]金仓数据库KingbaseES表空间(tablespace)知多少
金仓数据库KingbaseES表空间定义 金仓数据库KingbaseES中的表空间允许在文件系统里定义那些代表数据库对象的文件存放位置,比如表和索引等.一旦表空间被创建,那么就可以在创建数据库对象时通 ...
- [转帖]一、Kafka Tool使用
一.Kafka Tool使用 1.添加cluster 2.开启SASL_PLAINTEXT 如果kafka 开启SASL_PLAINTEXT认证(用户名和密码认证) 3.高级设置 如果设置的是SASL ...
- [转帖]MySQL ALTER TABLE: ALTER vs CHANGE vs MODIFY COLUMN
https://www.cnblogs.com/pachongshangdexuebi/p/5029152.html ALTER COLUMN 语法: ALTER [COLUMN] col_name ...
- [转帖]Day63_Kafka(一)
第一讲 Kafka基础操作 课程大纲 课程内容 学习效果 掌握目标 Kafka简介 消息队列 掌握 Kafka简介 Kafka分布式环境 Kafka操作 Kafka shell 掌握 Kafka ap ...
- 银河麒麟v10 安装 virt-manager 的过程
上个月公司购置一台飞腾2000+ 银河麒麟v10的机器. 想着能够利用虚拟化 安装一下虚拟机 提高测试灵活度 找了一下原厂要了一下相关的命令 在这里进行一下测试工作. 第一步: 安装必备的包 yum ...
- Python控制微信,实现聊天机器人
自从微信禁止网页版登陆之后,itchat 库实现的功能也就都不能用了,那现在 Python 还能操作微信吗?答案是:可以! 在Github上有一个项目叫<WeChatPYAPI>可以使用 ...
- js计算两个时间相差多少分钟
<script> var str = "2020-02-04" console.log(str) console.log(str.replace(/-/g, " ...