当前位置: 首页 > news >正文

从入门到精通【Redis】初识Redis集群(Cluster)

文章目录

    • 📕1. 集群的基本概念
    • 📕2. 数据分⽚算法
        • ✏️2.1 哈希求余
        • ✏️2.2 ⼀致性哈希算法
        • ✏️2.3 哈希槽分区算法 (Redis 使⽤)
    • 📕3. 集群机制对故障判定处理
        • ✏️3.1 主节点宕机故障判定
        • ✏️3.2 主节点宕机后故障迁移

特此注明 :
Designed By :长安城没有风
Version:1.0
Time:2025.10.11
Location:辽宁 · 大连

📕1. 集群的基本概念

虽然之前介绍的哨兵机制(Sentinel),提⾼了系统的可⽤性,但是真正⽤来存储数据的还是 master 和 slave 节点,所有的数据都需要存储在单个 master 和 slave 节点中,如果数据量很⼤,接近超出了 master / slave 所在机器的物理内存,就可能出现严重问题了。Redis 的集群就是在上述的思路之下,引⼊多组 Master / Slave,每⼀组 Master / Slave 存储数据全集的⼀部分,从⽽构成⼀个更⼤的整体,称为 Redis 集群 (Cluster)。

在这里插入图片描述
如图所示:

  1. Master1 和 Slave11 和 Slave12 保存的是同样的数据,占总数据的 1/3。
  2. Master2 和 Slave21 和 Slave22 保存的是同样的数据,占总数据的 1/3。
  3. Master3 和 Slave31 和 Slave32 保存的是同样的数据,占总数据的 1/3。

每个红框部分都可以称为是⼀个 分⽚ (Sharding),如果全量数据进⼀步增加,只要再增加更多的分⽚,即可解决。

📕2. 数据分⽚算法

Redis cluster 的核⼼思路是⽤多组机器来存数据的每个部分,那么接下来的核⼼问题就是,给定⼀个数据 (⼀个具体的 key),那么这个数据应该存储在哪个分⽚上?读取的时候⼜应该去哪个分⽚读取?围绕这个问题,业界有三种⽐较主流的实现⽅式。

✏️2.1 哈希求余

设有 N 个分⽚,使⽤ [0, N-1] 这样序号进⾏编号,针对某个给定的 key,先计算 hash 值,再把得到的结果 % N,得到的结果即为分⽚编号。

在这里插入图片描述

🌰例如: N 为 3,给定 key 为 hello,对 hello 计算 hash 值(⽐如使⽤ md5 算法),得到的结果为bc4b2a76b9719d91,再把这个结果 % 3,结果为 0,那么就把 hello 这个 key 放到 0 号分⽚上。后续如果要取某个 key 的记录,也是针对 key 计算 hash,再对 N 求余,就可以找到对应的分⽚编号了。

🌈优点: 简单⾼效,数据分配均匀。

🌈缺点: ⼀旦需要进⾏扩容,N 改变了,原有的映射规则被破坏,就需要让节点之间的数据相互传输,重新排列,以满⾜新的映射规则,此时需要搬运的数据量是⽐较多的,开销较⼤。

这里是引用
N 为 3 的时候,[100, 120] 这 21 个 hash 值的分布 (此处假定计算出的 hash 值是⼀个简单的整数,⽅便⾁眼观察),当引⼊⼀个新的分⽚,N 从 3 => 4 时,⼤量的 key 都需要重新映射(某个key % 3 和 % 4 的结果不⼀样,就映射到不同机器上了)。如上图可以看到,整个扩容⼀共 21 个 key,只有 3 个 key 没有经过搬运,其他的 key 都是搬运过的。

✏️2.2 ⼀致性哈希算法

为了降低上述的搬运开销,能够更⾼效扩容,业界提出了 “⼀致性哈希算法”,key 映射到分⽚序号的过程不再是简单求余了,⽽是改成以下过程:

第⼀步:把 0 -> 2^32-1 这个数据空间,映射到⼀个圆环上,数据按照顺时针⽅向增⻓

在这里插入图片描述

第⼆步:假设当前存在三个分⽚,就把分⽚放到圆环的某个位置上

在这里插入图片描述

第三步:假定有⼀个 key,计算得到 hash 值 H,那么这个 key 映射到哪个分⽚呢?规则很简单,就是从 H 所在位置,顺时针往下找,找到的第⼀个分⽚,即为该 key 所从属的分⽚

在这里插入图片描述

这就相当于,N 个分⽚的位置,把整个圆环分成了 N 个管辖区间,Key 的 hash 值落在某个区间内,就归对应区间管理

在这里插入图片描述

🌈优点: ⼤大降低了扩容时数据搬运的规模,提⾼了扩容操作的效率。

🌈缺点: 数据分配不均匀 (有的多有的少,数据倾斜)。

✏️2.3 哈希槽分区算法 (Redis 使⽤)

为了解决上述问题 (搬运成本⾼ 和 数据分配不均匀),Redis cluster 引⼊了哈希槽 (hash slots) 算法。相当于是把整个哈希值,映射到 16384 个槽位上,也就是 [0, 16383]。然后再把这些槽位⽐较均匀的分配给每个分⽚,每个分⽚的节点都需要记录⾃⼰持有哪些槽位。

假设当前有三个分⽚, ⼀种可能的分配⽅式:

  • 0 号分⽚: [0, 5461], 共 5462 个槽位
  • 1 号分⽚: [5462, 10923], 共 5462 个槽位
  • 2 号分⽚: [10924, 16383], 共 5460 个槽位

如果需要进⾏扩容,⽐如新增⼀个 3 号分⽚,就可以针对原有的槽位进⾏重新分配,⽐如可以把之前每个分⽚持有的槽位,各拿出⼀点,分给新分⽚,⼀种可能的分配⽅式:

  • 0 号分⽚: [0, 4095], 共 4096 个槽位
  • 1 号分⽚: [5462, 9557], 共 4096 个槽位
  • 2 号分⽚: [10924, 15019], 共 4096 个槽位
  • 3 号分⽚: [4096, 5461] + [9558, 10923] + [15019, 16383], 共 4096 个槽位

📕3. 集群机制对故障判定处理

✏️3.1 主节点宕机故障判定

集群中的所有节点,都会周期性的使⽤⼼跳包进⾏通信:

  1. 节点 A 给 节点 B 发送 ping 包,B 就会给 A 返回⼀个 pong 包。ping 和 pong 除了 message type属性之外,其他部分都是⼀样的,这⾥包含了集群的配置信息(该节点的id,该节点从属于哪个分⽚,是主节点还是从节点,从属于谁,持有哪些 slots 的位图…)。
  2. 每个节点,每秒钟,都会给⼀些随机的节点发起 ping 包,⽽不是全发⼀遍,这样设定是为了避免在节点很多的时候,⼼跳包也⾮常多(⽐如有 9 个节点,如果全发,就是 9 * 8 有 72 组⼼跳了,⽽且这是按照 N^2 这样的级别增⻓的)。
  3. 当节点 A 给节点 B 发起 ping 包,B 不能如期回应的时候,此时 A 就会尝试重置和 B 的 tcp 连接,看能否连接成功,如果仍然连接失败,A 就会把 B 设为 PFAIL 状态(相当于主观下线)。
  4. A 判定 B 为 PFAIL 之后,会通过 redis 内置的 Gossip 协议,和其他节点进⾏沟通,向其他节点确认 B的状态。(每个节点都会维护⼀个⾃⼰的 “下线列表”,由于视⻆不同,每个节点的下线列表也不⼀定相同。)
  5. 此时 A 发现其他很多节点,也认为 B 为 PFAIL,并且数⽬超过总集群节点个数的⼀半,那么 A 就会把 B 标记成 FAIL (相当于客观下线),并且把这个消息同步给其他节点(其他节点收到之后,也会把 B 标记成FAIL。)

⾄此,B 就彻底被判定为故障节点了。

以下三种情况会出现集群宕机:

  1. 某个分⽚,所有的主节点和从节点都挂了。
  2. 某个分⽚,主节点挂了,但是没有从节点。
  3. 超过半数的 master 节点都挂了。

核⼼原则是保证每个 slots 都能正常⼯作(存取数据)

✏️3.2 主节点宕机后故障迁移

上述例⼦中,节点 B 发生了故障,并且 A 把 B FAIL 的消息告知集群中的其他节点。

  • 如果 B 是从节点,那么不需要进⾏故障迁移。
  • 如果 B 是主节点,那么就会由 B 的从节点 (⽐如 C 和 D) 触发故障迁移了。

所谓故障迁移,就是指把从节点提拔成主节点,继续给整个 redis 集群提供⽀持,具体流程如下:

  1. 从节点判定⾃⼰是否具有参选资格,如果从节点和主节点已经太久没通信(此时认为从节点的数据和主节点差异太⼤了),时间超过阈值,就失去竞选资格。
  2. 具有资格的节点,⽐如 C 和 D,就会先休眠⼀定时间,休眠时间 = 500ms 基础时间 + [0, 500ms] 随机时间 + 排名 * 1000ms,offset 的值越⼤,则排名越靠前(越⼩)。
  3. ⽐如 C 的休眠时间到了,C 就会给其他所有集群中的节点进⾏拉票操作,但是只有主节点才有投票资格。
  4. 主节点就会把⾃⼰的票投给 C (每个主节点只有 1 票),当 C 收到的票数超过主节点数⽬的⼀半,C 就会晋升成主节点,(C ⾃⼰负责执⾏ slaveof no one,并且让 D 执⾏ slaveof C)。
  5. 同时,C 还会把⾃⼰成为主节点的消息,同步给其他集群的节点,⼤家也都会更新⾃⼰保存的集群结构信息。

上述选举的过程,称为 Raft 算法,是⼀种在分布式系统中⼴泛使⽤的算法。在随机休眠时间的加持下,基本上就是谁先唤醒,谁就能竞选成功。

http://www.dtcms.com/a/471130.html

相关文章:

  • IDF 定时器
  • 怎么做网站引流做网站服务器需要自己提供吗
  • 烟台市牟平区建设局网站石家庄今天最新新闻头条
  • 天津市做网站的公司有哪些ppt模板免费下载完整版免费网站
  • “数据化学习者”的存在论阐释:量化自我对学习主体性的形塑与异化
  • UG NX二次开发(Python)-tag_t转换为int
  • HOW - 如何使用 bundle-analyzer 工具优化包体积
  • 手机站建设o2o商城网站系统开发
  • 国产三维CAD皇冠CAD(CrownCAD)在「汽车零部件」建模教程:发动机零件
  • 中国网站的建设无锡企业做网站
  • systemd-journald和rsyslogd日志配置详解
  • figma打开编辑器时发生错误
  • 网站备案有效期知乎问答网站开发教程
  • ArkTS 与 TypeScript:鸿蒙生态下的语言演进与实践指南
  • AI 赋能 IBMS 集成系统:从 “数据集成中枢” 到 “智慧决策大脑” 的跃升
  • 做医疗网站颜色选择杭州网页设计招聘网
  • 力扣面试经典150题day3第五题(lc69),第六题(lc189)
  • 做网站去哪好盘锦威旺做网站建设
  • 字符串相关的方法有哪些?
  • 标签预制体上的组件
  • cms免费企业网站湖南网站模板建站
  • 【流氓软件】流氓软件及处理方法
  • 网站开发职业怎么经营网店生意才会好
  • 自动化脚本矩阵运营
  • 《Effective Java》第一条:用静态工厂方法代替构造器
  • 怎么做可以访问网站连接加密互联网营销模式
  • Diff-Shadow阴影去除
  • 怎么去接网站来做天津手机网站建设制作
  • 引擎搜索入口aso优化重要吗
  • 做外贸 需要做网站吗知名网站定制报价