分布式与一致性协议之一致哈希算法(二)

一致哈希算法

使用哈希算法有什么问题

通过哈希算法,每个key都可以寻址到对应的服务器,比如,查询key是key-01,计算公式为hash(key-01)%3,警告过计算寻址到了编号为1的服务器节点A,如图所示。
在这里插入图片描述

但如果服务器数量发生变化,我们基于新的服务器数量来执行哈希算法时,就会出现路由寻址失败的秦广,导致Proxy无法找到之前寻址到的那个服务器节点,这是为什么呢?
想象以下,加入3个节点不能满足当前的业务虚要,这时我们增加了一个节点,节点数量从3变为4,那么之前的hash(key-01)%3=1就变成了hash(key-01)%4=X,因为取模运算发生了变化,所以这个X大概率不是1(可能是2),这时你再查询,就会找不到数据,因为key-01对应的数据存储再节点A上,而不是节点B上,如图所示。
在这里插入图片描述

同样的道理,如果我们需要下线1个服务器节点(也就是缩容),也会存在类似的问题。而解决这个问题的办法在于我们要迁移数据,基于新的计算公式hash(key-01)%4来重新对数据和节点做映射。需要注意的是,数据的迁移成本是非常高的。
为了便于理解,我们用一个示例来说明。对于1000万个key 的3节点KV存储,如果我们增加1个节点,即3节点集群变为4节点集群,则需要迁移75%的数据,如代码所示

package mainimport (
"flag"
"fmt"
)var keysPtr = flag.Int("keys", 10000000, "key number")
var nodesPtr = flag.Int("nodes", 3, "node number of old cluster")
var newNodesPtr = flag.Int("new-nodes", 4, "node number of new cluster")func hash(key int, nodes int) int {
return key % nodes
}func main() {flag.Parse()
var keys = *keysPtr
var nodes = *nodesPtr
var newNodes = *newNodesPtrmigrate := 0
for i := 0; i < keys; i++ {
if hash(i, nodes) != hash(i, newNodes) {
migrate++
}
}migrateRatio := float64(migrate) / float64(keys)
fmt.Printf("%f%%\n", migrateRatio*100)
}
go run ./hash.go -keys 10000000 -nodes 3 -new-nodes 4
74.999980%

从示例代码的输出可以看到,迁移成本非常高昂,这在实际生产环境中也是无法想象的

如何使用一致哈希算法实现哈希寻址

一致哈希算法也采用取模运算,但与哈希算法是对节点的数量进行取模不同,一致哈希算法是对2 ^ 32进行取模。你可以想象以下,一致哈希算法是将整个哈希空间组织成一个虚拟的圆环,也就是哈希换,如图所示,在这里插入图片描述
从图中可以看到,哈希环的空间是按顺时针方向组织的,圆环的正上方点的点代表0,0点右侧的第一个点代表1,以此类推,2、3、4、5、6…知道2 ^ 32-1,也就是说0点左侧的第一个点代表2^32-1.在一致哈希算法中,你可以通过执行哈希算法(为了演示方便,假设哈希算法函数为c-hash())将节点映射到哈希环上,比如选择节点的主机名作为参数进行c-hash()函数运算,确定每个节点在哈希环上的位置,如图所示。在这里插入图片描述
当需要对指定的key的值进行读写的时候,你可以通过下面两步进行寻址:

  • 1.首先,将key作为参数进行c-hash()函数运算,计算哈希值,并确定此key在环上的位置
  • 2.然后,从这个位置沿着哈希环顺时针"行走",遇到的第一节点就是key对应的节点
    为了更好地理解如何通过一致哈希寻址,用一个示例来说明。假设key-01、key-02、key-03 3个key经过哈希算法c-hash()函数计算后,在哈希环上的位置如图所示。
    在这里插入图片描述

那么根据一致哈希算法,key-01将寻址到节点A,key-02将寻址到节点B,key-03将寻址到节点C.你可能会问,那一致哈希是如何避免哈希算法的问题的呢?
假设现在有一个节点故障了(比如节点C),如图所示。在这里插入图片描述

可以看到,key-01和key-02不会受到影响,而key-03得寻址将被重定位到A.一般来说,在一致哈希算法中,如果某个节点宕机不可用了,那么受影响的数据仅仅是会寻址到此节点和前一节点之间的数据。比如当节点C宕机时,受影响的数据是会寻址到节点B和节点C之间的数据(例如key-03),而寻址到其他哈希环空间的数据(例如key-01)不会受到影响。如果此时集群不能满足业务的需求,则需要扩容一个节点(也就是增加一个节点,比如D),如图所示.
在这里插入图片描述

可以看到,key-01、key-02不会受到影响,而key-03的寻址被重定位到新节点D.一般而言,在一致哈希算法中,如果增加一个节点,受影响的数据仅仅是会寻址到新节点和前一节点之间的数据,其他数据则不会受到影响。

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

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

相关文章

vue3使用el-autocomplete请求远程数据

服务器端 RestController RequestMapping("/teacher") public class TeacherController {Resourceprivate TeacherService teacherService;GetMapping({"/v1/getTop10TeacherByName/","/v1/getTop10TeacherByName/{name}"})public ResultBean&l…

快速批量重命名文件(夹)

首先&#xff0c;需要用到的这个工具&#xff1a; 度娘网盘 提取码&#xff1a;qwu2 蓝奏云 提取码&#xff1a;2r1z 我这里处理这4个文本&#xff0c;实际可以处理任意数量的文本和文件夹 1、打开工具&#xff0c;进入文件批量复制版块 2、点击“重命名” 3、把要重命名的…

使用Python爬取淘宝商品并做数据分析

使用Python爬取淘宝商品并做数据分析&#xff0c;可以按照以下步骤进行操作&#xff1a; 确定需求&#xff1a;确定要爬取的淘宝商品的种类、数量、关键词等信息。 编写爬虫程序&#xff1a;使用Python编写爬虫程序&#xff0c;通过模拟浏览器请求&#xff0c;获取淘宝商品的页…

Docker 中的 Nginx 服务为什么要启用 HTTPS

一安装容器 1 安装docker-20.10.17 2 安装所需的依赖 sudo yum install -y yum-utils device-mapper-persistent-data lvm23 添加Docker官方仓库 sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo4 安装Docker CE 20.10.17 s…

第182期 23ai:惊喜的全功能缓存True Cache-2安装部署(20240505)

数据库管理182期 2024-05-05 数据库管理-第182期 23ai:惊喜的全功能缓存True Cache-2安装部署&#xff08;20240505&#xff09;1 主机配置2 操作系统配置2.1 基础配置2.2 配置hosts2.3 安装preinstall RPM包2.4 创建目录2.5 配置环境变量 3 部署数据库3.1 部署DB软件3.2 创建监…

机器学习:基于K-近邻(KNN)、高斯贝叶斯(GaussianNB)、SVC、随机森林(RF)、梯度提升树(GBDT)对葡萄酒质量进行预测

前言 系列专栏&#xff1a;机器学习&#xff1a;高级应用与实践【项目实战100】【2024】✨︎ 在本专栏中不仅包含一些适合初学者的最新机器学习项目&#xff0c;每个项目都处理一组不同的问题&#xff0c;包括监督和无监督学习、分类、回归和聚类&#xff0c;而且涉及创建深度学…

linux上如何排查JVM内存过高?

怎么排查JVM内存过高&#xff1f; 前言&#xff1a; 想必工作一两年以后的同学都会逐渐面临到&#xff0c;jvm等问题&#xff0c;但是可能苦于无法熟练的使用一些工具&#xff1b;本文将介绍几个比较常用分析工具的使用方法&#xff0c;带着大家一步步定位分析问题。 1、top 查…

springmvc下

第二类初始化操作 multipartResolver应用 localeResolver应用 themeResolver应用 handlerMapping应用 handlerAdapter应用 handlerExceptionReslver requestToViewNameTranslator应用 viewResolver应用 flashMapManager应用 dispatcherServlet逻辑处理 processRequest处理web请…

目标跟踪—卡尔曼滤波

目标跟踪—卡尔曼滤波 卡尔曼滤波引入 滤波是将信号中特定波段频率滤除的操作&#xff0c;是抑制和防止干扰的一项重要措施。是根据观察某一随机过程的结果&#xff0c;对另一与之有关的随机过程进行估计的概率理论与方法。 历史上最早考虑的是维纳滤波&#xff0c;后来R.E.卡…

【C语言】分支和循环(上)

【C语言】分支和循环&#xff08;上&#xff09; 1、if语句1.2 else1.3分支中包含多条语句1.4嵌套if1.5悬空else问题 2、关系操作符3、条件操作符4、逻辑操作符&#xff1a;与、或、非&#xff08;取反&#xff09;&#xff08;&&&#xff0c;||&#xff0c;&#xff0…

小猪APP分发平台 – 掌握移动应用的推广新途径

在移动互联网高速发展的背景下小猪APP分发平台 – 掌握移动应用的推广新途径&#xff0c;app分发已成为开发者和企业关注的重点。小猪APP分发平台作为行业内的新星小猪APP分发平台 – 掌握移动应用的推广新途径&#xff0c;提供了一个创新且高效的方式帮助开发者推广他们的应用…

ZOC8 for Mac v8.08.1激活版:卓越性能的SSH客户端

在远程连接和管理的世界中&#xff0c;ZOC8 for Mac以其卓越的性能和丰富的功能&#xff0c;成为了众多专业人士的首选SSH客户端。它支持SSH1、SSH2、Telnet、Rlogin、Serial等多种协议&#xff0c;让您轻松连接到远程服务器。ZOC8拥有简洁直观的界面和强大的功能设置&#xff…

SQL 基础 | JOIN 操作介绍

在SQL中&#xff0c;JOIN是一种强大的功能&#xff0c;用于将两个或多个表中的行结合起来&#xff0c;基于相关的列之间的关系。 JOIN操作通常用在SELECT语句中&#xff0c;以便从多个表中检索数据。 以下是几种基本的JOIN类型以及它们的用法&#xff1a; INNER JOIN&#xff1…

STM32 串口IDLE接收空闲中断+DMA

参考 http://t.csdnimg.cn/fAV38 1.基础知识 STM32 IDLE 接收空闲中断 功能&#xff1a; 在使用串口接受字符串时&#xff0c;可以使用空闲中断&#xff08;IDLEIE置1&#xff0c;即可使能空闲中断&#xff09;&#xff0c;这样在接收完一个字符串&#xff0c;进入空闲状态时&…

(三)Appdesigner-界面转换及数据导入和保存

提示&#xff1a;文章为系列文章&#xff0c;可以在对应学习专栏里面进行学习。对应资源已上传 目录 前言 一、Appdesigner是什么&#xff1f; 二、界面切换 三、数据导入及保存 &#xff08;一&#xff09;数据导入 &#xff08;二&#xff09;数据保存 总结 前言 Appd…

ubuntu搭建kms服务器

1.下载kms开源包(如果提示找不到wget命令的话:apt install wget): wget https://github.com/Wind4/vlmcsd/releases/download/svn1111/binaries.tar.gz2.解压: tar -xzvf binaries.tar.gz接着cd 进入 Linux/intel/static/ 文件夹下: 3.选择对应的文件&#xff0c;这里我们选…

C++:继承-继承权限

在C中&#xff0c;类的权限分为公有、私有和保护三种。这些权限控制了类的成员&#xff08;数据成员和成员函数&#xff09;对外部代码的可见性和访问性。 公有&#xff08;public&#xff09;权限&#xff1a; 在公有权限下声明的成员可以被类的外部代码直接访问&#xff1b;公…

第十篇:深入文件夹:Python中的文件管理和自动化技术

深入文件夹&#xff1a;Python中的文件管理和自动化技术 1 文件系统基础操作 在今天的技术博客中&#xff0c;我们将深入探讨Python中的文件系统基础操作。文件系统对于任何操作系统都是不可或缺的组成部分&#xff0c;它管理着数据的存储、检索以及维护。Python通过其标准库中…

【Linux 进程】 自定义shell

目录 关于shell 1.打印提示符&&获取用户命令字符​编辑 2.分割字符串 3.检查是否为内建命令 cd命令 export命令 echo命令 1.输出最后一个执行的命令的状态退出码&#xff08;返回码&#xff09; 2.输出指定环境变量 4.执行外部命令 关于shell Shell 是计算机操…

免费开源,无需 GPU,本地化部署大语言模型的对话系统

免费开源&#xff0c;无需 GPU&#xff0c;本地化部署大语言模型的对话系统 分类 编程技术 项目名: FreeAskInternet -- 本地化部署大语言模型的对话系统 Github 开源地址&#xff1a; https://github.com/nashsu/FreeAskInternet FreeAskInternet 是一个免费开源的工具&am…