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

一致哈希算法

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

我们一起来看一个例子,对于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;其实也可以是一个独立…

PostgreSQL自带的命令行工具06- pg_isready

PostgreSQL自带的命令行工具06- pg_isready 基础信息 OS版本&#xff1a;Red Hat Enterprise Linux Server release 7.9 (Maipo) DB版本&#xff1a;16.2 pg软件目录&#xff1a;/home/pg16/soft pg数据目录&#xff1a;/home/pg16/data 端口&#xff1a;5777pg_isready 是 Po…

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;就可以访问到部…

持续总结中!2024年面试必问 100 道 Java基础面试题(二十九)

上一篇地址&#xff1a;持续总结中&#xff01;2024年面试必问 100 道 Java基础面试题&#xff08;二十八&#xff09;-CSDN博客 五十七、静态内部类和普通内部类有什么区别&#xff1f; 在Java中&#xff0c;内部类是指定义在另一个类中的类&#xff0c;而内部类的类型有很多…

分割回文串(力扣131)

解题思路&#xff1a;仍就是上递归三部曲&#xff0c;但于此同时要明白此时的index就可以作为切割回文串的线了 具体代码如下&#xff1a; class Solution { private: vector<vector<string>> result; vector<string> path; // 放已经回文的子串 void back…

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

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

【leetcode】DFS递归题目总结

DFS&#xff08;深度优先搜索&#xff09; 深度优先搜索是一种用于遍历或搜索树或图的算法&#xff0c;其基本思路是从起始节点开始&#xff0c;沿着一条路径一直走到底&#xff0c;直到无法再走下去为止&#xff0c;然后回溯到上一个节点&#xff0c;继续走到另外一个路径&…

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

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

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

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

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

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

大模型引领NLP研究新范式:从统计机器学习到预训练语言模型

自然语言处理&#xff08;NLP&#xff09;研究范式经历了从浅层到深层、从局部到整体、从特定到通用的演进过程。下面我们来详细回顾这一过程。 一、早期的统计机器学习方法&#xff08;20世纪90年代 - 21世纪初&#xff09; 词袋模型&#xff08;Bag-of-Words&#xff09; 将…

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、并行工程和集成产…

深度学习技术在运动想象脑电信号中分类中的学习实战

----&#xff08;本文由思影科技学习参考后得出&#xff09; 脑机接口&#xff08;BCI&#xff09;中运动想象脑电图&#xff08;MI-EEG&#xff09;是最常见的BCI范式之一&#xff0c;已经广泛应用于只能医疗&#xff0c;如中风后康复和移动辅助机器人。近年来&#…