Redis 总结

大型互联网系统如何将 Redis 从单机内存数据库,逐步演进为高性能、高可用、可水平扩展的分布式存储系统。

一、核心主线

演进路径可以概括为:

1
2
3
4
5
6
7
8
9
单机 Redis

主从模式:增加数据副本

哨兵模式:自动监控和主从切换

Redis Cluster:多主分片 + 自动故障转移

中心化集群:Proxy + Redis 分片,支撑超大规模节点

二、Redis 概述

1. Redis 的定位与特点

Redis 是一种支持网络访问、基于内存、可选持久化的开源键值型 NoSQL 数据库。

主要特点:

  • 性能高:数据主要存储在内存中;
  • 数据结构丰富:支持 String、List、Hash、Set、Sorted Set 等;
  • 支持分布式:提供主从、哨兵和集群模式;
  • 操作具有原子性:基于单线程事件驱动模式处理数据操作;
  • 应用范围广:可用于缓存、计数器、限流、排行榜和社交关系等场景。

大型互联网系统使用 Redis 时,重点是同时满足:

  1. 高性能;
  2. 高可用;
  3. 可扩展。

三、Redis 高可用与分布式架构

1. 主从模式

1.1 基本结构

一个 Master 与若干 Slave 组成主从关系:

1
2
3
              ┌── Slave 1
Redis Master ─┼── Slave 2
└── Slave 3
  • Master 负责处理数据写入;
  • Slave 从 Master 复制数据;
  • Slave 保存数据副本,也可以承担部分读取请求。

1.2 Redis 主从复制流程

Slave 首次连接 Master 时,先进行全量复制,再持续进行增量复制。

1
2
3
4
5
6
7
8
9
10
11
12
13
Slave 发送 PSYNC

Master 执行 BGSAVE

生成全量 RDB 快照

Master 将 RDB 发送给 Slave

Slave 加载 RDB 到内存

Master 发送生成快照期间缓存的数据变更命令

Slave 执行增量命令,持续与 Master 同步

详细步骤:

  1. Slave 连接 Master,并发送 PSYNC 命令;
  2. Master 执行 BGSAVE,生成当前数据的 RDB 快照;
  3. 生成和发送快照期间,Master 使用缓冲区记录新的数据变更;
  4. Slave 收到 RDB 后先保存到磁盘,再将数据加载到内存;
  5. Master 把缓冲区内的增量命令发送给 Slave;
  6. Slave 执行这些命令,使数据逐渐与 Master 保持一致。

1.3 通用复制规律

Redis 与 MySQL 等存储系统的主从复制具有相似思路:

1
全量复制 + 增量复制

如果一个 Master 向过多 Slave 复制数据,同样会产生复制风暴,增加 Master 的网络和处理压力。


2. 哨兵模式

2.1 主从模式的问题

单纯的主从模式存在一个明显缺点:

Master 宕机后,需要人工选择一个 Slave 并将其切换为新 Master。

人工切换费时费力,还会造成 Redis 在一段时间内无法写入。

2.2 Sentinel 的作用

Redis Sentinel(哨兵)负责:

  • 监控 Master 和 Slave 的健康状态;
  • 判断 Master 是否宕机;
  • 在多个 Slave 中选举新的 Master;
  • 通知其他 Slave 改为复制新 Master;
  • 向客户端提供新的 Master 地址。

典型结构:

1
2
3
4
5
Sentinel 集群
↓ 监控
Redis Master
↓ 复制
多个 Slave

2.3 自动故障转移流程

1
2
3
4
5
6
7
8
9
10
11
多个 Sentinel 持续监控 Master

超过指定数量的 Sentinel 判断 Master 宕机

Sentinel 协商并选择一个 Slave

将该 Slave 提升为新 Master

其他 Slave 改为复制新 Master

客户端从 Sentinel 获取新的 Master 地址

哨兵模式的本质是:

在主从复制基础上,增加自动监控、选主和故障转移能力。


3. Redis Cluster

3.1 为什么需要集群模式

主从模式和哨兵模式都只有一个 Master 处理主要读写请求,因此存在两个瓶颈:

  • 单个 Master 的内存有限,无法保存海量数据;
  • 单个 Master 的处理能力有限,无法承受海量请求。

解决方式是数据分片

1
2
3
4
5
全量数据
↓ 拆分
Master 1 + Slave
Master 2 + Slave
Master 3 + Slave

多个 Master 分别保存部分数据,并共同提供服务。

3.2 Redis Cluster 基本结构

Redis Cluster 从 Redis 3.0 开始提供分布式存储能力。

  • 集群至少需要 3 个 Master;
  • 每个 Master 管理一个数据分片;
  • 每个 Master 最好至少配置一个 Slave;
  • 同一分片通过主从复制保证高可用;
  • 集群节点之间可以相互通信。

3.3 哈希槽与数据路由

Redis Cluster 将整个数据库划分为 16384 个哈希槽

每个 Master 负责其中一部分槽位。例如:

1
2
3
Master 1:0~5461
Master 2:5462~10922
Master 3:10923~16383

数据所属槽位的计算方式:

1
slot = CRC16(Key) mod 16384

客户端访问流程

  1. 客户端连接集群中的任意节点;
  2. 获取并缓存“槽位—Master”的映射关系;
  3. 访问数据时,根据 Key 计算槽位;
  4. 根据槽位找到对应 Master;
  5. 将请求发送给正确的数据分片。

哈希槽的价值是:

  • 将数据分片抽象为槽位;
  • 数据与具体机器解耦;
  • 扩容、缩容时可以迁移槽位,而不是重新设计整体路由规则。

3.4 Gossip 协议

Redis Cluster 使用 Gossip 协议在节点之间传播集群元信息。

需要传播的信息包括:

  • 新节点加入;
  • 节点地址和状态;
  • 槽位归属;
  • 槽位迁移;
  • Master 宕机;
  • Slave 提升为新 Master。

Gossip 的传播方式

Gossip 类似“流言传播”:

  1. 每个节点周期性选择部分节点通信;
  2. 收到信息的节点再将信息传播给其他节点;
  3. 经过多轮传播,最终所有节点的信息趋于一致。

它不是一次广播给所有节点,而是通过多轮局部通信扩散。

主要消息类型

消息 作用
meet 邀请新节点加入集群
ping 发送自身状态、槽位信息并探测其他节点
pong 响应 pingmeet,返回自身信息
fail 通知集群某节点已经宕机

Gossip 的优点是去中心化,没有单独的元信息管理中心;缺点是信息需要多轮传播,因此只能保证最终一致性


3.5 新节点加入

新节点加入集群时,可以向集群内任意节点发送 CLUSTER MEET 命令。

简化流程:

1
2
3
4
5
6
7
8
9
客户端通知节点 A:节点 B 要加入

A 保存 B 的地址并发送 meet

B 保存 A 的信息并返回 pong

A、B 完成握手

通过 Gossip 将 B 的信息传播到整个集群

因此,新节点只需要先认识集群中的一个节点,之后便可通过 Gossip 逐渐被整个集群发现。


3.6 节点故障检测与转移

Redis Cluster 区分两种下线状态。

主观下线

节点 A 向节点 B 发送 ping,但在指定时间内没有收到 pong,于是 A 主观认为 B 已下线。

单个节点的判断可能受到局部网络异常影响,因此不能直接触发故障转移。

客观下线

如果集群中超过半数的节点都认为 B 主观下线,那么 B 被认定为客观下线。

1
2
单节点判断失败 → 主观下线
超过半数节点达成判断 → 客观下线

故障转移

如果被客观判定下线的是 Master:

  1. 集群广播 fail 消息;
  2. 该 Master 的 Slave 停止复制;
  3. 一个 Slave 接管原 Master 的槽位;
  4. Slave 提升为新 Master;
  5. 新 Master 广播 pong,通知整个集群更新状态。

3.7 Redis Cluster 的优势

  • 去中心化:各节点地位对等;
  • 数据分片清晰:通过槽位管理数据;
  • 扩展性较强:可以增加节点并迁移槽位;
  • 高可用:支持自动故障发现与主从切换;
  • 人工干预少:集群可以自动恢复;
  • 官方支持:对 Redis 命令的兼容和支持较全面。

3.8 Redis Cluster 的局限:Gossip 风暴

Gossip 依赖节点间扩散式通信。

当集群只有数百个节点时,一般可以正常运行;但如果扩展到成千上万个节点,节点之间的通信量会急剧增加,形成 Gossip 风暴

可能带来的问题:

  • 占用大量网络带宽;
  • 集群内部通信成本过高;
  • 元信息传播链路过大;
  • 集群规模继续扩大时受到限制。

对于需要数千甚至上万个 Redis 节点的亿级用户系统,更推荐放弃完全去中心化的元信息传播方式,转向中心化 Proxy 架构


4. 中心化集群

中心化架构的核心思想是:

使用中间代理统一维护数据路由和集群元信息,客户端不直接参与 Redis 分片寻址。

基本结构:

1
2
3
4
5
Redis 客户端

Proxy 集群
↓ 路由
多个 Redis 数据分片

优点:

  • 避免大规模节点间的 Gossip 通信;
  • 客户端无须了解槽位和节点拓扑;
  • 可以代理到成千上万台 Redis 服务器;
  • 更适合超大规模 Redis 集群。

4.1 Twemproxy

Twemproxy 是 Twitter 开源的 Redis 中间代理。

访问流程:

1
2
客户端 → Twemproxy → 根据路由规则选择 Redis 节点
← 汇总结果后返回客户端

优势

  • 客户端像连接普通 Redis 一样连接 Twemproxy,改造成本低;
  • Twemproxy 与 Redis 保持长连接,减少 Redis 节点的连接数;
  • 数据路由由代理完成,客户端和 Redis 节点无须参与。

不足

  • 缺少友好的管理后台;
  • 运维和监控不够方便;
  • 不支持 Redis 集群平滑扩缩容;
  • 增加节点时的数据迁移成本较高。

Twemproxy 提供了中心化代理的基本思路,但不是完善的超大规模集群管理方案。


4.2 Codis 架构

Codis 是借鉴 Twemproxy 思路发展出的中心化 Redis 集群方案。

Codis 默认把数据划分为 1024 个槽位

1
slot = CRC32(Key) mod N

其中 N 默认是 1024。

Codis 核心组件

组件 作用
Codis Server 二次开发的 Redis 服务器,负责数据读写并支持数据迁移
Codis Proxy 接收客户端请求并路由到正确的 Codis Server
ZooKeeper 保存槽位、分片、节点和 Proxy 等集群元信息
Codis Dashboard 执行扩缩容、槽位迁移和 Proxy 管理
Codis Fe 为 Dashboard 提供 Web 管理页面

Redis Server Group

Codis 将一个数据分片称为 Redis Server Group:

1
2
3
4
Redis Server Group
├── Master
├── Slave 1
└── Slave 2

每个 Group 通过主从复制保证分片高可用,新版本可为每个 Group 配置 Sentinel 完成自动主从切换。


4.3 Codis 数据访问流程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
客户端从 ZooKeeper 获取 Codis Proxy 地址

选择一个 Proxy 建立连接

向 Proxy 发送读写请求

Proxy 根据 Key 计算槽位

从集群元信息中找到对应 Redis Server Group

将请求转发给相应 Redis 节点

Redis 返回结果给 Proxy

Proxy 将结果返回客户端

其中:

  • Master 可以处理读写请求;
  • Slave 可以承担读取请求;
  • Proxy 负责屏蔽底层分片与节点变化。

4.4 Codis 平滑扩容与槽位迁移

Codis 以槽位为单位迁移数据。

假设要把节点 A 的槽位 S 迁移到新节点 B:

  1. A 将槽位 S 的关联数据复制到 B;
  2. 迁移过程中 A 继续提供服务;
  3. 如果请求的数据不属于 S,A 正常处理;
  4. 如果请求的数据属于正在迁移的 S,为确保数据已经位于 B,会先将该数据强制迁移到 B;
  5. 数据迁移完成后,请求被转发到 B 处理。

这种方式保证:

  • 扩容期间集群仍可提供服务;
  • 数据可以逐步迁移;
  • 避免一次性停机搬迁全部数据。

四、Redis 架构对比

架构 解决的问题 优点 局限
主从模式 数据副本 简单,具备基础容灾能力 Master 故障需人工切换,单主容量有限
哨兵模式 自动故障转移 自动监控、选主和切换 仍然只有一个 Master,不能解决分片和容量问题
Redis Cluster 分布式存储与自动恢复 多主分片、去中心化、官方支持 超大规模下可能产生 Gossip 风暴
中心化 Proxy 超大规模分片管理 客户端简单,可代理大量 Redis 节点 Proxy 和元信息系统的设计、运维更复杂

五、核心架构思想

  1. Redis 的价值不只是快,还包括丰富数据结构、原子操作和分布式能力。
  2. 主从复制采用全量复制加增量复制,是高可用的基础。
  3. 哨兵模式解决的是单个 Master 故障后的自动选主和切换问题。
  4. 哨兵不能解决单 Master 的容量和吞吐瓶颈,数据分片必须依靠集群模式。
  5. Redis Cluster 通过 16384 个哈希槽实现数据分片和路由。
  6. Gossip 让 Redis Cluster 去中心化,但只能保证元信息最终一致。
  7. 主观下线不能直接代表节点故障,需要多数节点确认后才形成客观下线。
  8. Redis Cluster 适合一般规模的分布式 Redis,但节点过多时可能出现 Gossip 风暴。
  9. 中心化 Proxy 架构牺牲部分去中心化特性,换取更强的超大规模扩展能力。
  10. Codis 通过 Proxy、ZooKeeper、槽位和 Server Group 实现集中路由、集群管理和平滑扩缩容。
  11. Redis 架构选型需要综合考虑数据量、请求量、节点规模、故障恢复和运维复杂度。

六、一句话总结

Redis 从主从复制、Sentinel 自动切主,演进到 Redis Cluster 多主分片,再到 Codis 等中心化 Proxy 架构,逐步解决数据副本、故障恢复、容量扩展和超大规模节点管理问题;中小规模集群可优先使用官方 Redis Cluster,而节点达到数千甚至上万时,中心化代理架构更有利于避免 Gossip 风暴并实现可控的平滑扩缩容。

© 2026 DadaVinCi's Blog

Elegant theme by Shiro · Made by Acris with ❤️