一致性哈希算法总结

news2024/11/26 8:27:11

title: 一致性哈希算法总结
date: 2023-05-22 11:25:13
tags:

  • 算法
    categories:
  • 数据结构与算法
    cover: https://cover.png
    feature: false

1. 背景

假设,我们有三台缓存服务器,用于缓存图片,我们为这三台缓存服务器编号为 0 号、1 号、2 号,现在,有 3 万张图片需要缓存,我们希望这些图片被均匀的缓存到这 3 台服务器上,以便它们能够分摊缓存的压力。也就是说,我们希望每台服务器能够缓存 1 万张左右的图片,那么,我们应该怎样做呢?

如果我们没有任何规律的将 3 万张图片平均的缓存在 3 台服务器上,可以满足我们的要求吗?可以!但是如果这样做,当我们需要访问某个缓存项时,则需要遍历 3 台缓存服务器,从 3 万个缓存项中找到我们需要访问的缓存,遍历的过程效率太低,时间太长,当我们找到需要访问的缓存项时,时长可能是不能被接受的,也就失去了缓存的意义,缓存的目的就是提高速度,改善用户体验,减轻后端服务器压力,如果每次访问一个缓存项都需要遍历所有缓存服务器的所有缓存项,想想就觉得很累,那么,我们该怎么办呢?

原始的做法是对缓存项的键进行哈希,将 hash 后的结果对缓存服务器的数量进行取模操作,通过取模后的结果,决定缓存项将会缓存在哪一台服务器上,比如假设我们使用图片名称作为访问图片的 key,假设图片名称是不重复的,那么,我们可以使用如下公式,计算出图片应该存放在哪台服务器上

hash(图片名称)% N

因为假设图片的名称是不重复的,所以,当我们对同一个图片名称做相同的哈希计算时,得出的结果应该是不变的,如果我们有 3 台服务器,使用哈希后的结果对 3 求余,那么余数一定是 0、1 或者 2,正好与我们之前的服务器编号相同,如果求余的结果为 0, 我们就把当前图片名称对应的图片缓存在 0 号服务器上,如果余数为 1,就把当前图片名对应的图片缓存在 1 号服务器上,如果余数为 2,同理

那么,当我们访问任意一个图片的时候,只要再次对图片名称进行上述运算,即可得出对应的图片应该存放在哪一台缓存服务器上,我们只要在这一台服务器上查找图片即可,如果图片在对应的服务器上不存在,则证明对应的图片没有被缓存,也不用再去遍历其他缓存服务器了,通过这样的方法,即可将 3 万张图片随机的分布到 3 台缓存服务器上了,而且下次访问某张图片时,直接能够判断出该图片应该存在于哪台缓存服务器上,这样就能满足我们的需求了,我们暂时称上述算法为 HASH 算法或者取模算法

但是,使用上述 HASH 算法进行缓存时,会出现一些缺陷,试想一下,如果 3 台缓存服务器已经不能满足我们的缓存需求,那么我们应该怎么做呢?没错,很简单,多增加两台缓存服务器不就行了,假设,我们增加了一台缓存服务器,那么缓存服务器的数量就由 3 台变成了 4 台,此时,如果仍然使用上述方法对同一张图片进行缓存,那么这张图片所在的服务器编号必定与原来 3 台服务器时所在的服务器编号不同,因为除数由 3 变为了 4,被除数不变的情况下,余数肯定不同,这种情况带来的结果就是当服务器数量变动时,所有缓存的位置都要发生改变,换句话说,当服务器数量发生改变时,所有缓存在一定时间内是失效的,当应用无法从缓存中获取数据时,则会向后端服务器请求数据

同理,假设 3 台缓存中突然有一台缓存服务器出现了故障,无法进行缓存,那么我们则需要将故障机器移除,但是如果移除了一台缓存服务器,那么缓存服务器数量从 3 台变为 2 台,如果想要访问一张图片,这张图片的缓存位置必定会发生改变,以前缓存的图片也会失去缓存的作用与意义,由于大量缓存在同一时间失效,造成了缓存的雪崩,此时前端缓存已经无法起到承担部分压力的作用,后端服务器将会承受巨大的压力,整个系统很有可能被压垮,所以,我们应该想办法不让这种情况发生,但是由于上述 HASH 算法本身的缘故,使用取模法进行缓存时,这种情况是无法避免的,为了解决这些问题,一致性哈希算法诞生了

2. 基本概念

其实,一致性哈希算法也是使用取模的方法,只是,刚才描述的取模法是对服务器的数量进行取模,而一致性哈希算法是对 2 32 2^{32} 232 取模

首先,我们把二的三十二次方想象成一个圆,就像钟表一样,钟表的圆可以理解成由 60 个点组成的圆,而此处我们把这个圆想象成由 2 32 2^{32} 232 个点组成的圆,示意图如下:

圆环的正上方的点代表 0,0 点右侧的第一个点代表 1,以此类推,2、3、4、5、6……直到 2 32 − 1 2^{32}-1 2321,也就是说 0 点左侧的第一个点代表 2 32 − 1 2^{32}-1 2321

我们把这个由 2 的 32 次方个点组成的圆环称为 hash 环

那么,一致性哈希算法与上图中的圆环有什么关系呢?

仍然以之前描述的场景为例,假设我们有 3 台缓存服务器,服务器 A、服务器 B、服务器 C,那么,在生产环境中,这三台服务器肯定有自己的 IP 地址,我们使用它们各自的 IP 地址进行哈希计算,使用哈希后的结果对 2 32 2^{32} 232 取模,可以使用如下公式示意

hash(服务器 A 的 IP 地址) % 2^32

通过上述公式算出的结果一定是一个 0 到 2 32 − 1 2^{32}-1 2321 之间的一个整数,我们就用算出的这个整数,代表服务器 A,既然这个整数肯定处于 0 到 2 32 − 1 2^{32}-1 2321 之间,那么,上图中的 hash 环上必定有一个点与这个整数对应,而我们刚才已经说明,使用这个整数代表服务器 A,那么,服务器 A 就可以映射到这个环上,用下图示意

同理,服务器 B 与服务器 C 也可以通过相同的方法映射到上图中的 hash 环中

假设 3 台服务器映射到 hash 环上以后如上图所示(当然,这是理想的情况),到目前为止,我们已经把缓存服务器与 hash 环联系在了一起,我们通过上述方法,把缓存服务器映射到了 hash 环上,那么使用同样的方法,我们也可以将需要缓存的对象映射到 hash 环上

我们需要使用缓存服务器缓存图片,而且我们仍然使用图片的名称作为找到图片的 key,那么我们使用如下公式可以将图片映射到上图中的 hash 环上

hash(图片名称) % 2^32

映射后的示意图如下,下图中的橘黄色圆形表示图片

现在服务器与图片都被映射到了 hash 环上,那么上图中的这个图片到底应该被缓存到哪一台服务器上呢?上图中的图片将会被缓存到服务器 A 上,为什么呢?因为从图片的位置开始,沿顺时针方向遇到的第一个服务器就是 A 服务器,所以,上图中的图片将会被缓存到服务器 A 上,如下图所示

一致性哈希算法就是通过这种方法,判断一个对象应该被缓存到哪台服务器上的,将缓存服务器与被缓存对象都映射到 hash 环上以后,从被缓存对象的位置出发,沿顺时针方向遇到的第一个服务器,就是当前对象将要缓存于的服务器,由于被缓存对象与服务器 hash 后的值是固定的,所以,在服务器不变的情况下,一张图片必定会被缓存到固定的服务器上,那么,当下次想要访问这张图片时,只要再次使用相同的算法进行计算,即可算出这个图片被缓存在哪个服务器上,直接去对应的服务器查找对应的图片即可

刚才的示例只使用了一张图片进行演示,假设有四张图片需要缓存,示意图如下

1 号、2 号图片将会被缓存到服务器 A 上,3 号图片将会被缓存到服务器 B 上,4 号图片将会被缓存到服务器 C 上

3. 优点

假设,服务器 B 出现了故障,我们现在需要将服务器 B 移除,那么,我们将上图中的服务器 B 从 hash 环上移除即可,移除服务器 B 以后示意图如下

在服务器 B 未移除时,图片 3 应该被缓存到服务器 B 中,可是当服务器 B 移除以后,按照之前描述的一致性哈希算法的规则,图片 3 应该被缓存到服务器 C 中,因为从图片 3 的位置出发,沿顺时针方向遇到的第一个缓存服务器节点就是服务器 C,也就是说,如果服务器 B 出现故障被移除时,图片 3 的缓存位置会发生改变

但是,图片 4 仍然会被缓存到服务器 C 中,图片 1 与图片 2 仍然会被缓存到服务器 A 中,这与服务器 B 移除之前并没有任何区别,这就是一致性哈希算法的优点,如果使用之前的 hash 算法,服务器数量发生改变时,所有服务器的所有缓存在同一时间失效了,而使用一致性哈希算法时,服务器的数量如果发生改变,并不是所有缓存都会失效,而是只有部分缓存会失效,前端的缓存仍然能分担整个系统的压力,而不至于所有压力都在同一时间集中到后端服务器上

4. hash 环的偏斜

在介绍一致性哈希的概念时,我们理想化的将 3 台服务器均匀的映射到了 hash 环上,如下图所示

在实际的映射中,服务器可能会被映射成如下模样

如果服务器被映射成上图中的模样,那么被缓存的对象很有可能大部分集中缓存在某一台服务器上,如下图所示

上图中,1 号、2 号、3 号、4 号、6 号图片均被缓存在了服务器 A 上,只有 5 号图片被缓存在了服务器 B 上,服务器 C 上甚至没有缓存任何图片,如果出现上图中的情况,A、B、C 三台服务器并没有被合理的平均的充分利用,缓存分布的极度不均匀,而且,如果此时服务器 A 出现故障,那么失效缓存的数量也将达到最大值,在极端情况下,仍然有可能引起系统的崩溃,上图中的情况则被称之为 hash 环的偏斜,那么,我们应该怎样防止 hash 环的偏斜呢?

5. 虚拟节点

由于我们只有 3 台服务器,当我们把服务器映射到 hash 环上的时候,很有可能出现 hash 环偏斜的情况,当 hash 环偏斜以后,缓存往往会极度不均衡的分布在各服务器上,

如果想要均衡的将缓存分布到 3 台服务器上,最好能让这 3 台服务器尽量多的、均匀的出现在 hash 环上,但是,真实的服务器资源只有 3 台,我们怎样凭空的让它们多起来呢,既然没有多余的真正的物理服务器节点,我们就只能将现有的物理节点通过虚拟的方法复制出来,这些由实际节点虚拟复制而来的节点被称为”虚拟节点”。加入虚拟节点以后的 hash 环如下

“虚拟节点”是”实际节点”(实际的物理服务器)在 hash 环上的复制品,一个实际节点可以对应多个虚拟节点

从上图可以看出,A、B、C 三台服务器分别虚拟出了一个虚拟节点,当然,如果你需要,也可以虚拟出更多的虚拟节点。引入虚拟节点的概念后,缓存的分布就均衡多了,上图中,1 号、3 号图片被缓存在服务器 A 中,5 号、4 号图片被缓存在服务器 B 中,6 号、2 号图片被缓存在服务器 C 中,如果你还不放心,可以虚拟出更多的虚拟节点,以便减小 hash 环偏斜所带来的影响,虚拟节点越多,hash 环上的节点就越多,缓存被均匀分布的概率就越大

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/764730.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

使用Vue + el-form + rules实现图书信息录入功能实战

前言 上节回顾 转眼2023年已经过去一半了,我咋记得2022年刚过去呢,有时候在前端打版本的时候我还不小心写成2022啥啥啥呢,写完才发现自己自己写错了,应该是2023,真是时光一去不复回,往事只能回味啊。 上…

基于FPGA的视频接口之SDI编码

简介 SDI接口是一种“数字分量串行接口”,对于详细解释,可以在Google下SDI,我就不当网络的搬运工了,划重点的是,SDI常见的分为3种模式,即SD-SDI、HD-SDI和3G-SDI,以及升级版12G-SDI。 SD-SDI很少有人用,我怀疑可能是640x512的说法,270Mb/s的数据传输量 HD-SDI最常遇到…

vue3 实现 Map 地图区域组件封装

图例:重庆区域 一、安装echarts 坑:地图echarts版本必须在5.0.0以下,否则不能显示,此处指定安装 echarts4.9.0 即可 cnpm install echarts4.9.0 --save 二、下载 “重庆” 区域地图json文件 下载地址:https://www.…

面向对象基础

目录 1. 类和对象 1.1 什么是对象 1.2 什么是面向对象 1.3 什么是类 1.4 什么是对象的属性 1.5 什么是对象的行为 1.6 类和对象的关系 1.7 类的定义 1.8 对象的使用 2. 成员变量和局部变量 2.1 什么是成员变量和局部变量 2.2 成员变量和局部变量的区别 3. 封装 3.1…

软件测试基础篇(测试系列3)

目录 前言: 1.软件测试的生命周期 2.如何描述一个BUG 3.如何定义BUG的级别 4.BUG的生命周期 5.如何开始第一次测试 6.测试执行和BUG管理 结束语: 前言: 在两节中小编与大家简单的讲解了一些有关于软件测试的基础知识,带着…

Ubuntu开机自启动设置

一、创建执行脚本 这里有两个程序所以编写了两个脚本,第一脚本(master.sh): gnome-terminal -- bash -c "source /home/zyy/anaconda3/bin/activate wood2;cd /home/zyy/pycharmProject/master_program;python main.py > /home/zyy/pycharmProj…

MYSQL常见面试题汇总

Yan-英杰的主页 悟已往之不谏 知来者之可追 C程序员,2024届电子信息研究生 目录 1、三大范式 2、DML 语句和 DDL 语句区别 3、主键和外键的区别 4、drop、delete、truncate 区别 5、基础架构 6、MyISAM 和 InnoDB 有什么区别? 7、推荐自增id作…

HCIP第十天

题目 拓扑图 配置IP地址和环回 启动OSPF,使得AS2内部互相学习到路由 BGP建立对等体关系,R1和R2为EBGP对等体,R234为AS64512的联邦,R567为AS64513的联邦,R7和R8为EBGP对等体,R2-R5和R4-R7为不同联邦的EBGP对…

UML类图的使用

相关概念 1. uml例图使用场景: 类图 类图的使用 1. 在UML类图中表示具体类 具体类在类图中用矩形框表示,矩形框分为三层:第一层是类名字。第二层是类的成员变量;第三层是类的方法。成员变量以及方法前的访问修饰符用符号来表示&#xff1…

文档加密软件有哪些(好用的文档加密软件排名)

在现代社会中,随着信息技术的快速发展,文档的保密性变得越来越重要。为了保护敏感信息不被未经授权的人访问,使用文档加密软件是一种常见的做法。本文将介绍文档加密软件的重要性,并列举一些常见的文档加密软件供读者参考。 文档加…

Git及Tortoisegit使用教程,设置中文

一、到git官网下载GIT 官网 二、下载安装Tortoisegit及中文语言包,Tortoisegit及语言包 语言包下载地址 三、在电脑某个盘的文件里右键 提示未设置git.exe 路径不能继续, 于是去下载git GIT下载 安装Git时, 一直点击 Next > 不要停, 直到结束 此时再跳到TortoiseGit…

[QT编程系列-21]:基本框架 - QT常见数据结构:QString、QList、QVector、QMap、QHash、QSet、QPair详解

目录 1 QString 2 QList 3 QVector 4 QMap 5 QHash 6 QSet 7 QPair 1 QString QString是Qt中用于存储和操作字符串的类。它提供了丰富的字符串处理方法和功能。 以下是QString的一些主要特点和常用操作: 创建QString对象: QString str "H…

远程在Ubuntu20.04安装nvidia显卡驱动

第零步,找人装一个todesk。 在终端运行: ifconfig 记住ip地址,后面要用。 第一步,安装软件: sudo apt-get update sudo apt-get install g gcc make 第二步,下载显卡驱动: 官方驱动 | NVI…

mac批量提取图片文件名到excel?

mac批量提取图片文件名到excel?最近有个小伙伴向我求助一个电脑操作上的问题,问我在Mac电脑上用什么方法可以快速批量的将大量图片的名称一次性提取出来,并且保存到excel表格里。记得小编曾经给大家分享过windows电脑上批量提取文件名称的方法…

关键点检测SIFT算法笔记

SIFT算法 SIFT(Scale Invariant Feature Transform),尺度不变特征变换。具有旋转不变性、尺度不变性、亮度变化保持不变性,是一种非常稳定的局部特征。在目标检测和特征提取方向占据着重要的地位。 SIFT算法所查找到的关键点是一些…

LabVIEW实现基于DCT的野生动物监测无线图像传输

LabVIEW实现基于DCT的野生动物监测无线图像传输 针对野生动物物种数量不断下降的情况,需改进以增强当前野生动物监测系统的能力。目前的系统要求工人进入森林以收集存储在存储卡中的图像数据。这项任务风险很大,而且耗费大量时间。系统也无法提供实时报…

APP加固:助力移动应用安全合规

近日,工业和信息化部发布了2023年第2批侵害用户权益行为的App(SDK)名单,55款App因涉及强制、频繁、过度索取权限等问题而被通报。这一举措进一步凸显了合规对于APP发展的重要性。 根据工业和信息化部的通报,被通报的这…

redolog 、undolog 和binlog

redolog(可以恢复数据,保证数据不丢失) 、undolog(事务回滚) 和binlog(主从同步数据) 脏页 在mysql中,当内存数据页和磁盘数据页上的内容不一致时,则称这个内存页为脏页 脏页什么时候会刷入磁盘? ● redo…

MySQL-DQL-小结

基本查询 条件查询 分组查询 排序查询 分页查询

TX Barcode .NET for WPF Crack

TX Barcode .NET for WPF Crack 用于WPF软件的TX Barcode.NET包括一天完成的功能以及用于WPF的软件的2D条形码控制。 用于WPF的TX Barcode.NET的功能和属性: 它具有以下特性和属性,如: 常见的文字处理功能:它可以为用户和开发人员…