当前位置: 首页 > news >正文

一致性Hash问题及解决方案

Hash算法的应用场景

  1. 请求的负载均衡
    Nginx的ip_hash策略可以在客户端ip不发生变化的情况下,将其发出的请求始终路由到同一个目标服务器上,实现会话粘滞,避免处理session共享问题。
  • 如果没有ip_hash策略,可以通过维护一张映射表的方式来实现会话粘滞:
    • 映射表存储的是客户端ip或者session与具体目标服务器的映射关系 <ip,server>

      • 缺点:
        1. 客户端很多的情况下,映射表非常大,浪费内存空间
        2. 客户端上下线、目标服务器上下线都会导致重新维护映射表,维护成本大
    • 如果使用Hash算法,可以对ip或者session计算hash值,hash值与服务器数量进行取模运算,得到的值就是当前请求应该被路由到的服务器编号。由此,同一个ip发送过来的请求就可以路由到同一个目标服务器,实现会话粘滞。

  1. 分布式存储
    有 Redis1、Redis2、Redis3 三台Redis服务器,可以针对key进行hash处理 Hash(key)%3 = index 使用余数锁定存储的具体服务器节点。

普通Hash算法存在的问题

以ip_hash为例,假定用户ip固定不变,当后端服务器有一个宕机,数量由3变为2,那么之前所有用户的求模都需要重新计算。
如果在生产环境中,后台服务器有很多台,客户端也有很多个,出现这种问题的影响是很大的。服务器的扩缩容都会出现这样的问题,大量的用户请求被路由到其他的目标服务器处理,用户在原来服务器的会话都将丢失。

普通Hash算法:

// 定义客户端IP
String[] clients = {"192.168.31.121", "192.168.3.21", "192.168.1.11"};// 定义服务器数量
int server = 5;// hash(ip) % server数量 = index
for (String client : clients) {int hashCode = Math.abs(client.hashCode());int index = hashCode % server;System.out.println("客户端:\t" + client + "\t 分配到了服务器 " + (index + 1) + " 上");
}

一致性Hash算法的思路

  1. 首先有一条直线,直线开头和结尾分别定为1和232-1,这相当于一个地址
  2. 对于这样一条直线,首尾相连构成一个闭环,这样的圆环称为Hash环
  3. 把服务器IP或者主机名求Hash值然后对应到Hash环上,针对客户端IP求Hash值,对应到环上的某个位置,然后按照顺时针的方向找最近的服务器节点

在这里插入图片描述

  • 缩容
    假设将节点3下线,原来路由到3的客户端请求重新路由到节点4,对于其他客户端没有影响,只是这一小部分受到影响
    请求的迁移量达到了最小,这样的算法对于分布式集群来说非常合适,避免了大量请求转移。

在这里插入图片描述

  • 扩容
    新增节点5之后,原来路由到节点3的部分客户端路由到了节点5上,对于其他客户端没有影响,只是这一小部分受到影响

在这里插入图片描述

代码如下:

// 定义服务器IP
String[] servers = {"192.168.31.121", "192.168.3.21", "192.168.1.11", "12.168.31.121", "192.138.3.21", "192.68.1.11"};
// 定义客户端IP
String[] clients = {"12.16.31.121", "12.18.3.1", "19.16.1.11"};
// 计算服务器的Hash,并放到排序的Map中
SortedMap<Integer,String> hashServerMap = new TreeMap<>();
for (String server : servers) {int hashCode = Math.abs(server.hashCode());hashServerMap.put(hashCode,server);
}
// 求客户端IP的Hash,取出对应的服务器
for (String client : clients) {int clientHash = Math.abs(client.hashCode());SortedMap<Integer, String> tailedMap = hashServerMap.tailMap(clientHash);// 取出Hash环上的第一台服务器Integer firstKey;if (tailedMap.isEmpty()){firstKey = hashServerMap.firstKey();}else {firstKey = tailedMap.firstKey();}System.out.println("客户端IP\t"+ client +"\t被路由到了服务器\t" + hashServerMap.get(firstKey));
}

存在的问题及解决方法

如上所述,每一台服务器负责一段,一致性Hash算法对于节点的增加都只需要重定位环空间的一小部分数据,具有较好的容错性和可扩展性。

  1. 一致性Hash算法在服务节点太少时,容易因节点分部不均匀造成数据倾斜问题。例如只有两台服务器,这两台服务器在环上的分部十分靠近,导致某个节点只负责非常小的一段,大量的请求落在了另外一个节点上,导致数据倾斜。
  2. 为了解决这种方法,一致性Hash算法引入了虚拟节点机制,即对每一个服务节点计算多个Hash,每个计算结果都放置一个此服务节点,称为虚拟节点。具体做法可以在服务器IP或者主机名后增加编号来实现,例如 “节点1的ip#1” “节点1的ip#2” “节点1的ip#3”……形成多个虚拟节点,当客户端被路由到虚拟节点的时候其实是被路由到该虚拟节点所对应的真实节点。

代码如下:

// 定义服务器IP
String[] servers = {"192.168.31.121", "192.168.3.21", "192.168.1.11", "12.168.31.121", "192.138.3.21", "192.68.1.11"};
// 定义客户端IP
String[] clients = {"12.16.31.121", "12.18.3.1", "19.16.1.11"};SortedMap<Integer, String> serverHash = new TreeMap<>();int virtualNodeCount = 3;
// 开始计算服务器的Hash
for (String server : servers) {int hash = Math.abs(server.hashCode());serverHash.put(hash, server);// 设置虚拟节点for (int i = 0; i < virtualNodeCount; i++) {int virtualNodeHash = Math.abs((server + "#" + i).hashCode());serverHash.put(virtualNodeHash, "虚拟节点" + i + "映射过来的请求:" + server);}
}System.out.println(serverHash.size());
// 计算客户端请求的服务器Hash
for (String client : clients) {int clientHash = Math.abs(client.hashCode());SortedMap<Integer, String> tailedMap = serverHash.tailMap(clientHash);if (tailedMap.isEmpty()) {Integer firstKey = serverHash.firstKey();System.out.println("客户端:" + client + "\t\t路由到了 \t" + serverHash.get(firstKey));} else {Integer firstKey = tailedMap.firstKey();System.out.println("客户端:" + client + "\t\t路由到了 \t" + serverHash.get(firstKey));}
}

相关文章:

一致性Hash问题及解决方案

Hash算法的应用场景 请求的负载均衡 Nginx的ip_hash策略可以在客户端ip不发生变化的情况下&#xff0c;将其发出的请求始终路由到同一个目标服务器上&#xff0c;实现会话粘滞&#xff0c;避免处理session共享问题。 如果没有ip_hash策略&#xff0c;可以通过维护一张映射表的…...

【接口设计】如何设计统一 RESTful 风格的数据接口

如何设计统一 RESTful 风格的数据接口 1.版本控制1.1 通过 URL1.2 通过自定义请求头1.3 通过 Accept 标头 2.过滤信息3.确定 HTTP 的方法4.确定 HTTP 的返回状态5.定义统一返回的格式 近年来&#xff0c;随着移动互联网的发展&#xff0c;各种类型的客户端层出不穷。如果不统一…...

【备战秋招】——算法题目训练和总结day3

【备战秋招】——算法题目训练和总结day3&#x1f60e; 前言&#x1f64c;BC149简写单词题解思路分析代码分享&#xff1a; dd爱框框题解思路分析代码分享&#xff1a; 除2&#xff01;题解思路分析代码分享&#xff1a; 总结撒花&#x1f49e; &#x1f60e;博客昵称&#xff…...

Git 操作总结

1. 安装、Git 环境配置 1.1 安装 Git 官方版本可以在 Git 官方网站下载&#xff1a;打开 https://git-scm.com/download/win&#xff0c;选择相应版本即可。 Git 安装完成后&#xff0c;可以在开始菜单中看到 Git 的三个启动图标&#xff08;Git Bash、Git CMD、Git GUI&…...

若依 ruoyi-vue SpringBoot highlight-textarea 输入框敏感词关键词高亮标红(二)

参考文章&#xff0c;非常感谢大佬的分享 实现可高亮的输入框 — HighlightTextarea GitHub:highlight-textarea 可看作者上一篇文章 若依 ruoyi-vue SpringBoot聊天敏感词过滤sensitive-word&#xff08;一&#xff09; 效果图 审核时&#xff0c;输入框高亮敏感词&#xff…...

33 IRF配置思路

IRF配置思路网络括谱图 主 Ten-GigabitEthernet 1/0/49 Ten-GigabitEthernet 1/0/50 Ten-GigabitEthernet 1/0/51 备 Ten-GigabitEthernet 2/0/49 Ten-GigabitEthernet 2/0/50 Ten-GigabitEthernet 2/0/51 思路 主 1 利用console线进入设备的命令行页面去更改…...

Dify中的RAG和知识库

一.RAG 基本架构 当用户提问 “美国总统是谁&#xff1f;” 时&#xff0c;系统并不是将问题直接交给大模型来回答&#xff0c;而是先将用户问题在知识库中进行向量搜索&#xff0c;通过语义相似度匹配的方式查询到相关的内容&#xff08;拜登是美国现任第46届总统…&#xff0…...

vue3 + i18n 中英文切换

第一步&#xff1a;安装vue-i18n npm install vue-i18n 第二步&#xff1a;配置语言包及js文件 目录如下&#xff1a; 英文语言包 en.js // lang/en.js - 英文语言包 export default {menu: { 库房管理: Warehouse Management,入库检测: Incoming Inspection, 设…...

one-hot-zhu案例

# 导入用于对象保存与加载的joblib # from sklearn.externals import joblib import joblib # 导入keras中的词汇映射器Tokenizer from keras.preprocessing.text import Tokenizer def one_hot_01(): # 1 准备语料 vocabs # vocabs {“周杰伦”, “陈奕迅”, “王力宏”, “…...

数据库课设---酒店管理系统(MySQL、VBNet)

目录 一. 知识技术 二. 需求分析 2.1 功能需求 2.2 数据需求 三. 数据流图与数据字典 3.1 数据流图 3.1.1 业务流图 3.1.2 数据流图 3.1.3 关系图 3.2 数据字典 四. 数据库设计 4.1 概念模型设计 4.2 逻辑模型设计 4.3 数据库实现 …...

NLP入门——前馈词袋分类模型的搭建、训练与预测

模型的搭建 线性层 >>> import torch >>> from torch import nn >>> class DBG(nn.Module): ... def forward(self,x): ... print(x.size()) ... return x ... >>> tmod nn.Sequential(nn.Linear(3,4),DB…...

GD32F303RET6读取SGM58031电压值

1、SGM58031芯片详解 &#xff08;1&#xff09;SGM58031是一款低功耗&#xff0c;16位精度&#xff0c;delta-sigma (ΔΣ)模数转换器(ADC)。它从3V到5.5V供电。 &#xff08;2&#xff09;SGM58031包含一个片上参考和振荡器。它有一个I2C兼容接口&#xff0c;可以选择四个I2…...

Pandas实战指南:any()函数深度解析与高效应用

Pandas实战指南&#xff1a;any()函数深度解析与高效应用 引言 在数据分析和处理过程中&#xff0c;经常需要快速检查数据集中是否存在满足特定条件的元素。Pandas库中的any()函数正是这样一个强大的工具&#xff0c;它可以帮助我们沿着指定的轴检查是否至少有一个元素满足某…...

ClickHouse中PRIMARY KEY和ORDER BY关键字的关系

在ClickHouse中&#xff0c;PRIMARY KEY和ORDER BY关键字在表的创建过程中扮演着重要的角色&#xff0c;它们共同决定了数据在物理存储上的排序方式&#xff0c;这对查询性能有着直接的影响。理解它们之间的关系对于设计高效的ClickHouse表结构至关重要。 ORDER BY ORDER BY定…...

android 图片轮播

在Android中&#xff0c;实现图片轮播&#xff08;也称为图片滑动或图片轮转&#xff09;通常涉及到使用ViewPager、RecyclerView配合PagerAdapter、RecyclerView.Adapter或者第三方库如Glide、Picasso来处理图片加载&#xff0c;以及一个定时器&#xff08;如Handler、Timer、…...

进度条提示-在python程序中使用避免我误以为挂掉了

使用库tqdm 你还可以手写一点&#xff0c;反正只要是输出点什么东西都可以&#xff1b; Demo from chatgpt import time from tqdm import tqdm# 示例函数&#xff0c;模拟长时间运行的任务 def long_running_task():total_steps 100for step in tqdm(range(total_steps), …...

【案例】python集成OCR识别工具调研

目录 一、前言二、Tesseract_OCR2.1、安装过程2.2、python代码使用三、PaddleOCR3.1、安装过程3.2、python代码使用四、EasyOCR五、ddddOCR六、CnOCR七、总结一、前言 因项目需要OCR识别能力,且要支持私有化部署。本文将对比市场一些开源的OCR识别工具,从中选择适合项目需要…...

第一关:Linux基础知识

Linux基础知识目录 前言LinuxInternStudio 关卡1. InternStudio开发机介绍2. SSH及端口映射2.1 什么是SSH&#xff1f;2.2 如何使用SSH远程连接开发机&#xff1f;2.2.1 使用密码进行SSH远程连接2.2.2 配置SSH密钥进行SSH远程连接2.2.3 使用VScode进行SSH远程连接 2.3. 端口映射…...

qt 自定义信号和槽举例

在Qt中&#xff0c;自定义信号和槽是对象间通信的一种强大机制。以下是一个简单的例子&#xff0c;展示了如何定义和使用自定义信号和槽。 首先&#xff0c;我们定义一个简单的Worker类&#xff0c;它有一个自定义信号workCompleted&#xff0c;当某个任务完成时&#xff0c;这…...

编程语言与数据结构的关系:深度解析与探索

编程语言与数据结构的关系&#xff1a;深度解析与探索 在编程的世界中&#xff0c;编程语言和数据结构是两个不可或缺的元素。它们之间既相互依存&#xff0c;又各自独立&#xff0c;共同构成了编程的核心。本文将深入探索编程语言与数据结构之间的复杂关系&#xff0c;从四个…...

超短脉冲激光自聚焦效应

前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应&#xff0c;这是一种非线性光学现象&#xff0c;主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场&#xff0c;对材料产生非线性响应&#xff0c;可能…...

CVPR 2025 MIMO: 支持视觉指代和像素grounding 的医学视觉语言模型

CVPR 2025 | MIMO&#xff1a;支持视觉指代和像素对齐的医学视觉语言模型 论文信息 标题&#xff1a;MIMO: A medical vision language model with visual referring multimodal input and pixel grounding multimodal output作者&#xff1a;Yanyuan Chen, Dexuan Xu, Yu Hu…...

基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容

基于 ​UniApp + WebSocket​实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配​微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...

2.Vue编写一个app

1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...

全球首个30米分辨率湿地数据集(2000—2022)

数据简介 今天我们分享的数据是全球30米分辨率湿地数据集&#xff0c;包含8种湿地亚类&#xff0c;该数据以0.5X0.5的瓦片存储&#xff0c;我们整理了所有属于中国的瓦片名称与其对应省份&#xff0c;方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...

selenium学习实战【Python爬虫】

selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...

安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)

船舶制造装配管理现状&#xff1a;装配工作依赖人工经验&#xff0c;装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书&#xff0c;但在实际执行中&#xff0c;工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...

智能AI电话机器人系统的识别能力现状与发展水平

一、引言 随着人工智能技术的飞速发展&#xff0c;AI电话机器人系统已经从简单的自动应答工具演变为具备复杂交互能力的智能助手。这类系统结合了语音识别、自然语言处理、情感计算和机器学习等多项前沿技术&#xff0c;在客户服务、营销推广、信息查询等领域发挥着越来越重要…...

SQL慢可能是触发了ring buffer

简介 最近在进行 postgresql 性能排查的时候,发现 PG 在某一个时间并行执行的 SQL 变得特别慢。最后通过监控监观察到并行发起得时间 buffers_alloc 就急速上升,且低水位伴随在整个慢 SQL,一直是 buferIO 的等待事件,此时也没有其他会话的争抢。SQL 虽然不是高效 SQL ,但…...

搭建DNS域名解析服务器(正向解析资源文件)

正向解析资源文件 1&#xff09;准备工作 服务端及客户端都关闭安全软件 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 2&#xff09;服务端安装软件&#xff1a;bind 1.配置yum源 [rootlocalhost ~]# cat /etc/yum.repos.d/base.repo [Base…...