Skip to content

缓存如何做到高可用? ​

上一篇讨论的是:

缓存如何与数据库协同工作(Cache Aside、Write Through 等)。

这一篇开始讨论另一个关键问题:

如果缓存本身挂了怎么办?

很多人学习缓存时容易忽略一点:

text
缓存提高了系统性能
↓
缓存也成为系统关键依赖
↓
缓存自身可能成为单点故障

当业务大量依赖 Redis 后,Redis 已经不是“优化组件”,而是核心基础设施。

因此:

缓存不仅要快,还必须高可用。

一、为什么缓存会成为高可用问题 ​

假设系统架构:

text
用户
 ↓
Redis
 ↓
MySQL

正常情况下:

text
95%
99%
请求
↓
Redis直接返回

数据库压力很小。


但如果 Redis 突然宕机:

text
Redis
✖

所有请求都会直接访问数据库:

text
用户
 ↓
MySQL

结果:

text
数据库QPS暴涨
↓
数据库崩溃
↓
整个系统雪崩

因此:

缓存故障往往会放大成整个系统故障。

二、缓存高可用的核心思想 ​

文章强调:

缓存高可用本质上还是那套互联网设计思想:

不让单个节点决定系统生死。

也就是:

text
消灭单点

因此:

单机 Redis:

text
Redis

必须演进成:

text
Redis集群

三、主从复制:最基础的高可用方案 ​

Redis 最基础方案:

text
      Master
      /    \
     /      \
 Slave1   Slave2

Master:

负责:

text
读
写

Slave:

负责:

text
同步数据

主节点收到写请求:

text
SET key value

之后:

同步给从节点。

这样:

Master 挂掉时:

从节点已经有完整数据。

四、主从复制解决了什么问题 ​

解决:

数据备份 ​

主节点挂掉:

数据不会丢失。

读扩展 ​

部分请求可以:

text
读Slave

减轻压力。

但是:

文章指出:

主从复制本身并不等于高可用。

因为:

Master 挂了以后:

系统仍然不能写。

因此:

还需要故障切换。

五、Redis Sentinel(哨兵模式) ​

这就是 Redis 的经典高可用方案。

架构:

text
      Sentinel
      Sentinel
      Sentinel

          │

      Master
      /    \
 Slave1  Slave2

Sentinel 的职责:

1. 监控 ​

持续检查:

text
Redis是否存活

2. 通知 ​

发现故障:

通知客户端。

3. 自动故障转移 ​

如果:

text
Master挂了

则:

text
Slave
↓
升级
↓
新Master

客户端自动切换。

整个过程:

无需人工参与。

六、为什么 Sentinel 要多个节点 ​

不能:

text
一个Sentinel

因为:

Sentinel 自己也可能挂。

因此:

通常:

text
3个
5个

Sentinel。

通过:

text
多数派投票

决定:

text
Master是否真的挂了

避免误判。

七、Redis Cluster ​

随着业务继续增长:

新的问题出现:

单机内存不够了。

例如:

text
Redis
128GB

已经达到极限。

此时:

仅仅主从复制不够。

因为:

数据仍然在同一台机器。

于是:

Redis Cluster 出现。

八、Redis Cluster 的核心思想 ​

核心:

数据分片。

例如:

text
Node1
Node2
Node3

不同 Key:

存储在不同节点。

例如:

text
user:1
→ Node1

user:2
→ Node2

user:3
→ Node3

这样:

容量可以无限扩展。

九、Redis 的 Hash Slot ​

Cluster 采用:

text
16384个Slot

机制。

例如:

text
Node1
0~5000

Node2
5001~10000

Node3
10001~16383

Key:

先计算:

text
CRC16(key)

然后:

text
%16384

确定 Slot。

Slot 决定:

数据在哪个节点。

因此:

新增节点时:

只需要迁移 Slot。

而不是迁移全部数据。

十、Cluster 如何保证高可用 ​

每个节点:

不仅有:

text
Master

还有:

text
Slave

例如:

text
Master1
 ↓
Slave1

Master2
 ↓
Slave2

Master 挂掉:

text
Slave
↓
升级
↓
Master

因此:

既实现:

text
容量扩展

又实现:

text
高可用

十一、缓存高可用面临的新问题 ​

文章特别强调:

高可用不是没有代价。

1. 数据同步延迟 ​

Master:

text
写入成功

并不意味着:

Slave 已同步。

因此:

极端情况下:

可能丢失少量数据。

这是:

Redis 默认:

text
最终一致性

方案。

2. 脑裂(Split Brain) ​

例如:

网络故障。

Master:

认为:

text
Sentinel失联

Sentinel:

认为:

text
Master挂了

于是:

产生两个 Master。

导致:

数据不一致。

这是分布式系统经典问题。

十二、缓存高可用与数据库高可用的区别 ​

数据库:

核心目标:

text
数据不能丢

缓存:

核心目标:

text
服务不能停

因为:

缓存本质上是:

text
数据库副本

最坏情况:

缓存全部丢失。

仍然可以:

text
回源数据库

恢复。

因此:

缓存高可用更关注:

text
服务连续性

而非:

text
绝对数据安全

十三、本章最核心的工程思想 ​

文章最重要的一句话其实是:

高可用缓存的本质是通过副本机制和自动故障转移,让缓存节点故障不影响业务连续运行。

具体演进路径:

text
单机Redis
     ↓
主从复制
     ↓
Sentinel
     ↓
Redis Cluster

本质上都是在解决两个问题:

text
节点挂了怎么办?

容量不够怎么办?

十四、本章核心脉络 ​

text
缓存成为核心组件
       ↓
单机Redis风险过高
       ↓
主从复制
       ↓
故障转移
       ↓
Sentinel
       ↓
容量继续增长
       ↓
Redis Cluster
       ↓
分片+副本
       ↓
高可用缓存集群

一句话总结 ​

当缓存成为系统流量入口后,它本身必须具备高可用能力。Redis 通过主从复制实现数据冗余,通过 Sentinel 实现自动故障转移,通过 Cluster 实现数据分片和横向扩展,最终构建出既能承载海量访问、又不会因单点故障导致系统雪崩的高可用缓存架构。

Released under the MIT License.