高可用(High Availability, HA)

一、高可用是什么意思?

高可用(High Availability, HA)的核心是消除单点故障(Single Point of Failure, SPOF)。即系统中任何一个组件坏了,整个系统都不会挂,用户几乎无感知。

通常用"几个9"来衡量可用性:

  • 99.9%(三九):一年约8.77小时不可用。

  • 99.99%(四九):一年约52.6分钟不可用。

  • 99.999%(五九):一年约5.26分钟不可用。

注意:100%的可用性在现实中不存在,因为计划内维护(如升级、打补丁)也需要时间。

二、核心实现方式

高可用主要通过冗余自动故障转移来实现。

1. 主备模式

  • 描述:一台主节点工作,一台或多台备用节点热待命,实时同步数据。主节点故障时,备节点自动接管。

  • 优点:实现简单,数据一致性好。

  • 缺点:存在资源浪费(备机平时不用),切换有短暂中断。

  • 典型场景:数据库(MySQL主从+自动切换)、Keepalived + VIP。

2. 主主模式

  • 描述:两台节点同时工作,互为备份,共同分担流量。任意一台故障,另一台承担全部工作。

  • 优点:资源利用率高,切换快。

  • 缺点:数据冲突风险高(如两台同时写同一行数据),实现复杂。

  • 典型场景:某些DNS系统、轻量级数据库集群(如MariaDB Galera)。

3. 集群模式

  • 描述:多台节点组成集群,前端用负载均衡器分发请求。故障节点被自动摘除,业务不受影响。

  • 优点:真正的高扩展和高可用,节点故障几乎无感知。

  • 缺点:架构复杂,需要负载均衡器和共享存储或分布式存储。

  • 典型场景:Web服务器集群(Nginx + 多个Tomcat)、Kubernetes容器集群。

4. 数据层高可用

  • 同步复制 :数据必须同时写入主库和备库才返回成功。强一致性,但性能影响大。

  • 异步复制 :主库写入后立即返回,后台同步到备库。性能好,但可能丢失少量数据。

  • 半同步复制:至少一个备库写入成功才返回。平衡了性能和数据安全。

三、需要具备哪些实现条件?

要实现真正的高可用,必须满足以下技术条件:

条件 说明 关键技术
1. 冗余无单点 所有可能故障的组件(服务器、网络、电源)都至少有两份。 双网卡绑定、双电源、多机多活、RAID磁盘阵列
2. 故障自动检测 能快速、准确判断节点是"真故障"还是"网络抖动",避免误切换。 心跳检测、健康检查(Ping/端口/接口)、Quorum仲裁机制
3. 自动切换(Failover) 检测到故障后,系统自动将VIP或流量切换到备用节点,无需人工介入。 VIP漂移(如Keepalived)、DNS切换(需短TTL)、负载均衡摘除节点
4. 数据一致性保障 切换后,新主节点的数据必须完整且最新,不能出现"脑裂"(两个主节点同时写数据)。 共享存储(SAN/NAS)、分布式一致性协议(Raft/Paxos)、 fencing(隔离故障节点)
5. 快速恢复能力 故障节点修复后能快速重新加入集群,自动同步缺失的数据。 增量数据同步、全量数据重建机制

四、一个典型的高可用架构示例

常见的LVS + Keepalived + Nginx + MySQL主从架构:

  • 接入层:用VRRP协议实现VIP在两台LVS/Keepalived之间漂移。主LVS故障,备LVS接管VIP,用户无感。

  • 应用层:多个Nginx节点组成集群,前端负载均衡器分发请求。某个Nginx宕机,流量自动切到其他节点。

  • 数据层:MySQL采用主从复制 + 自动切换工具(如MHA/Orchestrator)。主库故障,从库自动升级为新主库,应用只需修改数据源连接。

总结: 高可用就是用一堆普通机器一套自动容灾机制 ,模拟出一台永不掉线的超级机器的效果。代价是成本增加和架构复杂度提升。

高可用需要多台服务器 ,其中服务层多实例部署 ,而数据库/缓存层采用主从复制或集群,这两层通常跑在不同服务器上,避免资源冲突

五、核心原则:消除单点,而非简单克隆

高可用要求任何一个组件(服务器、进程、磁盘、网络)失效时,仍有其他冗余组件能接管工作。但这并不意味着每台服务器上都要把"所有服务+所有数据库"都部署一份。这样做反而会带来资源冲突、数据竞争、维护复杂等问题。


六、常见的合理冗余模式(不是"每台都部署所有")

1. 服务层(无状态)
  • 做法 :在两台或更多服务器上部署相同的服务实例(比如你的 Ocelot、Nginx)。

  • 特点:每台服务器只跑服务,不跑数据库。前端用负载均衡分发请求。

  • 结论 :✅ 这是"多套服务",但服务器上不部署数据库

2. 数据库层(有状态)
  • 做法 :通常是主从复制集群

    • 主库(Active)负责读写,部署在服务器A。

    • 从库(Standby/Read-only)同步数据,部署在服务器B(或更多)。

    • 主库故障时,将从库提升为新主库。

  • 特点 :并不是两台服务器都同时提供写服务(双主模式除外,但双主风险高)。从库平时可能只读,或者完全不接受流量

  • 结论 :❌ 不是"两套数据库都同时对外提供完整服务",而是一套主用,一套热备/只读

3. Redis 缓存
  • 做法

    • 哨兵模式:一主一从或一主多从,主负责写,从负责读或仅备份。故障时哨兵自动切换。

    • 集群模式:多个分片,每个分片有主从。

  • 结论 :❌ 也不是"两套完全独立的 Redis 同时读写",而是主从结构

七、为什么"主备服务器都部署全套服务+数据库"不好?

假设你有两台物理机,每台都运行:Nginx + Ocelot + MySQL + Redis。

问题 说明
端口冲突 两台机器各自运行 MySQL 占用 3306 端口没问题(不同IP),但你的应用程序要连接哪个 MySQL?如果都连本机的,数据就不一致。
数据不一致 两个 MySQL 独立运行,没有复制关系,写入 A 机的数据 B 机看不到,切换后数据丢失。
资源浪费 数据库和缓存非常消耗内存、CPU、磁盘 I/O。每台都跑全量数据库,硬件成本翻倍,且备用机平时几乎闲置。
维护复杂 升级、备份、监控都要做两份,且要处理两套数据之间的同步问题,比标准的主从复制复杂得多。

八、正确的高可用资源规划示例(架构如下)

层级 组件 采用的高可用模式
入口负载均衡 Nginx + Pacemaker 主备模式(Active-Standby)
内部网关服务 Ocelot 集群 + Consul 集群模式(多活 + 服务发现)
配置中心 Consul 集群 分布式集群模式(Raft)
数据库 MySQL(需自行配置) 通常为主备/主主或集群
缓存 Redis(需自行配置) 通常为哨兵(主备)或集群

假设你有 4 台物理机/虚拟机:

服务器 部署内容 角色
主机 A Nginx (Pacemaker 主) + Ocelot 实例1 入口主节点,网关实例
主机 B Nginx (Pacemaker 备) + Ocelot 实例2 入口备节点,网关实例
主机 C MySQL 主库 + Redis 主节点 数据主节点
主机 D MySQL 从库 + Redis 从节点 数据备节点
  • 服务层:Ocelot 在 A、B 上都运行,Nginx 通过 Consul 发现所有 Ocelot 实例,流量分发到 A 和 B。一台 Ocelot 挂了,Nginx 切到另一台。

  • 数据层:MySQL 主从复制,Redis 主从复制。C 故障时,D 接管成为新主。

  • 入口层:VIP 绑定在 A 的 Nginx,A 故障时 VIP 漂移到 B。

这样一共 4 台服务器,没有一台运行"所有组件",但实现了高可用。

相关推荐
Whitemeen太白2 小时前
查询子级分类、父级分类、叶子节点分类(MySQL / Oracle )
数据库·mysql·oracle
2401_883600252 小时前
Redis如何查询特定用户的排名_利用ZREVRANK指令获取ZSet降序名次
jvm·数据库·python
2301_777599372 小时前
如何决定是否需要创建索引_数据区分度与基数Cardinality计算
jvm·数据库·python
m0_514520572 小时前
SQL在SQL存储过程中优化子查询_缓存中间结果减少开销
jvm·数据库·python
21439652 小时前
JavaScript中剩余参数在函数签名中的定义位置与限制
jvm·数据库·python
2301_815279523 小时前
CSS定位如何实现多行文字垂直居中_通过绝对定位模拟表格
jvm·数据库·python
m0_684501983 小时前
C#怎么使用LINQ Contains包含判断 C#如何用Contains实现类似SQL IN查询的集合包含判断【语法】
jvm·数据库·python
weixin_520649873 小时前
C#进阶-特性全知识点总结
开发语言·c#
2301_764150563 小时前
c++如何读取和解析带BOM头的UTF-8与UTF-16文本流【详解】
jvm·数据库·python