广州市网站建设_网站建设公司_一站式建站_seo优化
2025/12/18 20:48:41 网站建设 项目流程

在前面的文章中,我们聊了 Redis 的持久化、锁机制以及热 Key 问题。今天,我们跳出具体的命令细节,从宏观架构的角度来看看 Redis 是如何一步步“做大做强”的。

在生产环境中,我们几乎不会只部署一台 Redis。为什么?因为单机 Redis (Single Node)存在三个无法回避的致命伤:

  1. 单点故障 (SPOF):万一机器宕机,全村吃饭。

  2. 容量瓶颈:一台机器的内存终究有限,存不下海量数据。

  3. 性能瓶颈:QPS 再高也受限于单机的 CPU 和网卡带宽。

为了解决这些问题,Redis 的架构经历了从主从复制哨兵模式,再到分片集群的进化之路。

前置知识:什么是高可用?

简单来说,redis单节点存在比如性能瓶颈、宕机风险等问题,可用性低,那高可用就是解决这个单节点低可用的问题。


一、 第一阶段:主从复制 (Master-Slave) —— 解决“备份与分流”

为了防止“单点故障”,最直接的思路就是:找个替补。

这就是主从架构的初衷。我们部署多台 Redis,一台做主节点 (Master),几台做从节点 (Slave)。

1. 核心架构

  • Master:唯一的“写”入口。负责接收写请求,并将数据异步同步给 Slave。

  • Slave:只读副本。负责接收读请求,并被动同步 Master 的数据。

2. 为什么要读写分离?

这源于一个业务常识:在绝大多数互联网场景中,读操作远远多于写操作(比如微博,看的人多,发的人少)。

  • 如果不分离,所有压力都在 Master 身上。

  • 分离后,Master 专注处理那 10% 的写请求,N 个 Slave 分担那 90% 的读请求。这样既提高了并发量,又避免了写操作(如持久化)阻塞读请求。

3. 依然存在的问题

主从架构解决了**“数据备份”和“读性能”**问题,但它有一个致命的缺陷:不够智能。

如果 Master 突然宕机,Slave 不会自动变成 Master。运维人员必须半夜爬起来,手动修改配置把 Slave 提拔上来。在人工介入的这段时间,服务是不可写的。


二、 第二阶段:哨兵模式 (Sentinel) —— 解决“自动故障恢复”

为了解决主从架构“人工恢复慢”的问题,Redis 引入了 哨兵 (Sentinel) 机制。

你可以把哨兵理解为一群**“自动化的运维巡逻队”**。它们不存数据,只干三件事:监控、选主、通知。

1. 哨兵的三大职责

  • 监控 (Monitoring):哨兵集群通过心跳机制(Ping),每秒检查 Master 和 Slave 是否活得好好的。

    • 主观下线:一个哨兵觉得 Master 没回消息。

    • 客观下线:超过半数(Quorum)哨兵都觉得 Master 没回消息,那才是真挂了。

  • 自动故障恢复 (Failover):当 Master 挂了,哨兵会自动从剩下的 Slave 中选出一个新的 Master。

  • 通知 (Notification):哨兵充当了服务发现的角色。客户端连接的是哨兵,当 Master 换人了,哨兵会把新地址推给客户端。

2. 新 Master 是怎么选出来的?

当 Master 倒下,哨兵会按照以下规则依次筛选 Slave:

  1. 排除法:先把那些断开连接很久、不健康的 Slave 踢出局。

  2. 拼优先级:看slave-priority配置,数字越小优先级越高(0 表示永不当选)。

  3. 拼进度 (Offset):谁的数据最全(Offset 最大),谁就当选。这意味着它和旧 Master 的数据差异最小。

  4. 拼人品 (RunID):如果以上都一样,就按运行 ID 排序,选 ID 小的。

3. 依然存在的问题

哨兵模式实现了高可用 (High Availability),但它依然是**“主从模式”**的变种。

  • 写瓶颈依然只有一个 Master 负责写,无法应对高并发写请求。

  • 容量瓶颈:所有节点存的数据都是一样的,无法突破单机内存上限(比如你只有 64G 内存,就存不下 100G 数据)。 解释:(比如:我有 3 台机器,每台 64G,加在一起我就能存 $64 \times 3 = 192G$ 的数据。但在 Redis 主从/哨兵架构下,这是错的!你依然只能存 64G。Master 有什么,Slave 就必须有一份一模一样的。)


三、 第三阶段:分片集群 (Cluster) —— 解决“海量数据与高并发写”

为了解决“存不下”和“写不过来”的问题,Redis 3.0 推出了 Redis Cluster。

这是真正的分布式去中心化方案,实现了多主多从。

1. 核心原理:散列插槽 (Hash Slots)(见下文解释)

Redis Cluster 没有把数据直接绑定到节点上,而是引入了一个概念:插槽 (Slot)

  • 整个集群被逻辑切分为16384个插槽。

  • 数据绑定插槽:当存一个 Key 时,Cluster 会根据CRC16(key) % 16384计算出这个 Key 属于哪个插槽。

  • 插槽绑定节点:这 16384 个插槽被均匀分配给集群中的多个 Master 节点。

2. 为什么要这么设计?

  • 解耦数据跟节点没关系,只跟插槽有关系。

  • 易扩容如果你想增加一个 Master 节点,只需要从其他节点挪一些“插槽”给新节点即可。数据迁移时,通过插槽搬运非常方便,不需要全量重新哈希。

3. Cluster 的能力

  • 多主写入:集群中有多个 Master,每个 Master 负责一部分插槽。这意味着写请求被分散了,性能线性提升。

  • 高可用:每个 Master 都有自己的 Slave。如果某个 Master 挂了,它的 Slave 会自动顶上(集群内部实现了类似哨兵的选举机制)。

  • 智能路由:客户端请求任意一个节点,如果数据不在该节点,它会返回重定向错误,告诉客户端去哪个节点找。

附:对于插槽——全量哈希的优化以及解耦思想的理解:

1. 如果没有插槽:直接哈希 (The Old Way)

假设你是一个物流主管,你有 3 辆车 (Node A, B, C),你要运送 10 万个包裹 (Keys)。

最笨的办法(直接绑定节点):

规则:拿到包裹,看一下单号,除以 3 取余数。

  • 余数 0 -> 扔进 A 车。

  • 余数 1 -> 扔进 B 车。

  • 余数 2 -> 扔进 C 车。

灾难发生了:扩容

生意太好,你买了一辆新车 D 车(节点增加到 4 个)。 规则变了:现在要除以 4 取余数。

后果:

  • 原来的包裹单号是 3,3 % 3 = 0 (在 A 车)。

  • 现在的包裹单号是 3,3 % 4 = 3 (得去 D 车)。

你会发现,几乎所有的包裹都需要从原来的车里翻出来,重新分配到新车去。 这就叫“全量重新哈希”。在数据迁移期间,你的物流系统基本瘫痪了。

2. 有了插槽:引入“中间层” (The Slot Way)

Redis Cluster 说:“别把包裹直接扔车里!先把包裹装进统一的箱子里!” 这 16384 个插槽,就是 16384 个固定的塑料收纳箱。

步骤一:包裹进箱子(这一步永远不变)

不管你有几辆车,我的规则是铁打不动的: 包裹 (Key) -> 经过 CRC16 算法 -> 算出它属于 第 500 号箱子 (Slot 500)。

重点:这个包裹永远属于第 500 号箱子,天塌下来它也在这个箱子里。

步骤二:箱子上车(这一步灵活多变)

现在你有 3 辆车 (Node A, B, C)。 你只需要分配箱子就行了:

  • A 车:负责运送 0 ~ 5000 号箱子。

  • B 车:负责运送 5001 ~ 10000 号箱子。

  • C 车:负责运送 10001 ~ 16383 号箱子。

3. 为什么这样扩容就容易了?

现在,生意好了,你又买了一辆新车 D 车。 这就是插槽的魔力时刻:

不需要动包裹:你不需要去把每一个包裹拿出来重新算。包裹依然在它原来的箱子里。

只需要挪箱子: 你对 A 车说:“把你那里的 0~1000 号箱子搬给 D 车。” 你对 B 车说:“把你那里的 5001~6000 号箱子搬给 D 车。” 你对 C 车说:“把你那里的 10001~11000 号箱子搬给 D 车。”

结果:

  • A、B、C 车腾出了一点空间。

  • D 车也有活干了。

整个过程只是搬运了几个箱子,而不是把几十万个散落的包裹重新分拣。

4. 总结:如何理解“解耦”?

插槽就是一个**“中间商”**。

  • 没有插槽时:数据 <-> 节点(直接强绑定,节点变了,数据位置全乱)。

  • 有插槽时

    1. 数据 <-> 插槽(强绑定,由于插槽数量 16384 是固定的,所以这个关系永远不变)。

    2. 插槽 <-> 节点(弱绑定,可以随时把插槽从这个节点挪到那个节点)。

一句话总结:插槽就像是搬家时的**“打包箱”**。 如果没有打包箱,搬家时你要一双袜子、一本书地搬(数据迁移极慢)。 有了打包箱,你只需要把箱子搬上车,至于哪个箱子在哪个车上,随时可以调整。这就是 Redis Cluster 灵活扩容的秘密。


四、 总结与选型

我们将这三个架构做一个最终对比:

架构模式核心特点解决的问题遗留的问题适用场景
主从复制一主多从,读写分离单点故障、读性能瓶颈故障恢复需人工、单机容量限制读多写少、数据量小、允许短暂宕机
哨兵模式主从 + 自动监控自动故障恢复 (HA)依然是单主写入、单机容量限制读多写少、对可用性要求高
分片集群多主多从,数据分片海量数据存储高并发写架构复杂、不支持部分跨 Slot 操作海量数据、高并发写、核心业务

一句话总结:

  • 如果你的 Redis 只是为了做缓存且数据量不大,主从就够了。

  • 如果你不能忍受机器挂了要半夜起来修,那就上哨兵

  • 如果你有100G 以上的数据或者每秒 10 万次的写请求,请毫不犹豫地使用Redis Cluster

最后说一下我自己对于扩容的理解:

我觉得容量问题的解决可以从两个维度去理解,第一个是多主多从这多主之间并不是和主从一样是复制备份的关系,另外引入插槽的概念它优化了扩容带来的全量哈希的危害。所以集群架构解决了容量问题。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询