java实现hash一致性算法
import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.StringUtils; import java.util.*; /**
* 一致性hash
*/
public class ConsistentHashWithVirtualNode { /**
* 待添加入Hash环的服务器列表
*/ private static String[] SERVERS = {"192.168.1.2:6379", "192.168.1.3:6379"}; /**
* key表示服务器的hash值,value表示虚拟节点的名称
*/
private static SortedMap<Integer, String> HASH_CIRCLE = new TreeMap<Integer, String>();
/**
* 用于结果统计
*/
private static Map<String, Integer> result = new HashMap<String, Integer>();
/**
* 每个真实节点对应虚拟节点数
*/
private static Integer VIRTUAL_NODES_NUM = 150; /**
* 使用FNV1_32_HASH算法计算服务器的Hash值
*/
private static int getHash(String str) {
final int p = 16777619;
int hash = (int) 2166136261L;
for (int i = 0; i < str.length(); i++)
hash = (hash ^ str.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;
} static {
for (int i = 0; i < SERVERS.length; i++) {
for (Integer j = 0; j < VIRTUAL_NODES_NUM; j++) {
setServer(SERVERS[i] + "vn" + j);
}
}
} private static void setServer(String ip) {
setServer(ip, null);
} private static void setServer(String ip, Integer hash) {
hash = hash != null ? getHash(hash.toString()) : getHash(ip);
if (StringUtils.isBlank(HASH_CIRCLE.get(hash))) {
HASH_CIRCLE.put(hash, ip);
System.out.println("[" + ip + "]加入sortedMap中, 其Hash值为" + hash);
} else {
//解决hash碰撞
setServer(ip, hash);
}
} public static void main(String[] args) {
for (int i = 0; i < 50; i++) {
long nodes = RandomUtils.nextLong();
String server = getServer(nodes);
String realServer = server.split("vn")[0];
System.out.println("[" + nodes + "]的hash值为" + getHash("" + nodes) + ", 被路由到虚拟结点[" + server + "], 真实结点[" + realServer + "]");
result.put(realServer, (result.get(realServer) == null ? 0 : result.get(realServer)) + 1);
}
result.forEach((k, v) -> {
System.out.println("结点[" + k + "]上有" + v);
});
} public static String getServer(Object node) {
String ip = HASH_CIRCLE.get(HASH_CIRCLE.firstKey());
// 得到带路由的结点的Hash值
int hash = getHash(node.toString());
// 得到大于该Hash值的所有Map
SortedMap<Integer, String> subMap = HASH_CIRCLE.tailMap(hash); if (!subMap.isEmpty()) {
// 第一个Key就是顺时针过去离node最近的那个结点
Integer i = subMap.firstKey();
ip = subMap.get(i);
}
// 返回对应的服务器名称
return ip;
}
}
java实现hash一致性算法的更多相关文章
- 【java】安全加密MessageDigest的功能及用法【hash一致性算法】
链接地址:https://blog.csdn.net/ma1kong/article/details/2662997 1.查看MessageDigest源码的注释说明 2.和hash一致性算法 什么关 ...
- 【hash】什么是hash,什么是哈希,什么是hash散列,什么是hash一致性算法【关于hash的详解】
什么是hash,什么是哈希,什么是hash散列,什么是hash一致性算法
- hash一致性算法
一致性hash算法是,1097麻省理工提出的分布式hashDHT实现算法,极倔internet的热点问题 平衡性 hash结果尽可能的分布到所有的缓存中去,缓冲空间利用率最高 单调性 保持已有的缓存能 ...
- 【Hash一致性算法】什么是Hash一致性算法
目录 1. 一致性Hash算法简介 环形Hash空间 把数据通过一定的hash算法处理后映射到环上 将机器通过hash算法映射到环上 机器的删除与添加 平衡性 本文转载自博客 1. 一致性Hash算法 ...
- Hash一致性算法底层原理
大纲 Hash取余算法 判定哈希算法好坏的四个定义 一致性Hash算法的两大设计 Hash取余算法 hash(Object.key)%N,hash值随Object.key.N的变化而变化. 如果有节点 ...
- 【java】hash一致性算法的实现区别【标题暂定】
下面两个都是在生成sign签名时候用到的方式,有什么区别? 第一种: import org.apache.commons.codec.digest.DigestUtils; String sign = ...
- redis 集群引出hash一致性算法
写的很棒的文章 https://blog.csdn.net/bntX2jSQfEHy7/article/details/79549368 这篇分析的更叼 https://www.jianshu.com ...
- nginx+php+memcache实现hash一致性memcache 集群
我们工作中可能会遇到key-value数据库,如果我们面对的不止一台memcache服务器,而是很多台.那么现在就回出现一个问题: 当我们访问nginx服务器的时候,我们会判断memcache中是否有 ...
- 11.redis cluster的hash slot算法和一致性 hash 算法、普通hash算法的介绍
分布式寻址算法 hash 算法(大量缓存重建) 一致性 hash 算法(自动缓存迁移)+ 虚拟节点(自动负载均衡) redis cluster 的 hash slot 算法 一.hash 算法 来了一 ...
随机推荐
- 10-[协程] greenlet模块、 gevent模块
1.greenlet模块:实现20个任务切换 如果我们在单个线程内有20个任务,要想实现在多个任务之间切换,使用greenlet模块可以非常简单地实现这20个任务直接的切换 使用yield生成器的方式 ...
- Kubernetes学习之路(十二)之Pod控制器--ReplicaSet、Deployment
一.Pod控制器及其功用 Pod控制器是用于实现管理pod的中间层,确保pod资源符合预期的状态,pod的资源出现故障时,会尝试 进行重启,当根据重启策略无效,则会重新新建pod的资源. pod控制器 ...
- SourceTree跳过注册安装使用
%LocalAppData%\Atlassian\SourceTree\目录 创建一个accounts.json [ { "$id": "1", ...
- JAVA图书管理系统汇总共27个[转]
java图书馆管理系统[优秀毕业设计论文+源码]http://down.51cto.com/data/68350java+sql server图书管理系统 http://down.51cto.com/ ...
- Andorid Studio 模块化开发相关配置
Andorid Studio 模块化开发相关配置 下面以宿主APP模块和Uer_Module模块为例: 第一步:在项目根目录gradle.properties配置文件中添加如下代码 isNeedUse ...
- SQL注入原理&分类&危害&防御
SQL是什么? 结构化查询语句 SQL注入是什么? 是一种将SQL 语句插入或添加到用户输入的参数中,这些参数传递到后台服务器,加以解析并执行 造成注入的原因/原理? 1.对用户输入的参数没有进行严格 ...
- 使用C#采集Shibor数据到Excel
对Shibor的变化一直以来比较关注,正好最近学习了对html数据处理的一些知识,就打算拿来采集一些我需要的Shibor数据. 使用到的库 HttpAgilityPack 一个非常不错的html解析工 ...
- Python科学测量与计算库Pymeasure: 控制你的仪器进行自动测试和科学计算
Python这种脚本语言因其语法简单,工具包丰富成熟,使用起来非常方便.在很多领域被广泛使用,今天介绍的是python在仪器控制应用领域,python在仪器控制领域相关的书籍可以参考<真实世界的 ...
- Linux 文件搜索命令:find、which、whereis 和 locate
Linux 提供了许多用于文件搜索的命令,这些命令都很强大,但是也有一些不同之处,这里分别介绍一下. 一.find 命令 find 是最常见和最强大的一个文件搜索命令.使用 find 命令可以在指定目 ...
- Windows 本地文件搜索神器
Wox: Windows 本地文件搜索神器 下载地址: https://github.com/Wox-launcher/Wox 注: Wox只能搜索C盘下的文件,所以需要结合everything 如果 ...