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

一致哈希算法

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

我们一起来看一个例子,对于1000万个key的3节点KV存储,如果我们使用一致哈希算法增加1个节点,即3节点集群变为4节点集群,则只需要迁移24.3%的数据,如代码所示

package mainimport (
"flag"
"fmt"
"log"
"stathat.com/c/consistent"
"strconv"
)var keysPtr = flag.Int("keys", 10000, "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 = *newNodesPtrc := consistent.New()
for i := 0; i < nodes; i++ {
c.Add(strconv.Itoa(i))
}newC := consistent.New()
for i := 0; i < newNodes; i++ {
newC.Add(strconv.Itoa(i))
}migrate := 0
for i := 0; i < keys; i++ {
server, err := c.Get(strconv.Itoa(i))
if err != nil {
log.Fatal(err)
}newServer, err := newC.Get(strconv.Itoa(i))
if err != nil {
log.Fatal(err)
}if server != newServer {
migrate++
}
}migrateRatio := float64(migrate) / float64(keys)
fmt.Printf("%f%%\n", migrateRatio*100)
}
go run ./consistent-hash.go -keys 10000000 -nodes 3 -new-nodes 4
24.301550%

你看,使用了一致哈希算法后,我们需要迁移的数据量仅为使用哈希算法时的三分之一,是不是大大提升了效率呢?
总的来说,使用一致哈希算法在扩容或缩容时,都只需要重定位环空间中的一小部分数据。也就是说,一致哈希算法具有较好的容错性和可扩展性。需要注意的是,在哈希寻址中常出现这样的问题:客户端访问请求集群在少数的节点上,导致有些机器高负载,有些机器低负载的情况。那么有什么办法能让数据访问分布得比较均匀呢?答案就是虚拟节点。
在一致哈希算法中,如果节点太少,则很容易因为节点分布不均匀造成数据访问的冷热不均,也就是说,大多数访问请求都会集中少量几个节点上,如图所示。从图中可以看到,虽然集群有3个节点,但访问请求主要集中在节点A上。那么如何通过虚拟节点解决冷热不均的问题呢?
其实,可以对每一个服务器节点计算多个哈希值,在每个计算结果位置上都放置一个虚拟节点,并将虚拟节点映射到实际节点。比如,在主机名的后面增加比那好,分别计算Node-A-01、Node-A-02、Node-B-01、Node-B-02、Node-C-01、Node-C-02的哈希值,形成6个虚拟节点,如图所示,可以从图中看到,增加了节点后,节点在哈希环上的分布就相对均匀了,这时,如果有访问请求寻址到Node-A-01这个虚拟节点,将被重定位到节点A。你看这样我们就解决了冷热不均匀的问题。可能有人已经发现了,节点数越多,使用哈希算法时需要迁移的数据就越多,而使用一致哈希算法时需要迁移的数据就越少,如代码清单所示

go run ./hash.go -keys 10000000 -nodes 3 -new-nodes 4
74.999980%
go run ./hash.go -keys 10000000 -nodes 10 -new-nodes 11
90.909000%go run ./consistent-hashgo.go -keys 10000000 -nodes 3 -new-nodes 4
24.301550%
go run ./consistent-hashgo.go -keys 10000000 -nodes 10 -new-nodes 11
6.479330%

从示例代码的输出中可以看到,当我们向10节点集群中增加节点时,如果使用哈希算法,则需要迁移高达90.91%的数据,如果使用一致哈希算法,则需要迁移6.48%的数据。
需要注意的是,使用一致哈希算法实现哈希寻址时,可以通过增加节点数来降低节点宕机对整个集群的影响,以及故障恢复时需要迁移的数据量。后续在需要时,你也可以通过增加节点数来提升系统的容灾能力和故障恢复效率。
在这里插入图片描述
在这里插入图片描述

思考

Raft集群具有容错能力,能容忍少数的节点故障,那么在多个Raft集群组成的KV系统中,如何设计一致哈希算法,以实现当某个集群的领导者节点出现故障并选举出新的领导者后,整个系统还能稳定运行呢?
在多个Raft集群组成的KV系统中,设计一致哈希算法以实现领导者节点故障后系统的稳定运行,需要确保在领导者节点变更时,数据的一致性和服务的连续性。以下是一些建议的步骤和考虑因素:

  • 1.虚拟节点和环形哈希空间:
    一致哈希算法通过引入虚拟节点和环形哈希空间,实现了节点动态扩缩容时数据迁移的最小化。在Raft集群组成的KV系统中,每个Raft集群可以视为一个物理节点,并在其上创建多个虚拟节点。虚拟节点能够平滑地将数据分布到多个物理节点上,减少单个物理节点故障对系统的影响。
  • 2.领导者故障检测与恢复:
    当某个Raft集群的领导者节点出现故障时,该集群内部会通过Raft的领导者选举机制选举出新的领导者。KV系统需要监控Raft集群的状态,并在检测到领导者节点故障时,更新其内部的一致哈希映射,确保新的领导者节点能够接管服务。
  • 3.数据同步与一致性:
    在领导者节点故障期间,可能会有一些数据尚未同步到新的领导者节点。因此,在选举出新的领导者后,需要确保数据的同步和一致性。
    这可以通过Raft的日志复制机制来实现。新的领导者节点可以从其他跟随者节点那里拉取缺失的日志条目,并应用到状态机中以更新系统状态。
  • 4.路由与负载均衡:
    一致哈希算法通过计算键的哈希值,并将其映射到环形哈希空间上的某个虚拟节点,从而确定数据的存储位置。在多个Raft集群组成的KV系统中,需要设计一种路由机制,使得客户端能够根据键的哈希值将数据路由到正确的Raft集群和虚拟节点上。同时,还需要考虑负载均衡的问题,确保各个Raft集群之间的负载相对均衡。
  • 5.故障恢复与容错性:
    在设计系统时,需要考虑各种可能的故障场景,并制定相应的故障恢复策略。
    例如,当某个Raft集群完全故障时,系统需要能够自动将其从一致哈希映射中移除,并将该集群上的数据迁移到其他健康的集群上。
    此外,还需要考虑如何在不影响系统稳定性的前提下,对系统进行扩容和缩容。
    6.测试与验证:
    在实际部署之前,需要对系统进行充分的测试和验证,以确保其能够在各种故障场景下稳定运行。
    这包括单元测试、集成测试、压力测试等不同类型的测试。
    综上所述,设计一致哈希算法以实现多个Raft集群组成的KV系统的稳定运行,需要综合考虑虚拟节点、领导者故障检测与恢复、数据同步与一致性、路由与负载均衡、故障恢复与容错性以及测试与验证等多个方面。

重点总结

  • 1.一致哈希算法是一种特殊的哈希算法,该算法可以使节点增减变化时只影响到部分数据的路由寻址,也就是说我们只要迁移部分数据,就能实现集群的稳定了。
  • 2.当节点数较少时,可能会出现节点在哈希环上分布不均匀的情况,即每个节点实际在环上占据的区间大小不一,最终导致业务对节点的访问冷热不均,而这个问题可以通过引入更多的虚拟节点来解决。
  • 3.一致哈希算法本质上是一种路由寻址算法,适合简单的路由寻址场景,比如,在KV存储系统内部,它的特点是简单,不需要维护路由信息

有人可能会有这样的疑问:关于Raft算法的原理以及一致哈希算法如何突破集群"领导者"的限制,但是有的公司的配置中心、名字路由等使用的是ZooKeeper,那么ZAB协议是如何实现一致性的呢?ZAB协议和Raft算法又有什么不一样呢?

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

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

相关文章

微搭低代码入门03页面管理

目录 1 创建页面2 页面布局3 页面跳转总结 上一篇我们介绍了应用的基本操作&#xff0c;掌握了应用的概念后接着我们需要掌握页面的常见操作。 1 创建页面 打开应用的编辑器&#xff0c;在顶部导航条点击创建页面图标 在创建页面的时候可以从空白新建&#xff0c;也可以使用模…

【原件】软件需求分析报告

第1章 序言 第2章 引言 2.1 项目概述 2.2 编写目的 2.3 文档约定 2.4 预期读者及阅读建议 第3章 技术要求 3.1 软件开发要求 第4章 项目建设内容 第5章 系统安全需求 5.1 物理设计安全 5.2 系统安全设计 5.3 网络安全设计 5.4 应用安全设计 5.5 对用户安全管理 …

Mysql复习笔记: 基础概念(待补充)

一. 基础概念 通用概念: 网络连接必须得分配给一个线程去进行处理&#xff0c;由一个线程来监听请求以及读取请求数据&#xff0c;比如从网络连接中读取和解析出来一条我们的系统发送过去的SQL语句 在数据库中&#xff0c;哪怕执行一条SQL语句&#xff0c;其实也可以是一个独立…

2024牛客五一集训派对day2 Groundhog Looking Dowdy 个人解题思路

前言&#xff1a; 被实验室教练要求要打的这次五一牛客的训练赛&#xff0c;这些区域赛难度的题对于大一的我来说难度实在是太高了&#xff0c;我和我的队友只写了一些非常简单的签到题&#xff0c;其他题目都没怎么看&#xff08;我们太弱了&#xff09;&#xff0c;但我可以分…

线上线下交友社区系统,支持打包小程序/公众号/H5,源码交付!

上网交友的好处有很多&#xff0c;以下是一些主要的好处&#xff1a; 1. 拓展人际关系&#xff1a;通过上网交友可以认识更多的人&#xff0c;拓展自己的社交圈。这有助于扩大自己的视野、增加人生经验和开阔心胸。 2. 找到志同道合的朋友&#xff1a;在网络上&#xff0c;我们…

JavaWeb请求响应概述

目录 一、请求响应流程-简述 二、深入探究 三、DispatcherServlet 四、请求响应流程-详细分析 一、请求响应流程-简述 web应用部署在tomcat服务器中&#xff0c;前端与后端通过http协议进行数据的请求和响应。前端通过http协议向后端发送数据请求&#xff0c;就可以访问到部…

批量抓取某电影网站的下载链接

思路&#xff1a; 进入电影天堂首页&#xff0c;提取到主页面中的每一个电影的背后的那个urL地址 a. 拿到“2024必看热片”那一块的HTML代码 b. 从刚才拿到的HTML代码中提取到href的值访问子页面&#xff0c;提取到电影的名称以及下载地址 a. 拿到子页面的页面源代码 b. 数据提…

第二代增强-创建采购申请时的增强

文章目录 第二代增强-创建采购申请时的增强业务要求实现过程创建项目编写代码激活增强 维护消息类运行效果断点 第二代增强-创建采购申请时的增强 业务要求 实现过程 创建项目 编写代码 "AFNAM&#xff0c;申请人 "需求&#xff1a;NB类型的采购申请&#xff0c;需要…

嵌入式全栈开发学习笔记---C语言笔试复习大全10

目录 字符数组&#xff08;笔试重点&#xff09; 字符数组初始化 字符串数组输出 字符串的输入 字符串处理函数 puts()输出字符串 gets()输入字符串 strlen()计算字符串长度 strcpy()将后面的字符串拷贝到前面的字符串数组里面 笔试题12 strcmp()比较字符串的大小 …

自动化机器学习——网格搜索法:寻找最佳超参数组合

自动化机器学习——网格搜索法&#xff1a;寻找最佳超参数组合 在机器学习中&#xff0c;选择合适的超参数是模型调优的关键步骤之一。然而&#xff0c;由于超参数的组合空间通常非常庞大&#xff0c;手动调整超参数往往是一项耗时且困难的任务。为了解决这个问题&#xff0c;…

C语言 | Leetcode C语言题解之第67题二进制求和

题目&#xff1a; 题解&#xff1a; void reserve(char* s) {int len strlen(s);for (int i 0; i < len / 2; i) {char t s[i];s[i] s[len - i - 1], s[len - i - 1] t;} }char* addBinary(char* a, char* b) {reserve(a);reserve(b);int len_a strlen(a), len_b st…

性能优化(一):ArrayList还是LinkedList?

引言 集合作为一种存储数据的容器&#xff0c;是我们日常开发中使用最频繁的对象类型之一。JDK为开发者提供了一系列的集合类型&#xff0c;这些集合类型使用不同的数据结构来实现。因此&#xff0c;不同的集合类型&#xff0c;使用场景也不同。 很多同学在面试的时候&#x…

大厂案例 - 通用的三方接口调用方案设计(中)

文章目录 Pre阿里云华为云【AK和SK生成方案】最佳实践1. 创建API密钥管理系统2. 生成AK和SK3. 存储和管理AK和SK4. 提供API密钥分发机制5. 安全性6. 其他注意事项 DB Model Design表结构Next考虑其他建议 API接口设计指导1. 使用POST作为接口请求方式2. 客户端IP白名单3. 单个接…

【研发管理】产品经理知识体系-产品创新流程

导读&#xff1a;产品创新流程是一个系统性的过程&#xff0c;旨在通过创造和引入新的产品或改进现有产品来满足市场需求、解决用户问题或实现竞争优势。 目录 1、产品创新引论 2、决策基本框架 3、模糊前端 4、产品创新流程模型概论 5、门径管理流程 6、并行工程和集成产…

Java与Go:并发

在此之前&#xff0c;我们先要明白什么是并发&#xff1f;为什么要并发编程&#xff1f; 在计算机中&#xff0c;同一时刻&#xff0c;只能有一条指令&#xff0c;在一个CPU上执行 后面的指令必须等到前面指令执行完才能执行&#xff0c;就是串行。在早年CPU核心数还少的时候倒…

Android版本依赖Version catalog

曾经我们使用config.gradle文件进行版本依赖配置&#xff0c;然后在project的build.gradle.kts中使用如下方式引入&#xff1a; apply(from "./config.gradle") 缺点&#xff1a;在project的module中引用无任何提示&#xff0c;无法跳转到指定引用 一、创建versio…

临床+康复的一体化治疗服务,把握黄金康复时间

随着我院脑血管病人&#xff0c;重症病人及骨科病人康复需求的日渐增多&#xff0c;为了使每位住院患者在治疗原发病的同时&#xff0c;第一时间接受到康复治疗&#xff0c;提高病人的生活质量&#xff0c;降低致残率&#xff0c;我院康复治疗科在院领导的大力支持下&#xff0…

C语言之递归函数、例题详解以及注意事项

目录 前言 一、递归的概念 二、递归例题详解 例1&#xff1a;斐波那契数列 例2&#xff1a;求次方 例3&#xff1a;求各位数之和 例4&#xff1a;阶乘 例5&#xff1a;顺序打印 三、递归的注意事项 总结 前言 本文将和大家分享一些递归函数的相关知识&#xff0c;技巧…

EPAI手绘建模APP颜色、贴图、材质、样式

⑦ 颜色选择页面 1) 颜色环选色。 图 65 颜色选择器-颜色环 2) RGB选色。 图 66 颜色选择器-RGB 3) HSL选色。 图 67 颜色选择器-HSL 4) 国风颜色库选色。 图 68 颜色选择器-国风 5) CSS颜色库选色。 图 69 颜色选择器-CSS 6) 历史颜色&#xff1a;保存最近使用的多个颜色&…

vue快速入门(五十三)使用js进行路由跳转

注释很详细&#xff0c;直接上代码 上一篇 新增内容 几种常用的路由跳转方式演示 源码 App.vue <template><div id"app"><div class"nav"><!-- router-link 自带两个高亮样式类 router-link-exact-active和router-link-active区别&a…