千家信息网

什么是一致性hash

发表于:2025-11-09 作者:千家信息网编辑
千家信息网最后更新 2025年11月09日,本篇内容主要讲解"什么是一致性hash",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"什么是一致性hash"吧!什么是HashHash就是把任意长度的输入,
千家信息网最后更新 2025年11月09日什么是一致性hash

本篇内容主要讲解"什么是一致性hash",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"什么是一致性hash"吧!

什么是Hash

Hash就是把任意长度的输入,通过散列算法,变换成固定长度的输出,该输出就是散列值。例如Integer.hashCode(),String.hashCode() 等。就算是输入的那内容不一致也有可能导致输出的hash值一致,这种情况就是hash碰撞,hash碰撞是不可避免的,设计出高效的hash算法是不容易的。

假设服务有四台服务器,多个用户来访问我们的服务,以下的分析都用此假设

普通Hash的分析

当用户来访问我的服务我们对请求和服务数量进行简单的运算等到hash,然后根据算出的hash分发请求到不同的服务上。
hash计算方式为 hash = 请求%serverCount
假设现在有四个请求分别是 请求1,请求2,请求3,请求4,现在对四个请求进行计算分发请求到不同非服务上, 计算结果如下图

普通Hash存在的问题

通过上图我们可以看到通过计算我们把不同的请求通过计算分别分发对应的服务器了, 但是这个方式会存在一定的问题,接下来我们就要分析了。
我们假设server3 宕机,name重新计算后的请求分发如下图

在实际情况下发生服务宕机或者扩容的情况是很普遍的,当发生宕机或者扩容的时候,我们之前计算的所有hash都需要重新计算,在生产环境下我们后台服务器很多台,客户端也有很多,那么影响是很⼤的,缩容和扩容都会存在这样的问题,⼤量⽤户的请求会被路由到其他的⽬标服务器处理,⽤户在原来服务器中的会话都会丢失。

一致性Hashg概念

一致性Hash的出现就解决了上述的问题,在发生宕机或者和扩容的时候尽可能少的影响请求的分发。

一致性Hash的思路如下:

首先有一条直线,直线的开始为0,结尾为2的32次方减1,这相当于一个地址,然后把直线弯曲形成一个圆环形成闭环,这就是hash环。我们对服务器求hash然后把服务器放到hash环上的对应位置上,当有请求到来时,对请求进行计算,把请求放到hash环的对应位置,然后顺时针获得最近的服务器节点。
示意图如下

当发生服务宕机或者扩容是请求转发也是会发生变化的,这次我用扩容示例,宕机同理
假如我们在server1和server2之间加个server4,请求转发如下图

由上图我们可以得出当发生扩容或者宕机的时候只会影响极少数一部分的用户,最大限度上提高的体验

当然一致性hash也可能存在一些问题的,比如如下图所示, 服务器分布及其不合理, 大量的请求都落在同一个服务器上,对服务的压力较大。

针对这种情况我们可以用增加虚拟节点的方式来尽可能更合理的分发请求来,减轻对某一服务的压力。
如下图我们对每个节点增加两个虚拟节点

实现普通Hash和一致性Hash

普通Hash实现

public static void main(String[] args) {   String[] ips = new String[]{   "101.1.1.1","101.1.1.2","101.1.1.3","101.1.1.4"};int serverCount = 4;for (String ip : ips) {   System.out.println(ip + " 的请求分发到 server" + ip.hashCode()%serverCount);}System.out.println("======================宕机分割线==========================================");// 模拟宕机一个serverCount = 3;for (String ip : ips) {   System.out.println(ip + " 的请求分发到 server" + ip.hashCode()%serverCount);}}

输出

101.1.1.1 的请求分发到 server3101.1.1.2 的请求分发到 server0101.1.1.3 的请求分发到 server1101.1.1.4 的请求分发到 server2======================宕机分割线==========================================101.1.1.1 的请求分发到 server1101.1.1.2 的请求分发到 server2101.1.1.3 的请求分发到 server0101.1.1.4 的请求分发到 server1

一致性Hash实现

不带虚拟节点实现

public static void main(String[] args) {   String[] serverIps = new String[]{   "101.231.123.11","11.1.112.234","123.112.11.123","232.12.11.22"};// 用来存放服务器的SortedMap hashServerMap = new TreeMap<>();for (String ip : serverIps) {   hashServerMap.put(Math.abs(ip.hashCode()), ip);}// 客戶端ipString[] clientIps = new String[]{   "101.23.234.33","11.1.112.2","123.112.11.12","23.121.11.22"};for (String ip : clientIps) {   // tailMap 方法返回的是大于参数的集合SortedMap serverMap = hashServerMap.tailMap(Math.abs(ip.hashCode()));// 取hash环上的第一个服务器if (serverMap.isEmpty()) {   Integer firstKey = hashServerMap.firstKey();System.out.println(ip + " 的请求分发到 " + hashServerMap.get(firstKey));}else {   // 获取结果集的第一个服务器System.out.println(ip + " 的请求分发到 " + hashServerMap.get(serverMap.firstKey()));}}}

分发结果

101.23.234.33 的请求分发到 232.12.11.2211.1.112.2 的请求分发到 123.112.11.123123.112.11.12 的请求分发到 11.1.112.23423.121.11.22 的请求分发到 123.112.11.123

带虚拟节点实现

public static void main(String[] args) {   String[] serverIps = new String[]{   "101.231.123.11","11.1.112.234"};// 每个节点的虚拟节点数int virtualNodeCount = 2;// 用来存放服务器的SortedMap hashServerMap = new TreeMap<>();for (String ip : serverIps) {   hashServerMap.put(Math.abs(ip.hashCode()), ip);// 处理虚拟节点for (int i = 0; i < virtualNodeCount; i++) {   hashServerMap.put(Math.abs((ip + "#" + i).hashCode()), ip + "#" + i);}}// 客戶端ipString[] clientIps = new String[]{   "101.23.234.33","11.1.112.2","123.112.11.12","23.121.11.22"};for (String ip : clientIps) {   // tailMap 方法返回的是大于参数的集合SortedMap serverMap = hashServerMap.tailMap(Math.abs(ip.hashCode()));// 取hash环上的第一个服务器if (serverMap.isEmpty()) {   Integer firstKey = hashServerMap.firstKey();System.out.println(ip + " 的请求分发到 " + hashServerMap.get(firstKey));}else {   // 获取结果集的第一个服务器System.out.println(ip + " 的请求分发到 " + hashServerMap.get(serverMap.firstKey()));}}}

分发结果

101.23.234.33 的请求分发到 101.231.123.1111.1.112.2 的请求分发到 11.1.112.234123.112.11.12 的请求分发到 11.1.112.23423.121.11.22 的请求分发到 101.231.123.11#0

到此,相信大家对"什么是一致性hash"有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

服务 服务器 一致 一致性 节点 结果 问题 就是 情况 输出 不同 普通 内容 方式 方法 时候 用户 直线 分析 影响 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 服务器管理口设置原理 网络技术的大学 公司网站服务器如何管理 如何在vs里面看见数据库的列 北京思源互联网科技 计算机安全网络安全信息安全关系 c 如何查询数据库所有表 remove在数据库中的作用是 软件开发会徽设计 杭州湖畔网络技术有限公司电话 软件开发公司可以运营业务吗 数据库信息的运行安全 汉中网络技术市场报价 初一网络安全画 重庆出库管理erp软件开发 大连银行股份有限公司软件开发 服务器电脑文件如何隔离 网约车服务器pdf怎么用 为什么重装上阵老是有人炸服务器 百度在线网络技术有限公司天津 文件中什么是数据库管理系统 一键读取mssql数据库 计算机网络安全关键字 网络安全保卫工作如何 学生登录入口网络安全 计算机等级网络技术教程 关系数据库的逻辑模型是 德宏网络安全出路 ddr3服务器内存 word怎样建立写作数据库
0