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

一致性Hash算法

Hash算法

哈希算法将任意长度的二进制值映射为较短的固定长度的二进制值,这个小的二进制值称为哈希值。哈希值是一段数据唯一且极其紧凑的数值表示形式。

Hash算法在安全加密领域MD5、SHA等加密算法,数据存储和查找的Hash表等方面均有应用。Hash表的数据查询效率极高,时间复杂度达到O(1)。Hash表通常使用数组下标与数据进行对应的方式进行存储,查找时,通过数据计算出下标(通常是取模)得到下标,然后通过下标直接访问数据。当然,当数组空间有限时,不同的数据计算出相同的下标的情况必然发生,这种情况叫Hash冲突,而解决Hash冲突的常用方法有开放寻址法、拉链法(常用)。

如下图,1和6这两个数据通过对5取模,得到的下标都是1,发生了Hash冲突。

开放寻址法:1放进去了,6再来的时候,向前或者向后找空闲位置存放。但这种方法存在明显缺陷,即数组长度是一定的,当数组被用完时,发生Hash冲突后将无法解决。

拉链法:当发生Hash冲突时,以链表将冲突数据串起来。即数组元素存的一个链表,而不是一个简单数值了。发生Hash冲突时,只需要把新数据放到链表头即可。查找数据时,遍历链表。当然,当链表过长会影响查询性能。此时可以把链表转自平衡二叉查找树(如红黑树,Java8的ConcurrentHashMap 就是使用数组 + 链表 + 红黑树来实现的),这样一来,查询性能将从O(n)降低到 O(log(n))。

Hash算法应用场景

  • 安全加密

日常用户密码加密通常使用的都是 md5、sha等哈希函数,因为不可逆,而且微小的区别加密之后的结果差距很大,所以安全性更好。

  • 唯一标识

比如 URL 字段或者图片字段要求不能重复,这个时候就可以通过对相应字段值做 md5 处理,将数据统一为 32 位长度从数据库索引构建和查询角度效果更好,此外,还可以对文件之类的二进制数据做 md5 处理,作为唯一标识,这样判定重复文件的时候更快捷。

  • 数据校验

比如从网上下载的很多文件(尤其是P2P站点资源),都会包含一个 MD5 值,用于校验下载数据的完整性,避免数据在中途被劫持篡改。

  • 散列函数

  • 负载均衡

对于同一个客户端上的请求,尤其是已登录用户的请求,需要将其会话请求都路由到同一台机器,以保证数据的一致性,这可以借助哈希算法来实现,通过用户 ID 尾号对总机器数取模(取多少位可以根据机器数定),将结果值作为机器编号。

  • 分布式缓存

分布式缓存和其他机器或数据库的分布式不一样,因为每台机器存放的缓存数据不一致,每当缓存机器扩容时,需要对缓存存放机器进行重新索引((参考redis分片集群扩容hash槽重分配) ),这里应用到的也是哈希算法的思想。

普通Hash算法存在的问题

普通Hash算法应用在分布式环境中会存在比较大的问题,比如通过Hash算法将同一会话的客户端路由到相同的服务器上,实现会话保持。当服务器扩缩容时,客户端需要重新取服务器数量进行取模得到Hash索引,确定目标服务器,这时,这些客户端的会话会丢失。(当然,实际的会话保持通常会通过分布式缓存,如redis来实现)。如何将服务器的扩缩容的影响减到最小?这就是一致性Hash算法需要解决的问题。

一致性Hash算法

一致性Hash算法思路如下:

将0到2^32-1作为Hash环,即原本是对有限的服务器数量进行取模,现在是对2^32进行取模,这样取模结果范围更广了,也就是Hash环更大了。这样一来,生产中不可能会使用2^32这么多服务器,扩缩容对客户端的影响是很小的。客户端访问时,是将客户端IP地址对2^32取模,然后得出一个索引值,根据这个值,顺时针找最近的服务器节点,如下图

假设服务器3下线,原来路由到3的客户端重新路由到服务器4,这样一来,影响到的只是原来路由到服务器3的这部分客户端,这在分布式系统里非常有用,避免了大量请求迁移。

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

但是一致性哈希算法在服务节点太少时,容易因为节点分布不均匀而造成数据倾斜问题。比方说按顺时针的情况下,服务节点1和2很近,1到2的区间的客户端由服务器2负责,然后剩下的大区间只能由1负责,这就是数据都倾斜到服务节点1上了。

2)为了解决这种数据倾斜问题,一致性哈希算法引入 了虚拟节点机制,即对每一个服务节点计算多个哈希,每个计算结果位置都放置一个此服务节点,称为虚拟节点。

具体做法可以在服务器IP或主机名的后面增加编号来实现。比如,可以为每台服务器计算三个虚拟节点,于是可以分别诸“节点1的IP#1”、“节点1的IP#2”、“节点1的IP#3”的哈希值,于是形成六个虚拟节点,当客户端被路由到虚拟节点的时候其实是被路由到该虚拟节点所对应的真实节点。

nginx配置一致性Hash负载均衡策略

ngx_http_upstream_consistent_hash模块是一个负载均衡器,通过一致性Hash算法来为客户端选择合适的后端节点。

该模块可以根据配置参数采取不同的方式将请求均匀映射到后面机器。

consistent_hash $remote_addr :根据客户端IP映射

consistent_hash $request_uri :根据客户端uri映射

consistent_hash $args :根据客户端携带的参数进行映射

ngx_http_upstream_consistent_hash是一个第三方模块,需要我们下载安装后使用

1,下载

https://github.com/replay/ngx_http_consistent_hash

2,编译nginx(进入nginx的源码目录)

./configure —add-module=/root/ngx_http_consistent_hash-master
make
make install

3,配置使用

upstream test_server_nodes {#ip_hash;consistent_hash $request_uri;server 192.168.43.71:7771;server 192.168.43.72:7772;
}

相关文章:

一致性Hash算法

Hash算法 哈希算法将任意长度的二进制值映射为较短的固定长度的二进制值,这个小的二进制值称为哈希值。哈希值是一段数据唯一且极其紧凑的数值表示形式。 Hash算法在安全加密领域MD5、SHA等加密算法,数据存储和查找的Hash表等方面均有应用。Hash表的数…...

linux 下如何将/dev/nvme0n1符格式化为空盘符

linux 下如何将/dev/nvme0n1符格式化为空盘符 作者:DPDK开发栏目:公开2023-08-30 03:01254 在Linux下,你可以使用以下步骤将/dev/nvme0n1硬盘格式化为空盘符: 首先,确保你拥有适当的权限。以管理员或root用户身份登录…...

IP地址的最后一位不可以为0或255

说明 通常情况下,IP 地址的最后一位不能为 0 或 255。这是因为这些特定的 IP 地址有特殊用途。 IP 地址的最后一位为 0 通常用作网络地址,表示整个网络的起始地址。IP 地址的最后一位为 255 通常用作广播地址,用于将数据包发送到同一网络中…...

代洋集团:太阳能智能座椅,创新能源的未来篇章

在代洋集团,我们致力于打造一个更绿色,更智能的未来。我们的太阳能智能座椅,就是我们对这一承诺的最新体现。 太阳能智能座椅,一种将绿色能源与智能化完美结合的产品。它利用高效的太阳能电池板,捕获并转化阳光为电能…...

linux服务器安装gitlab

一、安装gitlab sudo yum install curl policycoreutils-python openssh-server openssh-clients sudo systemctl enable sshd sudo systemctl start sshd sudo firewall-cmd --permanent --add-servicehttp curl https://packages.gitlab.com/install/repositories/gitla…...

Tlog SpringBoot3.x版本无法正常打印TraceId等数据

问题:Springboot3.0版本使用Tlog(1.5.1版本)开源框架时无法打印指定参数 原因:在Java EE 8及更高版本中,javax.servlet.*包已经替换成了jakarta.servlet.*,但是tlog官方只更新到了1.5.1版本所以还没支持到…...

基于Spring原生框架构建原生Spring的第一个程序!

😉😉 学习交流群: ✅✅1:这是孙哥suns给大家的福利! ✨✨2:我们免费分享Netty、Dubbo、k8s、Mybatis、Spring...应用和源码级别的视频资料 🥭🥭3:QQ群:583783…...

[个人笔记] Git的CLI笔录

Git - CLI笔录 Git的CLI笔录 Git - CLI笔录Git的CLI笔录 Git的CLI笔录 origin: 表示远程仓库节点名称。 当有多个远程仓库时 可新增远程仓库节点名称如 new_origin | new_remote origin/HEAD: 表示当前Git仓库默认分支的引用,通常指向origin/master或origin/main g…...

如何运行C/C++程序

一、在线运行C/C 码曰 - 让代码在云端多飞一会:这是一个支持C/C,Java,Python等多种语言的在线编程,编译运行,粘贴分享的平台。你可以在这里输入你的代码,点击运行按钮,就可以看到输出结果。你也…...

HTML中input标签的23种type类型

一、概述 随着html5的出现,input标签新增了多种类型,用以接收各种类型的用户输入。其中传统输入控件有10种,新增输入控件有13种。 二、传统类型 传统输入控件有10种,如下所示 text 定义单行文本输入框 password 定义…...

接口多态与方法多态

作者简介:大家好,我是smart哥,前中兴通讯、美团架构师,现某互联网公司CTO 联系qq:184480602,加我进群,大家一起学习,一起进步,一起对抗互联网寒冬 在上一篇设计山寨版Str…...

js小技巧|如何提取经过Function函数混淆了的代码

关注它,不迷路。 本文章中所有内容仅供学习交流,不可用于任何商业用途和非法用途,否则后果自负,如有侵权,请联系作者立即删除! 1.需求 星友发过来一个混淆代码,打开一看,长这…...

【GitLab】流水线入门

(꒪ꇴ꒪ ),Hello我是祐言QAQ我的博客主页:C/C语言,数据结构,Linux基础,ARM开发板,网络编程等领域UP🌍快上🚘,一起学习,让我们成为一个强大的攻城狮&#xff0…...

es 中文前缀短语匹配(搜索智能补全)

需求:es进行前缀匹配,用来进行智能补全 过程:es正常的prefix只能进行词语匹配,而中文的分词大部分按字分词,不按语义分词,所以无法搜索出正确的前缀匹配,而能进行短语匹配的match_phrase_prefix…...

机器学习之决策树及随机森林

决策树 概念 决策树(Decision Tree)是一种常见的机器学习算法,用于分类和回归任务。它是一种树状结构,其中每个内部节点表示一个特征或属性,每个分支代表一个决策规则,而每个叶节点表示一个输出标签或值。 构建决策树过程 构建决策树的过程通常涉及以下步骤: 数据准…...

用通俗的方式讲解Transformer:从Word2Vec、Seq2Seq逐步理解到GPT、BERT

直到今天早上,刷到CSDN一篇讲BERT的文章,号称一文读懂,我读下来之后,假定我是初学者,读不懂。 关于BERT的笔记,其实一两年前就想写了,迟迟没动笔的原因是国内外已经有很多不错的资料&#xff0…...

数据结构-01-数组

每一种编程语言中,基本都会有数组这种数据类型。不过,它不仅仅是一种编程语言中的数据类型,还是一种最基础的数据结构。 1-数组的概念和特性 数组(Array)是一种线性表数据结构。它用一组连续的内存空间,来…...

甘草书店记: 2023年10月11日 星期三 晴 「做有光的人,照亮他人,也引人同行」

发了两篇《甘草书店记》,书店计划公之于众,收获了不少人的赞扬和鼓励,来自生活中的友人,来自麦田的客户和朋友,来自图书界的同行前辈,也来自商界的同仁。其中,最特别留言来自甘草书店投资方的张…...

让 OpenAI GPT4 出 10 道题测试其他开源大语言模型

让 OpenAI GPT4 出 10 道题测试其他开源大语言模型 1. 中文题目及答案2. 日文题目及答案3. 英文题目及答案 1. 中文题目及答案 数学题:一个矩形的长是10厘米,宽是5厘米,求它的面积。 答案:面积 长 x 宽 10厘米 x 5厘米 50平方厘…...

动态库与静态库

1. 库 是代码的二进制的封装形式 在其他的源代码或库中,可以直接调用库的,但是又看不到它 没有公开源代码 库的这种实现方法有利于模块化 而且只要接口合理 不影响库的使用的 sum.c sum.h int sum(int a,int b) { return ab; } xxx.c 需要使用…...

【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)

服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...

蓝桥杯 2024 15届国赛 A组 儿童节快乐

P10576 [蓝桥杯 2024 国 A] 儿童节快乐 题目描述 五彩斑斓的气球在蓝天下悠然飘荡,轻快的音乐在耳边持续回荡,小朋友们手牵着手一同畅快欢笑。在这样一片安乐祥和的氛围下,六一来了。 今天是六一儿童节,小蓝老师为了让大家在节…...

Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具

文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...

【论文笔记】若干矿井粉尘检测算法概述

总的来说,传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度,通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...

汇编常见指令

汇编常见指令 一、数据传送指令 指令功能示例说明MOV数据传送MOV EAX, 10将立即数 10 送入 EAXMOV [EBX], EAX将 EAX 值存入 EBX 指向的内存LEA加载有效地址LEA EAX, [EBX4]将 EBX4 的地址存入 EAX(不访问内存)XCHG交换数据XCHG EAX, EBX交换 EAX 和 EB…...

k8s业务程序联调工具-KtConnect

概述 原理 工具作用是建立了一个从本地到集群的单向VPN,根据VPN原理,打通两个内网必然需要借助一个公共中继节点,ktconnect工具巧妙的利用k8s原生的portforward能力,简化了建立连接的过程,apiserver间接起到了中继节…...

使用Spring AI和MCP协议构建图片搜索服务

目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式(本地调用) SSE模式(远程调用) 4. 注册工具提…...

【从零学习JVM|第三篇】类的生命周期(高频面试题)

前言: 在Java编程中,类的生命周期是指类从被加载到内存中开始,到被卸载出内存为止的整个过程。了解类的生命周期对于理解Java程序的运行机制以及性能优化非常重要。本文会深入探寻类的生命周期,让读者对此有深刻印象。 目录 ​…...

NPOI Excel用OLE对象的形式插入文件附件以及插入图片

static void Main(string[] args) {XlsWithObjData();Console.WriteLine("输出完成"); }static void XlsWithObjData() {// 创建工作簿和单元格,只有HSSFWorkbook,XSSFWorkbook不可以HSSFWorkbook workbook new HSSFWorkbook();HSSFSheet sheet (HSSFSheet)workboo…...

NPOI操作EXCEL文件 ——CAD C# 二次开发

缺点:dll.版本容易加载错误。CAD加载插件时,没有加载所有类库。插件运行过程中用到某个类库,会从CAD的安装目录找,找不到就报错了。 【方案2】让CAD在加载过程中把类库加载到内存 【方案3】是发现缺少了哪个库,就用插件程序加载进…...