在后端开发中,Redis几乎是标配的缓存中间件。但很多人只会基础的读写操作,对高可用架构一知半解。
面试时经常被问:Redis单机有什么问题?主从架构解决了什么痛点?哨兵和集群的核心作用区别是什么?生产环境该怎么选型?
本文全程问题驱动,从单机痛点出发,循序渐进带你吃透 Redis 主从、哨兵、集群三套高可用架构,彻底搞懂每一层设计的意义、核心原理与落地逻辑。
一、为什么不能用单机Redis?高可用的初衷是什么?
我们先思考一个核心问题:生产环境为什么绝对不推荐单机Redis?
单机Redis存在两个致命短板,直接影响系统稳定性:
-
单点故障风险:一旦Redis进程宕机、服务器重启或网络异常,所有缓存请求全部失效。大量并发请求会直接穿透到MySQL等数据库,瞬间压垮数据库,引发系统雪崩。
-
性能瓶颈受限:单机读写能力、内存容量固定,面对高并发读、海量数据存储场景,完全无法支撑业务扩容。
为了解决以上问题,Redis 逐步迭代出三套高可用方案:主从架构 → 哨兵架构 → 集群架构,层层递进解决故障、性能、容量三大问题。
二、主从架构
什么是主从架构?核心价值是什么?
首先解答核心疑问:为什么需要主从架构?
单机Redis最大的问题是无数据冗余、无读写分离。而主从架构通过「一主多从」的节点部署,完美解决这两个问题:
-
数据冗余:主节点数据自动同步到从节点,避免单节点宕机导致数据丢失
-
读写分离:所有写请求统一走主节点,所有读请求分摊到从节点,大幅提升读吞吐量
简单来说:主从架构就是给Redis做「数据备份+读负载分担」,是高可用的基础架构。
核心原理:主从复制机制
主从架构的核心是主从复制,定义很简单:将主节点(Master)的所有数据,自动同步到所有从节点(Slave),最大限度保证主从数据一致性。
主从复制分为两种场景:全量复制、增量复制,分别应对不同的同步场景。
全量复制:
触发场景:新从节点首次接入集群、从节点断线太久,本地数据和主节点差距过大。
完整执行流程,帮你彻底理清细节:
-
主节点执行
bgsave命令,在后台生成当前内存数据的 RDB 快照文件; -
主节点开启复制缓冲区,临时存储生成RDB文件期间的所有新写命令;
-
主节点将完整的RDB文件发送给从节点;
-
从节点清空本地旧数据,加载RDB文件完成数据初始化;
-
主节点将缓冲区暂存的写命令,批量发送给从节点执行,补齐快照生成期间的数据差异。
增量复制
全量复制完成后,主从节点会建立一条永久TCP长连接。
后续主节点每收到一条写命令,都会通过这条长连接异步实时同步给所有从节点,保证主从数据实时一致,无需重复全量同步,性能极高。
全量复制为什么用RDB,不用AOF?
-
文件体积更小、传输更快:RDB是压缩后的二进制数据,存储的是内存快照;AOF是纯文本写命令日志,同等数据量下文件体积远大于RDB,网络传输耗时更长。
-
数据加载效率更高:从节点加载RDB只需直接解析二进制文件写入内存;而AOF需要逐条重放所有命令,海量数据场景下耗时差距极大。
简单总结:RDB适合整体数据同步,AOF适合持久化落地,各司其职。
主从架构的致命缺陷
主从架构解决了数据冗余和读性能问题,但主节点依然是单点:
一旦主节点宕机,整个集群无法自动切换主节点,需要人工介入修改配置、提升从节点为主节点,不仅效率极低,还容易人为出错,导致服务长时间不可用。
为了解决主节点故障人工切换的问题,哨兵机制应运而生。
三、哨兵架构:实现主从架构的自动故障转移
哨兵的核心作用
一句话概括:哨兵是主从架构的“监控管家”,专门解决主节点故障后的自动切换问题,实现Redis服务的真正高可用。
核心能力三点:实时监控节点状态、故障自动判定、自动故障转移。
哨兵如何判断主节点真的挂了?
很多人以为哨兵超时没响应就判定宕机,其实不然!为了避免网络抖动、单哨兵异常导致的误判,哨兵采用「主观下线+客观下线」双重判定机制。
-
主观下线:单个哨兵节点,在指定超时时间内,没有收到主节点的PING响应,单方面认为主节点下线。 特点:仅单节点判定,可信度低,可能是哨兵自身网络问题,不触发故障转移。
-
客观下线:做出主观下线的哨兵,会主动询问集群内其他所有哨兵节点;当超过半数哨兵都判定主节点下线,才正式确认主节点故障,标记为客观下线,触发后续故障转移。
生产环境哨兵必须部署3节点及以上,核心目的就是满足半数投票机制,杜绝误判。
哨兵完整故障转移过程
主节点客观下线后,哨兵集群会自动完成一整套切换流程,全程无人干预:
第一步:选举哨兵Leader
多个哨兵不能同时操作切换,会通过Raft算法选举出一个唯一的Leader哨兵,由它全权主导故障转移,避免冲突。
第二步:筛选最优新主节点
Leader哨兵会从所有存活的从节点中,按优先级从高到低筛选,规则依次兜底:
-
优先排除已下线、断线时间过长的无效从节点;
-
节点优先级数值越小,优先级越高(可手动配置);
-
优先级相同时,对比复制偏移量,偏移量越大,数据越完整,优先选中;
-
偏移量一致时,选择运行ID最小的节点作为新主节点。
第三步:执行集群切换
-
Leader哨兵发送指令,将筛选出的最优从节点提升为新主节点;
-
通知集群内所有剩余从节点,修改复制源,改为同步新主节点的数据;
-
通过哨兵发布/订阅机制,将新主节点的IP、端口推送给所有客户端,实现业务无缝切换;
-
持续监控旧主节点,待其恢复上线后,自动将其降级为从节点,接入新集群。
哨兵架构的瓶颈
主从+哨兵的组合,解决了高可用、读扩容、故障自动恢复三大问题,但依然存在两个无法突破的瓶颈:
-
容量瓶颈:所有数据最终都存储在主节点,单机内存有限,无法支撑海量数据存储;
-
写性能瓶颈:所有写请求只能落在唯一的主节点,无法横向扩展写能力,高并发写场景完全扛不住。
想要解决容量和写性能的横向扩容问题,就必须用到 Redis集群(Cluster)。
四、Redis集群:突破容量与写性能的终极方案
集群的核心价值
简单来说,集群就是多主多从的分布式架构:
-
将海量数据分散到多个主节点存储,突破单机内存限制;
-
多个主节点同时承接写请求,实现写性能横向扩容;
-
支持在线不停机扩容、缩容,完美适配业务迭代。
同时为了保证每个节点的高可用,集群中每一个主节点都会搭配对应的从节点,实现数据冗余。
核心原理:Hash槽数据分片机制
集群如何把数据均匀分散到不同节点?核心是16384个Hash槽机制,这是Redis集群的核心精髓。
-
Redis集群预分配 0~16383 共16384个固定Hash槽,集群初始化时会将所有槽位均匀分配给各个主节点;
-
客户端读写任意Key时,通过固定公式计算槽位:
CRC16(key) % 16384; -
根据计算出的槽位,精准路由到对应负责的主节点执行读写操作。
针对扩容、缩容场景:集群会在线迁移部分Hash槽到新节点,若客户端请求的Key处于迁移中,集群会通过重定向机制,引导客户端请求新节点,全程不影响业务使用。
节点通信机制:Gossip协议
Redis集群不再依赖哨兵监控节点状态,而是通过Gossip流言协议实现所有节点信息同步。
核心思想:每个节点周期性随机和其他节点通信,同步自身状态、节点列表、槽位分配信息,最终实现全网节点数据一致。主要包含4种核心消息:
-
MEET消息:新节点加入集群时,现有节点发送MEET消息,将新节点纳入集群网络;
-
PING消息:节点周期性发送,携带自身状态、已知节点、槽位信息,用于心跳检测;
-
PONG消息:收到PING/MEET消息后的响应消息,确认节点存活并同步自身信息;
-
FAIL消息:节点被判定下线后,全网广播FAIL消息,所有节点同步标记该节点下线。
集群节点故障如何处理?
集群的故障判定逻辑和哨兵一致,采用「主观下线+客观下线」,由Gossip协议完成全网判定:
-
主观下线:单个节点检测到其他节点心跳超时,单方面标记其下线;
-
客观下线:超过半数主节点判定某节点下线,全网广播FAIL消息,正式确认故障,触发故障转移。
根据故障节点角色,处理方式不同:
-
从节点故障:主节点直接将该从节点从复制列表中移除,不影响集群整体运行,无业务影响;
-
主节点故障:集群内其他主节点发起投票,选举该故障主节点的最优从节点,升级为新主节点,接管原有Hash槽,同步全网节点更新配置,恢复集群服务。


1348

被折叠的 条评论
为什么被折叠?



