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

news2024/12/25 0:56:21

一致哈希算法

使用哈希算法有什么问题

通过哈希算法,每个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 main

import (
"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 = *newNodesPtr

migrate := 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.coloradmin.cn/o/1642693.html

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

相关文章

分享一篇关于AGI的短文:苦涩的教训

学习强化学习之父、加拿大计算机科学家理查德萨顿&#xff08; Richard S. Sutton &#xff09;2019年的经典文章《The Bitter Lesson&#xff08;苦涩的教训&#xff09;》。 文章指出&#xff0c;过去70年来AI研究走过的最大弯路&#xff0c;就是过于重视人类既有经验和知识&…

STM32控制DS1302时钟模块获取实时时间

时间记录&#xff1a;2024/3/30 一、知识点 &#xff08;1&#xff09;读写数据时序&#xff08;伪SPI协议&#xff09; 1.1 读写时序默认电平均为SCLK线低电平&#xff0c;CE线低电平 1.2 写数据&#xff0c;CE线拉高为高电平&#xff0c;开始传输数据&#xff0c;然后准备数…

2024年5月青岛教师编招聘报名详细流程

2024年5月青岛教师编招聘报名详细流程

【开发记录】青龙面板设置飞书机器人

接上篇文章&#xff0c;笔者在写上篇文章时对青龙面板的消息通知功能感兴趣&#xff0c;遂实验之&#xff0c;于是有了这篇文章。 首先参考这篇文章在群聊中引入一个机器人&#xff0c;此时可以获得该机器人的webhook。在青龙面板的通知设置中有larkKey一项&#xff0c;填入web…

[数据结构]————排序总结——插入排序(直接排序和希尔排序)—选择排序(选择排序和堆排序)-交换排序(冒泡排序和快速排序)—归并排序(归并排序)

文章涉及具体代码gitee&#xff1a; 登录 - Gitee.com 目录 1.插入排序 1.直接插入排序 总结 2.希尔排序 总结 2.选择排序 1.选择排序 ​编辑 总结 2.堆排序 总结 3.交换排序 1.冒泡排序 总结 2.快速排序 总结 4.归并排序 总结 5.总的分析总结 1.插入排…

用队列实现栈——leetcode刷题

题目的要求是用两个队列实现栈&#xff0c;首先我们要考虑队列的特点&#xff1a;先入先出&#xff0c;栈的特点&#xff1a;后入先出&#xff0c;所以我们的目标就是如何让先入栈的成员后出栈&#xff0c;后入栈的成员先出栈。 因为有两个队列&#xff0c;于是我们可以这样想&…

[Java EE] 多线程(七): 锁策略

&#x1f338;个人主页:https://blog.csdn.net/2301_80050796?spm1000.2115.3001.5343 &#x1f3f5;️热门专栏:&#x1f355; Collection与数据结构 (90平均质量分)https://blog.csdn.net/2301_80050796/category_12621348.html?spm1001.2014.3001.5482 &#x1f9c0;Java …

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

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

VMware虚拟机中ubuntu使用记录(6)—— 如何标定单目相机的内参(张正友标定法)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、张正友相机标定法1. 工具的准备2. 标定的步骤(1) 启动相机(2) 启动标定程序(3) 标定过程的操作(5)可能的报错 3. 标定文件内容解析 前言 张正友相机标定法…

语义分割——铁路轨道数据集

引言 亲爱的读者们&#xff0c;您是否在寻找某个特定数据集&#xff0c;用于研究或项目实践&#xff1f;欢迎您在评论区留言&#xff0c;或者通过公众号私信告诉我&#xff0c;您想要的数据集的类型主题。小编会竭尽全力为您寻找&#xff0c;并在找到后第一时间与您分享。 重…

typescript 对象数组和函数

typescript 对象数组和函数 对象 在JavaScript中&#xff0c;对象属于非原始类型。对象也是一种符合数组类型&#xff0c;由若干个对象属性构成。对象属性可以是任意数据类型&#xff0c;比如数组&#xff0c;函数或者对象等。当对象属性为函数的时候&#xff0c;称为方法。 …

vue3--element-plus-抽屉文件上传和富文本编辑器

一、封装组件 article/components/ArticleEdit.vue <script setup> import { ref } from vue const visibleDrawer ref(false)const open (row) > {visibleDrawer.value trueconsole.log(row) }defineExpose({open }) </script><template><!-- 抽…

Java与Go: 生产者消费者模型

什么是生产者消费者模型 生产者-消费者模型&#xff08;也称为生产者-消费者问题&#xff09;是一种常见的并发编程模型&#xff0c;用于处理多线程或多进程之间的协同工作。该模型涉及两个主要角色&#xff1a;生产者和消费者&#xff0c;一个次要角色&#xff1a;缓冲区。 生…

全方位解析Node.js:从模块系统、文件操作、事件循环、异步编程、性能优化、网络编程等高级开发到后端服务架构最佳实践以及Serverless服务部署指南

Node.js是一种基于Chrome V8引擎的JavaScript运行环境&#xff0c;专为构建高性能、可扩展的网络应用而设计。其重要性在于革新了后端开发&#xff0c;通过非阻塞I/O和事件驱动模型&#xff0c;实现了轻量级、高并发处理能力。Node.js的模块化体系和活跃的npm生态极大加速了开发…

【React】React-redux多组件间的状态传递

效果&#xff08;部分完整代码在最底部&#xff09;&#xff1a; 编写 Person 组件 上面的 Count 组件&#xff0c;已经在前面几篇写过了&#xff0c;也可以直接翻到最底部看 首先我们需要在 containers 文件夹下编写 Person 组件的容器组件 首先我们需要编写 index.jsx 文件…

一种算法分类方式及其应用

在计算机科学领域&#xff0c;算法是解决问题的有效方法&#xff0c;而对算法进行分类有助于理解它们的特性、优劣以及在不同场景下的应用。常见的算法分类方法&#xff0c;包括按设计思想、问题类型、数据结构和应用领域等&#xff0c;每一类算法会对应有其典型和实际应用。 算…

连接HiveMQ代理器实现MQTT协议传输

先下载MQTTX: MQTTX: Your All-in-one MQTT Client Toolbox 使用线上免费的MQTTX BROKER:The Free Global Public MQTT Broker | Try Now | EMQ 打开MQTTX&#xff0c;创建连接&#xff0c;点击NEW SUBSCRIPTION,创建一个主题&#xff0c;这里使用test/topic,在下面Json中填写…

大语言模型教程与实践(开源)

1.简介 大语言模型&#xff08;Large Language Models, LLMs&#xff09;的兴起确实始于OpenAI在2018年发布的GPT&#xff08;Generative Pre-trained Transformer&#xff09;&#xff0c;这一开创性工作引领了自然语言处理领域的新纪元。随后&#xff0c;2022年底ChatGPT的横…

DDD:根据maven的脚手架archetype生成ddd多模块项目目录结构

随着领域驱动的兴起&#xff0c;很多人都想学习如何进行ddd的项目开发&#xff0c;那ddd的项目结构是怎么样的&#xff1f;又是如何结合SpringBoot呢&#xff1f;那么针对这个问题&#xff0c;笔者使用maven的archetype封装一个相对通用的ddd的项目目录&#xff0c;方便一键生成…

Redisson 分布式锁和同步器

系列文章目录 文章目录 系列文章目录前言前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这篇文章男女通用,看懂了就去分享给你的码吧。 redisson 是基于redis的扩展库,使得redis除了应用于缓存以外,还能做队列…