--- title: 冗余设计详解 description: 本文系统讲解冗余设计核心知识,涵盖冗余类型(硬件/软件/数据/服务冗余)、RTO/RPO 指标、高可用集群(主备/主主模式)、同城灾备、异地灾备、同城多活、异地多活架构对比及故障转移机制,助力高可用架构设计与面试。 category: 高可用 icon: cluster head: - - meta - name: keywords content: 冗余设计,高可用集群,同城灾备,异地灾备,同城多活,异地多活,故障转移,RTO,RPO,容灾架构 --- ## 什么是冗余? **冗余(Redundancy)** 是保证系统和数据高可用的最常用手段,其核心思想是 **通过部署多份相同的资源,当某一份资源出现故障时,其他资源可以接管其工作,从而保证系统的持续可用**。 冗余设计可以从以下几个维度来理解: | 冗余类型 | 说明 | 典型实现 | | ------------ | ---------------------- | -------------------------------- | | **硬件冗余** | 关键硬件设备部署多份 | 双电源、双网卡、RAID 磁盘阵列 | | **软件冗余** | 应用服务部署多个实例 | 集群部署、容器化多副本 | | **数据冗余** | 数据存储多份副本 | 数据库主从复制、分布式存储多副本 | | **网络冗余** | 网络链路和设备冗余 | 多运营商接入、双活负载均衡 | | **地域冗余** | 在不同地理位置部署系统 | 同城灾备、异地多活 | 对于 **服务** 来说,冗余的思想就是相同的服务部署多份,如果正在使用的服务突然挂掉的话,系统可以很快切换到备份服务上,大大减少系统的不可用时间,提高系统的可用性。 对于 **数据** 来说,冗余的思想就是相同的数据备份多份,这样就可以很简单地提高数据的安全性。 实际上,日常生活中就有非常多的冗余思想的应用。拿我自己来说,我对于重要文件的保存方法就是冗余思想的应用。我日常所使用的重要文件都会同步一份在 GitHub 以及个人云盘上,这样就可以保证即使电脑硬盘损坏,我也可以通过 GitHub 或者个人云盘找回自己的重要文件。 ## 容灾核心指标:RTO 和 RPO 在讨论容灾架构之前,需要先理解两个核心指标: ```mermaid flowchart TB subgraph Timeline["时间线"] direction LR A["上次备份"] --> B["故障发生"] --> C["系统恢复"] end A -.->|"数据丢失窗口(RPO)"| B B -.->|"恢复时间窗口(RTO)"| C classDef core fill:#4CA497,color:#fff,rx:10,ry:10 classDef highlight fill:#E99151,color:#fff,rx:10,ry:10 class A,B,C core style Timeline fill:#F5F7FA,stroke:#E0E6ED,stroke-width:1.5px linkStyle default stroke-width:1.5px,opacity:0.8 ``` - **RPO(Recovery Point Objective,恢复点目标)**:可容忍的 **最大数据丢失量**,即从上次备份到故障发生之间的数据。RPO = 0 表示不允许丢失任何数据。 - **RTO(Recovery Time Objective,恢复时间目标)**:可容忍的 **最大恢复时间**,即从故障发生到系统恢复正常服务的时间。RTO = 0 表示服务不能中断。 | 架构方案 | RPO | RTO | 成本 | | ---------- | -------------- | ----------- | ---- | | 单机无备份 | 可能全部丢失 | 不可预估 | 低 | | 本地备份 | 取决于备份周期 | 小时级 | 低 | | 同城灾备 | 分钟级 | 分钟~小时级 | 中 | | 异地灾备 | 分钟~小时级 | 小时级 | 中高 | | 同城多活 | 秒级 | 秒级 | 高 | | 异地多活 | 秒级 | 秒级 | 很高 | ## 冗余架构方案对比 高可用集群(High Availability Cluster,简称 HA Cluster)、同城灾备、异地灾备、同城多活和异地多活是冗余思想在高可用系统设计中最典型的应用。 ```mermaid flowchart TB subgraph Grid["冗余架构方案对比"] direction LR style Grid fill:#F0F2F5,stroke:#E0E6ED,stroke-width:1.5px subgraph HACluster["高可用集群"] direction LR style HACluster fill:#F5F7FA,stroke:#E0E6ED,stroke-width:1.5px A1["主节点"] --> A2["从节点"] end subgraph LocalDR["同城灾备"] direction LR style LocalDR fill:#F5F7FA,stroke:#E0E6ED,stroke-width:1.5px B1["主机房
(处理请求)"] -.->|"同步"| B2["备机房
(不处理请求)"] end subgraph RemoteDR["异地灾备"] direction LR style RemoteDR fill:#F5F7FA,stroke:#E0E6ED,stroke-width:1.5px C1["主机房
北京"] -.->|"异步同步"| C2["备机房
上海"] end subgraph LocalActive["同城多活"] direction LR style LocalActive fill:#F5F7FA,stroke:#E0E6ED,stroke-width:1.5px D1["机房A
(处理请求)"] <-->|"双向同步"| D2["机房B
(处理请求)"] end subgraph RemoteActive["异地多活"] direction LR style RemoteActive fill:#F5F7FA,stroke:#E0E6ED,stroke-width:1.5px E1["北京机房
(处理请求)"] <-->|"双向同步"| E2["上海机房
(处理请求)"] end end classDef core fill:#4CA497,color:#fff,rx:10,ry:10 classDef external fill:#005D7B,color:#fff,rx:10,ry:10 class A1,B1,C1,D1,D2,E1,E2 core class A2,B2,C2 external linkStyle default stroke-width:1.5px,opacity:0.8 ``` ### 高可用集群 **高可用集群** 是指同一份服务部署两份或者多份,当正在使用的服务突然挂掉的话,可以切换到另外一台服务,从而保证服务的高可用。 高可用集群有两种常见模式: | 模式 | 说明 | 优点 | 缺点 | | ------------------------------ | -------------------------- | ------------------------ | ------------------------------ | | **主备模式(Active-Standby)** | 主节点提供服务,备节点待命 | 实现简单,数据一致性好 | 资源利用率低,备节点闲置 | | **主主模式(Active-Active)** | 多个节点同时提供服务 | 资源利用率高,无单点故障 | 数据同步复杂,可能有一致性问题 | 高可用集群单纯是服务的冗余,**并没有强调地域**。同城灾备、异地灾备、同城多活和异地多活实现了地域上的冗余。 ### 同城灾备 **同城灾备** 是指一整个集群可以部署在同一个机房,而同城灾备中相同服务部署在 **同一个城市的不同机房** 中。并且,**备用服务不处理请求**。这样可以避免机房出现意外情况比如停电、火灾。 - **适用场景**:对 RTO 要求较高(分钟级),成本有限的企业。 - **典型配置**:两个机房距离 30~100 公里,通过专线连接。 ### 异地灾备 **异地灾备** 类似于同城灾备,不同的是,相同服务部署在 **异地(通常距离较远,甚至是在不同的城市或者国家)的不同机房中**。 - **适用场景**:需要防范区域性灾难(地震、洪水)的核心业务系统。 - **挑战**:网络延迟较大,数据同步通常采用异步方式,可能存在数据丢失。 ### 同城多活 **同城多活** 类似于同城灾备,但 **备用服务可以处理请求**,这样可以充分利用系统资源,提高系统的并发。 - **适用场景**:对性能和可用性都有较高要求的系统。 - **技术要点**:需要解决数据同步、流量调度、会话管理等问题。 ### 异地多活 **异地多活** 将服务部署在 **异地的不同机房** 中,并且,它们可以 **同时对外提供服务**。 和传统的灾备设计相比,同城多活和异地多活最明显的改变在于 **"多活"**,即所有站点都是同时在对外提供服务的。异地多活是为了应对突发状况比如火灾、地震等自然或者人为灾害。 同城和异地的主要区别在于 **机房之间的距离**。异地通常距离较远,甚至是在不同的城市或者国家。 ## 故障转移机制 光做好冗余还不够,必须要配合上 **故障转移(Failover)** 才可以!所谓故障转移,简单来说就是 **实现不可用服务快速且自动地切换到可用服务,整个过程不需要人为干涉**。 故障转移通常包含以下几个步骤: 1. **故障检测**:通过心跳检测、健康检查等机制发现故障节点。 2. **故障确认**:避免误判,通常需要多次检测确认。 3. **故障切换**:将流量切换到备用节点。 4. **故障通知**:发送告警通知运维人员。 5. **故障恢复**:故障节点恢复后重新加入集群。 ### Redis 哨兵模式示例 哨兵模式的 Redis 集群中,如果 Sentinel(哨兵)检测到 master 节点出现故障的话,它就会帮助我们实现故障转移,自动将某一台 slave 升级为 master,确保整个 Redis 系统的可用性。整个过程完全自动,不需要人工介入。 ### Nginx + Keepalived 示例 Nginx 可以结合 Keepalived 来实现高可用。如果 Nginx 主服务器宕机的话,Keepalived 可以自动进行故障转移,备用 Nginx 主服务器升级为主服务。并且,这个切换对外是透明的,因为使用的 **虚拟 IP(VIP)**,虚拟 IP 不会改变。 ## 异地多活的挑战 异地多活架构实施起来非常难,需要考虑的因素非常多: | 挑战 | 说明 | 解决思路 | | -------------- | ------------------------------ | ------------------------ | | **数据一致性** | 多个机房数据如何保持一致 | 最终一致性、冲突解决机制 | | **网络延迟** | 异地机房之间网络延迟较大 | 就近接入、数据分区 | | **流量调度** | 如何将用户请求分配到合适的机房 | DNS 智能解析、GSLB | | **会话管理** | 用户会话如何在多机房之间共享 | 分布式会话、无状态设计 | | **成本** | 多机房建设和运维成本高 | 按业务重要性分级部署 | 如果你想要深入学习异地多活相关的知识,推荐以下资料: - [搞懂异地多活,看这篇就够了 - 水滴与银弹 - 2021](https://mp.weixin.qq.com/s/T6mMDdtTfBuIiEowCpqu6Q) - [四步构建异地多活](https://mp.weixin.qq.com/s/hMD-IS__4JE5_nQhYPYSTg) - [《从零开始学架构》— 28 | 业务高可用的保障:异地多活架构](http://gk.link/a/10pKZ)