目录
[1.1 配置](#1.1 配置)
[info replication](#info replication)
[1.2 拓扑](#1.2 拓扑)
[1.3 PSYNC 机制与数据同步](#1.3 PSYNC 机制与数据同步)
[1.4 解决的问题与缺点](#1.4 解决的问题与缺点)
[1.5 Q&A](#1.5 Q&A)
[2. 哨兵机制(Sentinel):自动化的故障转移](#2. 哨兵机制(Sentinel):自动化的故障转移)
[2.1 监控与下线判定 (SDOWN vs ODOWN)](#2.1 监控与下线判定 (SDOWN vs ODOWN))
[2.2 故障转移与选举原理](#2.2 故障转移与选举原理)
[2.3 注意事项](#2.3 注意事项)
[2.4 Q&A](#2.4 Q&A)
[3. Redis Cluster 集群:海量数据的终极解法](#3. Redis Cluster 集群:海量数据的终极解法)
[3.1 数据分片算法:哈希槽](#3.1 数据分片算法:哈希槽)
[3.2 集群故障判定与迁移](#3.2 集群故障判定与迁移)
[3.3 集群扩容](#3.3 集群扩容)
[3.4 Q&A](#3.4 Q&A)
[4. 选型对比](#4. 选型对比)
**1.**主从复制(Replication):高可用的基石
主从复制解决了单节点可用性低和性能有限的问题,通过主写从读、多副本和多种拓扑提升读性能与数据可靠性;但它不能自动故障转移,主节点宕机后仍需人工或额外组件介入
1.1 配置
建立复制
参与复制的 Redis 实例划分为主节点(master)和从节点(slave)。每个从结点只能有⼀个主节点,而⼀个主节点可以同时具有多个从结点。复制的数据流是单向的,只能由主节点到从节点。配置复制的方式有以下三种:
- 在配置文件中加入 slaveof {masterHost} {masterPort},随 Redis 启动生效
- 在 redis-server 启动命令时加入 --slaveof {masterHost} {masterPort} 生效
- 直接使用 Redis 命令:slaveof {masterHost} {masterPort} 生效
注意:修改配置主要是修改从机的配置,主机配置不变
info replication
info replication 是 Redis 中用来查看主从复制(复制/Replica)状态信息的命令
它不是独立命令,而是 INFO 命令的一个 section:
redis-cli info replication
进入 redis-cli 后也可以直接:
info replication
-
在主机上执行
127.0.0.1:6379> info replication
Replication
role:master
connected_slaves:1
slave0:ip=127.0.0.1,port=6380,state=online,offset=100,lag=0
master_replid:2fbd35a8b8401b22eb92ff49ad5e42250b3e7a06
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:100
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:100
| 字段 | 含义 |
|---|---|
role |
当前节点角色为主节点 |
connected_slaves |
当前主节点已连接的从节点数量为 1 个 |
slave0 |
第 1 个从节点信息:IP 为 127.0.0.1,端口 6380,状态在线,复制偏移量 100,延迟 0 秒 |
master_replid |
主节点当前复制 ID,用于标识当前复制流 |
master_replid2 |
第二个复制 ID,用于故障转移后保留旧主节点的复制历史,以支持部分同步;全 0 表示当前没有 |
master_repl_offset |
主节点当前复制偏移量 |
second_repl_offset |
第二个复制 ID 对应的偏移量;-1 表示未使用 |
repl_backlog_active |
复制积压缓冲区是否启用,1 表示启用 |
repl_backlog_size |
复制积压缓冲区大小,单位字节,即 1MB |
repl_backlog_first_byte_offset |
复制积压缓冲区中第一个字节的偏移量 |
repl_backlog_histlen |
复制积压缓冲区中有效历史数据长度 |
-
从机上执行
127.0.0.1:6380> info replication
Replication
role:slave
master_host:127.0.0.1
master_port:6379
master_link_status:up
master_last_io_seconds_ago:1
master_sync_in_progress:0
slave_repl_offset:170
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:2fbd35a8b8401b22eb92ff49ad5e42250b3e7a06
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:170
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:170
| 字段 | 含义 |
|---|---|
role |
当前节点角色为从节点。Redis 5.0 后也常用 replica 表示 |
master_host |
主节点 IP 地址 |
master_port |
主节点端口 |
master_link_status |
与主节点连接状态正常;down 表示断开 |
master_last_io_seconds_ago |
最近一次与主节点通信距今 1 秒 |
master_sync_in_progress |
是否正在进行全量同步,0 表示没有 |
slave_repl_offset |
从节点当前的复制偏移量 |
slave_priority |
从节点优先级,供 Sentinel 选主使用;数值越小优先级越高,0 表示不会被提升为主节点 |
slave_read_only |
从节点是否只读,1 表示只读 |
connected_slaves |
当前节点作为主节点时连接的从节点数量;这里从节点下面没有从节点,所以为 0 |
master_replid |
从节点记录的主节点复制 ID |
master_replid2 |
第二个复制 ID,全 0 表示没有 |
master_repl_offset |
从节点记录的主节点复制偏移量,表示已处理到的位置 |
second_repl_offset |
第二个复制 ID 对应偏移量;-1 表示未使用 |
repl_backlog_active |
复制积压缓冲区是否启用,1 表示启用 |
repl_backlog_size |
复制积压缓冲区大小,单位字节,即 1MB |
repl_backlog_first_byte_offset |
复制积压缓冲区中第一个字节的偏移量 |
repl_backlog_histlen |
复制积压缓冲区中有效历史数据长度 |
断开复制
在从节点执行:
slaveof no one
可断开与主节点的复制关系。断开复制流程:
- 断开与主节点的复制关系
- 从节点晋升为主节点
特点:
- 从节点断开复制后,不会抛弃原有数据
- 只是无法再获取主节点上的后续数据变化
切主操作
在从节点执行:
slaveof {newMasterIp} {newMasterPort}
可将当前从节点的数据源切换到另一个主节点。切主操作流程:
- 断开与旧主节点的复制关系
- 与新主节点建立复制关系
- 删除从节点当前所有数据
- 从新主节点进行复制操作
安全性
- 对数据比较重要的节点,主节点可通过 requirepass 设置密码验证
- 设置后,所有客户端访问都必须使用 AUTH 命令进行校验
- 从节点与主节点之间的复制连接,是通过一个特殊标识的客户端完成的
- 因此,从节点需要配置 masterauth,并与主节点密码保持一致
- 只有这样,从节点才能正确连接主节点并发起复制流程
只读
- 默认情况下,从节点使用 slave-read-only=yes,即只读模式
- 复制方向只能从主节点到从节点
- 对从节点的任何修改,主节点都无法感知
- 修改从节点会造成主从数据不一致
- 所以线上环境不建议修改从节点的只读模式
传输延迟
- 主从节点一般部署在不同机器上,网络延迟需要重点考虑
- Redis 提供 repl-disable-tcp-nodelay 参数,用于控制是否禁用 TCP_NODELAY
- 默认值为 no,即不禁用,也就是开启 TCP_NODELAY 功能
- repl-disable-tcp-nodelay=no 时:
- 主节点产生的命令数据无论大小都会及时发送给从节点
- 主从延迟变小
- 但会增加网络带宽消耗
- 适用于网络环境良好的场景,如同机房部署
- repl-disable-tcp-nodelay=yes 时:
- 主节点会合并较小的 TCP 数据包,从而节省带宽
- 默认发送时间间隔取决于 Linux 内核,一般约为 40 毫秒
- 节省了带宽,但会增大主从之间的延迟
- 适用于网络环境复杂的场景,如跨机房部署
1.2 拓扑
| 拓扑结构 | 特点 | 优点 | 注意/缺点 | 适用场景 |
|---|---|---|---|---|
| 一主一从 | 一个主节点 + 一个从节点 | 简单,支持故障转移 | 主节点关闭持久化时需避免宕机后自动重启 | 简单复制、故障转移 |
| 一主多从 | 一个主节点 + 多个从节点,星形 | 读写分离,读命令可负载均衡 | 写并发高时,主节点需多次发送写命令,负载加重 | 读多写少 |
| 树形主从 | 从节点可继续作为下层的主节点 | 降低主节点负载,减少数据传输量 | 结构更复杂,管理成本更高 | 从节点较多、需要分层减压 |
1.3 PSYNC 机制与数据同步
Redis 使用 PSYNC 命令完成主从数据同步,PSYNC 的语法格式:
PSYNC replicationid offset
- 如果 replicationid 设为 ? 并且 offset 设为 -1 此时就是在尝试进行全量复制.
- 如果 replicationid offset 设为了具体的数值, 则是尝试进行部分复制.
PSYNC 运行流程
- 从节点向主节点发送:PSYNC replid offset;第一次复制时,从节点没有主节点复制 ID 和复制偏移量,所以发送:PSYNC ? -1
- 主节点根据 PSYNC 参数和自身数据情况决定响应结果:
- +FULLRESYNC replid offset:需要进行全量复制
- +CONTINUE:可以进行部分复制
- -ERR:主节点版本过低,不支持 PSYNC;从节点改用 SYNC 进行全量复制
- 使用特点:
- PSYNC 一般不需要手动执行,Redis 在主从复制模式下会自动调用
- SYNC 会阻塞 Redis Server 处理其他请求
- PSYNC 不会阻塞
复制过程分为三个阶段:
- **建立连接:**从节点保存主节点信息 -> 建立 TCP 连接 -> 发送 PING -> 权限验证
- **数据同步:**首次连接触发全量复制;网络闪断后触发部分复制
- **命令传播:**后续主节点的写命令持续同步给从节点
首次先全量复制,再实时复制;断线后先尝试部分复制,再实时复制;部分复制不行就退回全量复制,然后继续实时复制。它们共同组成完整的主从复制流程
核心概念
- Replid(复制ID):标识一个数据集。每个主节点重启或从节点晋升都会生成新的 replid。从节点会记录主节点的 master_replid 和 master_replid2(用于网络分区后的数据找回)
- Offset(偏移量):主从节点分别维护。主节点每执行一条写命令,offset 累加;从节点每秒上报自身 offset。replid + offset 共同标识了唯一的数据集
全量复制
- 全量复制是 Redis 最早支持的复制方式,也是主从第一次建立复制时必须经历的阶段
- 全量复制流程:
- 从节点发送 PSYNC ? -1 给主节点
- 主节点解析后判断需要全量复制,回复 +FULLRESYNC
- 从节点接收并保存主节点的运行信息
- 主节点执行 BGSAVE,生成 RDB 文件
- 主节点将 RDB 文件发送给从节点,从节点保存 RDB 数据到本地硬盘
- 主节点将"生成 RDB 到从节点接收完成"期间执行的写命令,暂存到主节点上为该从节点维护的输出缓冲区中。等从节点保存并加载完 RDB 后,主节点再把这些写命令发送给从节点,从节点按顺序执行,从而与主节点保持一致
- 从节点清空自身原有旧数据
- 从节点加载 RDB 文件,得到与主节点一致的数据
- 如果从节点开启了 AOF 持久化,加载 RDB 完成后会执行 BGREWRITEAOF,得到最新的 AOF 文件
- 全量复制成本很高:
- 主节点 BGSAVE 时间
- RDB 网络传输时间
- 从节点清空旧数据时间
- 从节点加载 RDB 时间
- 结论:
- 应尽量避免对已有大量数据集的 Redis 进行全量复制
无磁盘复制 :主节点 bgsave 时不落盘,直接通过网络发送 RDB,节省磁盘 IO
大内存场景慎用,可能撑爆网卡
部分复制
部分复制是 Redis 针对全量复制过高开销做出的优化措施,使用命令:
PSYNC replicationId offset
适用场景:从节点正在复制主节点时出现网络闪断或命令丢失等异常情况,从节点向主节点要求补发丢失的命令数据
部分复制流程:
- 主从节点之间网络中断,超过 repl-timeout 时间后,主节点认为从节点故障并中断复制连接
- 主从连接中断期间,主节点依然响应命令,但这些复制命令无法及时发送给从节点,于是暂时滞留在复制积压缓冲区中
- 网络恢复后,从节点再次连上主节点
- 从节点将之前保存的 replicationId 和复制偏移量作为 PSYNC 参数发送给主节点,请求部分复制
- 主节点接到 PSYNC 请求后进行必要验证,根据 offset 去复制积压缓冲区查找合适数据,并回复 +CONTINUE
- 主节点将需要从节点同步的数据发送给从节点,最终完成一致性
复制积压缓冲区
-
定义:保存在主节点上的一个固定长度的队列,默认大小为 1MB,当主节点有连接的从节点时被创建
-
写入机制:主节点响应写命令时,不但会把命令发送给从节点;还会写入复制积压缓冲区
-
作用:保存最近已复制的数据;用于部分复制和复制命令丢失的数据补救
-
相关统计信息可通过主节点 INFO replication 查看:
repl_backlog_active:1 // 开启复制缓冲区 repl_backlog_size:1048576 // 缓冲区最大长度 repl_backlog_first_byte_offset:7479 // 起始偏移量 repl_backlog_histlen:1048576 // 已保存数据的有效长度 -
可用偏移量范围:
[repl_backlog_first_byte_offset, repl_backlog_first_byte_offset + repl_backlog_histlen] -
本质:相当于一个基于数组实现的环形队列,上述区间中的值就是"数组下标"
-
重要限制:如果当前从节点需要的数据已经超出主节点积压缓冲区的范围,则无法进行部分复制,只能全量复制
实时复制与心跳
- **实时复制:**主从节点建立复制连接后;主节点会把自己收到的修改操作,通过 TCP 长连接源源不断传输给从节点;从节点根据这些请求同步修改自身数据,从而保持与主节点数据一致
- **心跳机制:**这种长连接需要通过心跳包维护连接状态;这里的心跳是应用层自己实现的心跳。主从节点彼此都有心跳检测机制,各自模拟成对方的客户端进行通信
- 主节点心跳:主节点默认每隔 10 秒对从节点发送 PING 命令;用于判断从节点的存活性和连接状态
- 从节点心跳:从节点默认每隔 1 秒向主节点发送:REPLCONF ACK {offset} 给主节点上报自身当前的复制偏移量
- 超时判定:如果主节点发现从节点通信延迟超过 repl-timeout 配置的值;默认 repl-timeout 为 60 秒;则判定从节点下线,断开复制客户端连接;从节点恢复连接后,心跳机制继续
1.4 解决的问题与缺点
问题:
- **单点可用性问题:**单个 Redis 节点可用性不高,故障后服务容易中断
- **单点性能问题:**单个 Redis 节点性能有限,读请求压力大时容易成为瓶颈
- 通过主从复制,可以为数据提供多个副本,提升可用性和读性能
缺点:
- 从节点过多时,复制数据延迟会非常明显
- 主节点挂掉后,从节点不会自动升级为主节点
- 只能通过人工干预恢复,或额外引入 Sentinel、Redis Cluster 等机制实现自动故障转移
1.5 Q&A
Q:主从复制是怎么实现的?
- Redis 主从复制基于 PSYNC 命令实现,从节点发送 PSYNC replid offset,主节点根据复制 ID 是否一致、偏移量是否还在复制积压缓冲区内,决定走全量复制还是部分复制;同步完成后进入命令传播阶段,主节点通过 TCP 长连接持续把写命令发给从节点,从节点执行并累加自身偏移量,同时主节点默认每 10 秒发 PING、从节点每秒回 REPLCONF ACK {offset},通过心跳维护连接和检测数据丢失
Q:全量复制和部分复制怎么选?
- 首次连接、复制 ID 不一致,或者从节点要的 offset 已经不在主节点复制积压缓冲区内时,只能走全量复制,主节点 BGSAVE 生成 RDB 发给从节点,期间写命令暂存到该从节点对应的输出缓冲区,等从节点加载完 RDB 再补发;如果复制 ID 一致且 offset 仍在复制积压缓冲区内,就走部分复制,只补发缺失的命令,开销远小于全量复制
Q:频繁全量复制怎么办?
- 核心是调大复制积压缓冲区 repl-backlog-size,它默认是 1MB 的环形队列,网络抖动断连后,如果从节点 offset 仍落在缓冲区内,就能触发部分复制而不是全量复制;可按"峰值写入速率 × 最大重连时间 × 2"估算,生产环境常设为 64MB~256MB,高写入场景可更大,同时可开无磁盘复制加快全量复制速度
Q:主从延迟怎么解决?
- Redis 默认 repl-disable-tcp-nodelay no,即开启 TCP_NODELAY,主节点产生命令会立即发送给从节点,减小延迟;但跨机房部署时建议改为 yes 以节省带宽,代价是内核合并小包,默认约 40ms 延迟。此外还可优化网络、控制写入峰值、提升从节点性能、调大 repl-backlog-size,并用 min-slaves-max-lag 等参数在延迟过大时拒绝写入,避免主从差距继续扩大
2. 哨兵机制(Sentinel):自动化的故障转移
2.1 监控与下线判定 (SDOWN vs ODOWN)
哨兵节点(独立进程 redis-sentinel)定期监控所有 Redis 数据节点,其余哨兵节点是否可达
- 主观下线 (SDOWN):单个哨兵发现主节点超过 down-after-milliseconds(默认30秒)没响应。此时可能仅仅是该哨兵网络不通
- 客观下线 (ODOWN):该哨兵向其他哨兵发起投票(sentinel monitor <quorum> 法定票数)。票数 >= quorum 才能判定主节点真的挂了
- 建议哨兵节点为奇数个(至少3个),因为 Raft 选举需要半数以上同意,奇数可以避免平票,提高选举效率,防止脑裂
什么是脑裂?怎么解决?
- 脑裂是指网络分区后,原 Master 与哨兵失联,但客户端仍能连上原 Master 写入;哨兵选出新 Master,导致集群出现两个 Master 同时写。网络恢复后原 Master 降为 Slave,期间写入的数据可能丢失
- 缓解方案是在主节点配置
min-replicas-to-write 1和min-replicas-max-lag 10,表示如果健康从节点少于 1 个,或从节点同步延迟超过 10 秒,主节点就拒绝写命令。这能降低旧主在分区期间继续写入的概率,但不能完全杜绝脑裂,也不能保证数据绝对安全。还需要配合哨兵奇数部署、合理 quorum、客户端正确连接等措施
2.2 故障转移与选举原理
当主节点被判定为 ODOWN 后,触发故障转移:
- **选举 Leader 哨兵:**哨兵之间选出 Leader。可以简单的认为谁先发起拉票(网络延迟最小),谁就大概率当选
- Leader 挑选新主节点: 从所有从节点中筛选,规则依次为:
- 过滤掉长时间未通信的节点(保证数据相对完整)
- slave-priority 最高(数值最小)
- 复制偏移量 offset 最大(数据最新)
- run id 最小(字典序,避免平票)
- **执行转移:**向新主发送 slaveof no one,向其他从发送 slaveof <newMaster>,并通知客户端
- **旧主恢复:**旧主重启后,会被哨兵作为从节点加入集群
2.3 注意事项
- 哨兵节点不能只有一个,否则哨兵节点挂了也会影响系统可用性
- 哨兵节点最好是奇数个,方便选举 Leader,得票更容易超过半数
- 哨兵节点不负责存储数据,仍然由 Redis 主从节点负责存储
- 哨兵 + 主从复制解决的问题是"提高可用性",不能解决"数据极端情况下写丢失"的问题
- 哨兵 + 主从复制不能提高数据的存储容量,当需要存储的数据接近或超过机器的物理内存时,这种结构就难以胜任。为了能存储更多数据,就引入了集群
2.4 Q&A
Q:哨兵是怎么判定主节点下线的?
- Sentinel 会定期向主节点发送 PING,如果超过 down-after-milliseconds 没收到有效回复,单个 Sentinel 先把主节点标记为主观下线;随后它会向其他 Sentinel 发送 is-master-down-by-addr 询问,当认为主节点下线的 Sentinel 数量达到配置的 quorum 时,就判定为客观下线,进而触发故障转移流程
Q:客观下线后,谁来做故障转移?怎么选主?
- 客观下线后,Sentinel 集群会先选举出一个 Leader Sentinel 来执行故障转移,选举类似 Raft,需要获得多数票且达到 quorum;然后 Leader 从从节点中挑选新主节点,优先级依次是:slave-priority 最高的、复制偏移量 offset 最大的(数据最新)、runid 最小的;选中后向该从节点发送 SLAVEOF NO ONE 将其提升为主节点,再让其他从节点复制新主节点,并通知客户端更新主节点地址
Q:哨兵集群节点数量为什么建议是奇数?
- 因为 Sentinel 判定客观下线和选举 Leader 都需要超过半数的同意,奇数个节点更容易达到多数,避免平票,同时在容错能力和成本之间更优;比如 3 个节点允许挂 1 个,4 个节点虽然多了一个但多数仍是 3,挂 2 个就失去多数,所以奇数个更划算
Q:哨兵模式能解决写压力吗?
- 不能。哨兵 + 主从复制主要解决的是高可用性,即主节点故障时自动切换;写操作仍然只能在主节点执行,从节点默认只读,增加从节点或哨兵并不能分担写压力。要解决写压力,需要引入分片集群,比如 Redis Cluster
3. Redis Cluster 集群:海量数据的终极解法
3.1 数据分片算法:哈希槽
Redis Cluster 引入多组 Master/Slave,每组存一部分数据,实现分布式存储
- 哈希槽算法:hash_slot = crc16(key) % 16384。将所有数据映射到 16384 个槽位
- 为什么是 16384?
- 节点间心跳包需要携带槽位信息(位图)。16384 个槽位使用 16384 / 8 = 2048 字节 (2KB) 的位图即可表示;如果使用 65536,则需要 8KB。频繁的心跳包中,2KB 的开销是可接受的,8KB 则过大
- Redis 作者建议集群节点不应超过 1000 个,16384 个槽位足够 1000 个节点分配
- 不用一致性哈希: 一致性哈希容易产生数据倾斜,且扩容时较难均匀分配
- 不用简单哈希求余:扩容时 N 变化,几乎所有的 Key 都需要重新映射,数据迁移成本极高
3.2 集群故障判定与迁移
- 故障判定:
- 节点间周期性 PING/PONG
- 若 A 连不上 B,A 标记 B 为 PFAIL(主观下线)
- A 向其他节点八卦,若超过半数主节点认为 B 是 PFAIL,则 B 标记为 FAIL(客观下线)
- 集群宕机条件:某个分片的主从全挂 / 某分片主挂且无从 / 超过半数的主节点挂掉
- 故障迁移:
- 从节点检查自身是否有资格(与主节点断连时间未超阈值)
- 休眠时间计算:500ms + 0, 500ms 随机时间 + rank * 1000ms(rank 与 offset 相关,offset 越大,rank 越小,休眠越短,越容易先拉票)
- 先醒来的从节点向所有主节点拉票,获得半数以上投票后,晋升为新 Master,接管原 Master 的槽位
3.3 集群扩容
- **扩容:**add-node 加入新主节点 -> reshard 重新分配槽位(从旧节点搬运部分槽位给新节点) -> add-node --cluster-slave 为新主添加从节点
- **重定向机制:**客户端访问 Key 不在当前节点时,会收到 MOVED 重定向。如果正在发生槽位迁移,则可能收到 ASK 重定向(临时重定向,客户端需先发送 ASKING 命令)。客户端必须使用 -c 参数启动
- **Hash Tag:**如果业务需要多个 Key 原子的操作(如事务、Lua 脚本),必须让这些 Key 落在同一个槽位。可以使用 {user:1000}:name 和 {user:1000}:age,Redis 只计算 {} 内的内容,确保它们落在同一个分片
3.4 Q&A
Q:数据量暴增,单机内存扛不住了,怎么办?
- 官方方案是 Redis Cluster,它把整个数据集划分为 16384 个哈希槽,每个节点负责一部分槽位,客户端根据 key 计算槽位并路由到对应节点;Redis Cluster 是官方原生支持、去中心化的,能同时解决容量和写压力问题
Q:一致性哈希有什么缺陷?Redis 怎么分片?
- 一致性哈希虽然能在节点增减时只影响相邻数据,但存在数据倾斜问题,节点少时容易分布不均,需要引入虚拟节点来平衡,而且实现和运维相对复杂;Redis 没有采用一致性哈希,而是用哈希槽分片:对 key 做 CRC16 计算,然后对 16384 取模得到槽位,每个节点负责一部分槽位,槽位可以在节点间迁移,扩容缩容时只需移动部分槽位,客户端通过集群协议获取槽位映射,实现去中心化路由
Q:为什么是 16384 个槽位?
- 主要权衡了心跳包大小和集群规模:Redis Cluster 节点间通过 Gossip 协议交换信息,心跳包里会携带槽位位图,16384 个槽位用位图表示是 2KB,而 65536 个槽位是 8KB,心跳包太大会浪费带宽;同时集群节点数通常不超过 1000 个,16384 个槽位足够均匀分配,槽位少也便于压缩、传播和迁移,所以 16384 是带宽、规模和效率之间的最佳平衡点
Q:Cluster 集群怎么判定节点故障?怎么扩容?
- 节点间通过 Gossip 协议定期发送 PING/PONG,如果某节点超过 cluster-node-timeout 未响应,其他节点先标记它为 PFAIL(疑似下线);当多数主节点都认为该节点 PFAIL 时,就升级为 FAIL(客观下线),然后触发故障转移,从节点发起选举,获得多数主节点投票后提升为新主节点。扩容时先用 redis-cli --cluster add-node 把新节点加入集群,再用 reshard 把部分槽位从旧节点迁移到新节点,迁移过程中槽位有 MIGRATING 和 IMPORTING 状态,客户端访问时通过 ASK 重定向保证数据正确
4. 选型对比
| 架构模式 | 解决的核心问题 | 核心优势 | 致命缺点 / 边界 |
|---|---|---|---|
| 主从复制 | 数据热备份、读性能扩展 | 简单、易配置、读写分离 | 主节点宕机需人工介入; 写/存储受单机限制 |
| 哨兵机制 | 主从架构的自动化故障转移 | 高可用(HA),无需人工干预,客户端透明 | 未解决写压力与存储容量; 配置略复杂 |
| Cluster 集群 | 海量数据存储、高并发写入 | 分布式分片,水平扩展(加机器即可);高可用 | 架构复杂;客户端需支持重定向;跨槽位操作受限 |