Redis 通过多种机制和架构来保证其高可用性,核心目标是确保服务在发生部分节点故障(如主节点宕机)时,仍能继续提供服务,并尽可能减少数据丢失。主要策略包括:
🧱 1. 主从复制 (Replication)
-
基本原理: 这是高可用性的基础。一个 Redis 实例作为主节点 (Master),负责处理写操作。一个或多个 Redis 实例作为从节点 (Slaves / Replicas),异步复制主节点的数据。
-
如何保证可用性:
-
数据冗余: 数据在多个节点上有副本。即使主节点宕机,从节点上仍有(可能稍旧)的数据副本。
-
读负载均衡: 客户端可以将读请求分发到从节点,减轻主节点压力,间接提升整体服务的稳定性(写请求仍必须发送到主节点)。
-
故障转移的基础: 主从结构是实现自动故障转移(由 Sentinel 或 Cluster 触发)的前提。
-
🔍 2. Redis Sentinel (哨兵)
-
基本原理: Sentinel 是一个独立的分布式系统,由一个或多个 Sentinel 进程组成。它不存储数据,而是专门用于监控 Redis 主从节点,并在主节点故障时自动执行故障转移。
-
核心功能:
-
监控 (Monitoring): 持续检查主节点和从节点是否正常运行。
-
通知 (Notification): 当被监控的 Redis 实例出现问题时,可以通过 API 或其他集成方式通知系统管理员或其他应用程序。
-
自动故障转移 (Automatic Failover): 这是 Sentinel 的核心价值。当 Sentinel 集群(需要多个 Sentinel 实例达成共识)判定主节点客观下线 (Objectively Down) 时,它会执行以下操作:
-
在存活的从节点中,根据配置规则(如优先级、复制偏移量)选举出一个新的主节点。
-
让其他从节点改为复制这个新的主节点。
-
通知客户端配置更新,客户端应连接新的主节点。
-
-
配置提供者 (Configuration Provider): 客户端可以向 Sentinel 查询当前的主节点地址。
-
-
如何保证可用性:
-
自动化故障转移: 主节点宕机后,能在较短时间内(秒级到分钟级,取决于配置)自动切换到一个从节点,恢复写服务,无需人工干预。
-
Sentinel 自身高可用: Sentinel 设计为分布式集群。即使个别 Sentinel 进程挂掉,只要集群中还有多数 (
quorum
) Sentinel 进程存活并能达成共识,就能正常工作。 -
避免脑裂: Sentinel 通过
quorum
和majority
机制(需要多个 Sentinel 确认主节点下线)来减少误判和脑裂发生的概率。
-
-
适用场景: 中小规模部署,需要自动故障转移但不需要大规模水平扩展的场景。是 Redis 早期推荐的高可用方案。
🌐 3. Redis Cluster (集群)
-
基本原理: Redis 内置的分布式数据分片和高可用方案。它将数据自动分片 (Sharding) 到多个节点(称为分片或槽位 Slot)上,每个分片由一个主节点和至少一个从节点组成。
-
核心功能:
-
数据分片: 数据按 key 的哈希值分布到
16384
个槽位中,槽位再分配到不同的主节点上。客户端可以直接将请求路由到正确的节点。 -
主从复制: 每个分片内部是主从结构,数据在主节点和其从节点间复制。
-
自动故障转移: 每个分片内部的高可用机制与 Sentinel 类似,但由集群本身管理。当某个主节点被集群中的大多数主节点判定为故障时,其对应的从节点会自动晋升为主节点。
-
节点间通信 (Gossip): 集群节点间通过 Gossip 协议交换状态信息,维护集群拓扑视图。
-
-
如何保证可用性:
-
节点级冗余: 每个分片有主从节点,主节点故障时从节点能接管。
-
服务连续性: 只要不是某个分片的主节点和其所有从节点同时挂掉(或者大多数主节点挂掉导致无法达成共识),集群就能继续提供服务。故障转移在分片内部自动完成。
-
无中心化: 没有单点故障(不像 Sentinel 需要独立的 Sentinel 进程,但 Cluster 自身的节点也承担管理功能)。
-
可扩展性: 支持水平扩展,通过增加分片来提升性能和容量,这也间接增强了整体系统的可用性。
-
-
适用场景: 大规模部署,需要同时满足高可用性、大容量和高性能需求的场景。是 Redis 官方推荐的现代高可用和扩展方案。
3. Redis Cluster (集群) 的数据分片是按照节点来分还是槽位slot来分的
这是一个非常好的问题!Redis Cluster 的数据分片机制的核心是 槽位 (Slot),节点 (Node) 是槽位的物理承载者。更准确地说:
-
数据分片的基本单位是槽位 (Slot):
-
Redis Cluster 将整个数据空间划分为 16384 (16K) 个固定的逻辑槽位 (Slot)。
-
每个有效的键 (Key) 通过一个哈希函数
CRC16(key) % 16384
计算出一个介于 0 到 16383 之间的值,这个值决定了这个键属于哪个槽位。 -
数据分片是按照 Key 映射到哪个槽位来决定的。 同一个槽位内的所有 Key 会被存储在一起。
-
-
节点 (Node) 负责管理槽位:
-
集群中的每个 主节点 (Master Node) 会被分配一个或多个槽位范围(例如:节点 A 负责槽位 0-5000,节点 B 负责槽位 5001-10000,节点 C 负责槽位 10001-16383)。
-
槽位到节点的映射关系 (Cluster Slots) 是整个集群状态的核心元数据。每个节点都维护一份完整的、最新的槽位分配信息。
-
客户端可以向集群中任意节点发送请求。如果请求的 Key 不属于该节点负责的槽位,节点会根据其存储的槽位映射信息,向客户端返回一个
MOVED
或ASK
重定向错误,告知客户端正确的节点地址。
-
总结关键点:
-
逻辑分片靠槽位: 数据空间被逻辑划分为 16384 个 Slot。Key 通过哈希计算固定归属到一个 Slot。
-
物理存储靠节点: 集群将这些 Slot 动态地分配给各个主节点来负责存储和管理。一个主节点管理一个或多个连续的 Slot 范围。
-
动态分配: Slot 到节点的映射关系不是固定的。可以通过集群管理命令 (
CLUSTER ADDSLOTS
,CLUSTER DELSLOTS
,CLUSTER SETSLOT
等) 动态地将 Slot 从一个节点迁移到另一个节点,这是 Redis Cluster 实现水平扩展(扩容/缩容)和负载均衡的基础。 -
高可用基础: 每个 Slot 的数据在主节点和其从节点之间复制。如果主节点故障,其负责的 Slot 会被提升的从节点接管,保证这些 Slot 的数据服务不中断。
为什么说“按 Slot 分”比“按节点分”更准确?
-
抽象层: Slot 提供了一个稳定的逻辑抽象层。客户端只需要知道 Key 属于哪个 Slot(通过固定的哈希计算),而不需要关心当前是哪个物理节点在负责这个 Slot。
-
灵活性: 数据迁移是以 Slot 为单位进行的。当需要增加节点(扩容)或减少节点(缩容)时,管理员或自动化工具可以将一组特定的 Slot 从源节点迁移到目标节点。这期间集群仍然可用(部分 Slot 可能处于迁移状态)。如果直接“按节点分”,迁移的粒度会非常大(整个节点的数据),操作更复杂且影响更大。
-
均衡性: 理论上,16384 个 Slot 可以非常均匀地分配给节点。即使节点数量不是 16384 的约数,通过合理分配 Slot 范围,也能实现较好的数据负载均衡。直接按节点分(比如简单的哈希取模节点数)在节点数量变化时会导致大量的数据重新分布(Resharding)。
简单来说:
-
问:数据存在哪里? 答:数据根据 Key 的哈希值存放在其对应的 Slot 里。
-
问:Slot 由谁管理? 答:Slot 由集群动态分配给具体的主节点(及其从节点)来管理存储和访问。
因此,Redis Cluster 的数据分片首先是按照槽位 (Slot) 进行逻辑划分,然后由节点 (Node) 负责物理存储和管理分配给它的槽位。Slot 是分片的核心抽象和操作单元。
🛠 4. 其他增强可用性的措施
-
持久化 (Persistence): 虽然不是直接的“在线可用性”,但 RDB 快照和 AOF 日志保证了在服务器重启后能恢复数据,是数据可靠性的基础。合理的持久化配置可以减少故障转移后的数据丢失量。
-
网络和部署: 将主节点和从节点部署在不同的物理机、机架甚至可用区(AZ)上,避免单点物理故障(如断电、网络中断)同时影响主从节点。
-
配置优化: 合理设置
min-slaves-to-write
和min-slaves-max-lag
选项,确保主节点在足够数量的从节点同步状态良好时才接受写操作,可以防止在主节点故障且未同步足够数据到从节点的情况下进行故障切换导致的数据丢失风险(但会牺牲一些可用性)。 -
客户端处理: 高可用也需要客户端配合。客户端库需要支持 Sentinel 或 Cluster 协议,能够在故障转移后自动重定向请求到新的主节点,并处理重试和连接错误。
-
监控告警: 完善的监控系统(如 Prometheus + Grafana)对节点状态、内存、CPU、网络、复制延迟、Sentinel/Cluster 状态等进行监控,及时发现潜在问题并告警。
-
定期维护: 滚动重启、版本升级、备份验证等。
📌 总结与选择
-
主从复制 (Replication) 是基础,提供数据冗余和读扩展。
-
Redis Sentinel 在主从复制基础上提供自动化故障转移,适合中小规模、非分片的 Redis 高可用部署。
-
Redis Cluster 提供了集数据分片、主从复制、自动化故障转移于一体的高可用和可扩展解决方案,适合大规模、分布式部署,是当前复杂场景下的首选方案。
-
持久化、合理部署、客户端支持、监控告警是支撑任何高可用方案有效运行的必要条件。
选择依据:
-
需要自动故障转移但数据量不大? -> 主从 + Sentinel
-
需要海量数据、高并发、自动故障转移? -> Redis Cluster
-
对数据丢失容忍度极低? -> 优先保证持久化安全配置(AOF + fsync everysec/always)并配合
min-slaves-to-write
,但可能降低写入可用性。 -
预算有限/简单场景? -> 单主多从 + 手动故障转移(不推荐生产环境)。
理解这些机制并根据实际业务需求(数据量、性能要求、容灾要求、运维能力)进行选择和配置,是保障 Redis 服务高可用性的关键。💪🏻