什么是高可用?高可用介绍:

article/2025/10/12 18:13:01

前言:
高可用(High availability,即 HA)的主要目的是为了保障「业务的连续性」,即在用户眼里,业务永远是正常(或者说基本正常)对外提供服务的。高可用主要是针对架构而言,那么要做好高可用,就要首先设计好架构,第一步我们一般会采用分层的思想将一个庞大的 IT 系统拆分成为应用层,中间件,数据存储层等独立的层,每一层再拆分成为更细粒度的组件,第二步就是让每个组件对外提供服务,毕竟每个组件都不是孤立存在的,都需要互相协作,对外提供服务才有意义。

要保证架构的高可用,就要保证架构中所有组件以及其对外暴露服务都要做高可用设计,任何一个组件或其服务没做高可用,都意味着系统存在风险。

那么这么多组件该怎么做高可用设计呢,其实任何组件要做高可用,都离不开「冗余」和「自动故障转移」,众所周知单点是高可用的大敌,所以组件一般是以集群(至少两台机器)的形式存在的,这样只要某台机器出现问题,集群中的其他机器就可以随时顶替,这就是「冗余」。简单计算一下,假设一台机器的可用性为 90%,则两台机器组成的集群可用性为 1-0.1*0.1 = 99%,所以显然冗余的机器越多,可用性越高。

但光有冗余还不够,如果机器出现问题,需要人工切换的话也是费时费力,而且容易出错,所以我们还需要借助第三方工具(即仲裁者)的力量来实现「自动」的故障转移,以达到实现近实时的故障转移的目的,近实时的故障转移才是高可用的主要意义

怎样的系统可以称之为高可用呢,业界一般用几个九来衡量系统的可用性,如下在这里插入图片描述
一般实现两个 9 很简单,毕竟每天宕机 14 分钟已经严重影响业务了,这样的公司迟早歇菜,大厂一般要求 4 个 9,其他要求严苛的业务要达到五个九以上,比如如果因为一个电脑的故障导致所有列车停驶,那么就会有数以万计的人正常生活受到阻碍,这种情况就要求五个九以上

接下来我们就来一起看看架构中的各个组件如何借助「冗余」和「自动故障转移」来实现高可用。

互联网架构剖析
目前多数互联网都会采用微服务架构,常见架构如下:
在这里插入图片描述
可以看到架构主要分以下几层

1.接入层:主要由 F5 硬件或 LVS 软件来承载所有的流量入口

2.反向代理层:Nginx,主要负责根据 url 来分发流量,限流等

3.网关:主要负责流控,风控,协议转换等

4.站点层:主要负责调用会员,促销等基本服务来装配 json 等数据并返回给客户端

5.基础 service:其实与站点层都属于微服务,是平级关系,只不过基础 service 属于基础设施,能被上层的各个业务层 server 调用而已

6.存储层:也就是 DB,如 MySQL,Oracle 等,一般由基础 service 调用返回给站点层

7.中间件:ZK,ES,Redis,MQ 等,主要起到加速访问数据等功能,在下文中我们会简单介绍下各个组件的作用

如前所述,要实现整体架构的高可用,必须要实现每一层组件的高可用,接下来我们就来分别看一下每一层的组件都是如何实现高可用的

接入层&反向代理层
这两层的高可用都和 keepalived 有关,所以我们结合起来一起看在这里插入图片描述
对外,两个 LVS 以主备的形式对外提供服务,注意只有 master 在工作(即此时的 VIP 在 master 上生效),另外一个 backup 在 master 宕机之后会接管 master 的工作,那么 backup 怎么知道 master 是否正常呢,答案是通过 keepalived,在主备机器上都装上 keepalived 软件,启动后就会通过心跳检测彼此的健康状况,一旦 master 宕机,keepalived 会检测到,从而 backup 自动转成 master 对外提供服务,此时 VIP 地址(即图中的 115.204.94.139)即在 backup 上生效,也就是我们常说的「IP漂移」,通过这样的方式即解决了 LVS 的高可用。

keepalived 的心跳检测主要通过发送 ICMP 报文,或者利用 TCP 的端口连接和扫描检测来检测的,同样的,它也可以用来检测 Nginx 暴露的端口,这样的话如果某些 Nginx 不正常 Keepalived 也能检测到并将其从 LVS 能转发的服务列表中剔出。Nginx也能通过端口检测服务健康状态

借用 keepalived 这个第三方工具,同时实现了 LVS 和 Nginx 的高可用,同时在出现故障时也可以将宕机情况发送到对应开发人员的邮箱以让他们及时收到通知处理,确实很方便,Keepalived 应用广泛,下文我们会看到它也可以用在 MySQL 上来实现 MySQL 的高可用。

微服务
接下来我们再来看一下「网关」,「站点层」,「基础服务层」,这三者一般就是我们所说的微服务架构组件,当然这些微服务组件还需要通过一些 RPC 框架如 Dubbo 来支撑才能通信,所以微服务要实现高可用,就意味着 dubbo 这些 RPC 框架也要提供支撑微服务高可用的能力,我们就以 dubbo 为例来看下它是如何实现高可用的

我们先来简单地看下 dubbo 的基本架构
在这里插入图片描述
思路也很简单,首先是 Provider(服务提供者)向 Registry(注册中心,如 ZK 或 Nacos 等)注册服务,然后 Consumer(服务消费者)向注册中心订阅和拉取 Provider 服务列表,获取服务列表后,Consumer 就可以根据其负载均衡策略选择其中一个 Provider 来向其发出请求,当其中某个 Provider 不可用(下线或者因为 GC 阻塞等)时,会被注册中心及时监听(通过心跳机制)到,也会及时推送给 Consumer,这样 Consumer 就能将其从可用的 Provider 列表中剔除,也就实现了故障的自动转移,不难看出,注册中心就起到了类似 keepalived 的作用
中间件
我们再来看下这些中间件如 ZK,Redis 等是如何实现高可用的呢

ZK
上一节微服务中我们提到了注册中心,那我们就以 ZK(ZooKeeper)为例来看看它的高可用是如何实现的,先来看下它的整体架构图如下
在这里插入图片描述
Zookeeper 中的主要角色如下

Leader: 即领导者,在集群中只有一个 Leader,主要承担了以下的功能

1.事务请求的唯一调度和处理者,保证集群事务处理的顺序性,所有 Follower 的写请求都会转给 Leader 执行,用来保证事务的一致性

2.集群内部各服务器的调度者:处理好事务请求后,会将数据广播同步到各个 Follower,统计 Follower 写入成功的数量,超过半数 Follower 写入成功,Leader 就会认为写请求提交成功,通知所有的 Follower commit 这个写操作,保证事后哪怕是集群崩溃恢复或者重启,这个写操作也不会丢失。

Follower:

1.处理客户端非事务请求、转发事务请求给 leader 服务器

2.参与事物请求 Proposal 的投票(需要半数以上服务器通过才能通知 leader commit 数据; Leader 发起的提案,要求 Follower 投票)

3.参与 Leader 选举的投票

画外音:Zookeeper 3.0 之后新增了一种 Observer 的角色,不过与此处讨论的 ZK 高可用关系不是很大,为了简化问题,所以省略

可以看到由于只有一个 Leader,很显然,此 Leader 存在单点隐患,那么 ZK 是怎么解决此问题的呢,首先 Follower 与 Leader 会用心跳机制保持连接,如果 Leader 出现问题了(宕机或者因为 FullGC 等原因无法响应),Follower 就无法感知到 Leader 的心跳,就会认为 Leader 出问题了,于是它们就会发起投票选举,最终在多个 Follower 中选出一个 Leader 来(这里主要用到了 Zookeeper Atomic Broadcast,即 ZAB 协议,它是为 ZK 专门设计的一种支持崩溃恢复的一致性协议),选举的细节不是本文重点,就不在此详述了。

除了 ZAB 协议,业界上常用的还有 Paxos,Raft 等协议算法,也可以用在 Leader 选举上,也就是是在分布式架构中,这些协议算法承担了“第三者”也就是仲裁者的作用,以承担故障的自动转移

Redis
Redis 的高可用需要根据它的部署模式来看看,主要分为「主从模式」和「Cluster 分片模式」两种

主从模式
先来看一下主从模式,架构如下
在这里插入图片描述
主从模式即一主多从(一个或者多个从节点),其中主节点主要负责读和写,然后会将数据同步到多个从节点上,Client 也可以对多个从节点发起读请求,这样可以减轻主节点的压力,但和 ZK 一样,由于只有一个主节点,存在单点隐患,所以必须引入第三方仲裁者的机制来判定主节点是否宕机以及在判定主节点宕机后快速选出某个从节点来充当主节点的角色,这个第三方仲裁者在 Redis 中我们一般称其为「哨兵」(sentinel),当然哨兵进程本身也有可能挂掉,所以为了安全起见,需要部署多个哨兵(即哨兵集群)
在这里插入图片描述
这些哨兵通过 gossip(流言) 协议来接收关于主服务器是否下线的信息,并在判定主节点宕机后使用 Raft 协议来选举出新的主节点

Cluster 分片集群
主从模式看似完美,但存在以下几个问题

1.主节点写的压力难以降低:因为只有一个主节点能接收写请求,如果在高并发的情况下,写请求如果很高的话可能会把主节点的网卡打满,造成主节点对外无法服务

2.主节点的存储能力受到单机存储容量的限制:因为不管是主节点还是从节点,存储的都是全量缓存数据,那么随着业务量的增长,缓存数据很可能直线上升,直到达到存储瓶颈

3.同步风暴:因为数据都是从 master 同步到 slave 的,如果有多个从节点的话,master 节点的压力会很大

为了解决主从模式的以上问题,分片集群应运而生,所谓分片集群即将数据分片,每一个分片数据由相应的主节点负责读写,这样的话就有多个主节点来分担写的压力,并且每个节点只存储部分数据,也就解决了单机存储瓶颈的问题,但需要注意的是每个主节点都存在单点问题,所以需要针对每个主节点做高可用,整体架构如下在这里插入图片描述
原理也很简单,在 Proxy 收到 client 执行的 redis 的读写命令后,首先会对 key 进行计算得出一个值,如果这个值落在相应 master 负责的数值范围(一般将每个数字称为槽,Redis 一共有 16384 个槽)之内,那就把这条 redis 命令发给对应的 master 去执行,可以看到每个 master 节点只负责处理一部分的 redis 数据,同时为了避免每个 master 的单点问题,也为其配备了多个从节点以组成集群,当主节点宕机时,集群会通过 Raft 算法来从从节点中选举出一个主节点

ES
再来看一下 ES 是如何实现高可用的,在 ES 中,数据是以分片(Shard)的形式存在的,如下图所示,一个节点中索引数据共分为三个分片存储
在这里插入图片描述
但只有一个节点的话,显然存在和 Redis 的主从架构一样的单点问题,这个节点挂了,ES 也就挂了,所以显然需要创建多个节点在这里插入图片描述
一旦创建了多个节点,分片(图中 P 为主分片,R 为副本分片)的优势就体现出来了,可以将分片数据分布式存储到其它节点上,极大提升了数据的水平扩展能力,同时每个节点都能承担读写请求,采用负载均衡的形式避免了单点的读写压力

ES 的写机制与 Redis 和 MySQL 的主从架构有些差别(后两者的写都是直接向 master 节点发起写请求,而 ES 则不是),所以这里稍微解释一下 ES 的工作原理
首先说下节点的工作机制,节点(Node)分为主节点(Master Node)和从结点(Slave Node),主节点的主要职责是负责集群层面的相关操作,管理集群变更,如创建或删除索引,跟踪哪些节点是集群的一部分,并决定哪些分片分配给相关的节点,主节点也只有一个,一般通过类 Bully 算法来选举出来,如果主节点不可用了,则其他从节点也可以通过此算法来选举以实现集群的高可用,任何节点都可以接收读写请求以达到负载均衡的目的

再说一下分片的工作原理,分片分为主分片(Primary Shard,即图中 P0,P1,P2)和副本分片(Replica Shard,即图中 R0,R1,R2),主分片负责数据的写操作,所以虽然任何节点可以接收读写请求,但如果此节点接收的是写请求并且没有写数据所在的主分片话,此节点会将写请求调度到主分片所在的节点上,写入主分片后,主分片再把数据复制到其他节点的副本分片上,以有两个副本的集群为例,写操作如下
在这里插入图片描述
MQ
ES 利用数据分片来提升高可用和水平扩展能力的思想也应用在其他组件的架构设计上,我们以 MQ 中的 Kafka 为例再来看下数据分片的应用
在这里插入图片描述
如上是 Kafka 集群,可以看到每个 Topic 的 Partition 都分布式存储在其它消息服务器上,这样一旦某个 Partition 不可用,可以从 follower 中选举出 leader 继续服务,不过与 ES 中的数据分片不同的是,follower Partition 属于冷备,也就是说在正常情况下不会对外服务,只有在 leader 挂掉之后从 follower 中选举出 leader 后它才能对外提供服务

存储层
接下来我们再来看一下最后一层,存储层(DB),这里我们以 MySQL 为例来简单地讨论一下其高可用设计,其实大家如果看完了以上的高可用设计,会发现 MySQL 的高可用也不过如此,思想都是类似的,与 Redis 类似,它也分主从和分片(即我们常说的分库分表)两种架构

主从的话与 LVS 类似,一般使用 keepalived 的形式来实现高可用,如下所示
在这里插入图片描述
如果 master 宕机了,Keepalived 也会及时发现,于是从库会升级主库,并且 VIP 也会“漂移”到原从库上生效,所以说大家在工程配置的 MySQL 地址一般是 VIP 以保证高可用

数据量大了之后就要分库分表了,于是就有了多主,就像 Redis 的分片集群一样,需要针对每个主配备多个从,如下
在这里插入图片描述
之前有读者问分库分表之后为啥还要做主从,现在我想大家应该都明白了,不是为了解决读写性能问题,主要是为了实现高可用

总结
看完了架构层面的高可用设计,相信大家对高可用的核心思想「冗余」和「自动故障转移」会有更深刻的体会,观察以上架构中的组件你会发现冗余的主要原因是因为只有一主,为什么不能有多主呢,也不是不可以,但这样在分布式系统下要保证数据的一致性是非常困难的,尤其是节点多了的话,数据之间的同步更是一大难题,所以多数组件采用一主的形式,然后再在主和多从之间同步,多数组件之所以选择一主本质上是技术上的 tradeoff

那么做好每个组件的高可用之后是否整个架构就真的可用了呢,非也,这只能说迈出了第一步,在生产上还有很多突发情况会让我们的系统面临挑战,比如

1.瞬时流量问题:比如我们可能会面临秒杀带来的瞬时流量激增导致系统的承载能力被压垮,这种情况可能影响日常交易等核心链路,所以需要做到系统之间的隔离,如单独为秒杀部署一套独立的集群

2.安全问题:比如 DDOS 攻击,爬虫频繁请求甚至删库跑路等导致系统拒绝服务

3.代码问题:比如代码 bug 引起内存泄露导致 FullGC 导致系统无法响应等

4.部署问题:在发布过程中如果贸然中止当前正在运行的服务也是不行的,需要做到优雅停机,平滑发布

5.第三方问题:比如我们之前的服务依赖第三方系统,第三方可能出问题导致影响我们的核心业务

6.不可抗力:如机房断电,所以需要做好容灾,异地多活,之前我司业务就由于机房故障导致服务四小时不可用,损失惨重

所以除了做好架构的高可用之外,我们还需要在做好系统隔离,限流,熔断,风控,降级,对关键操作限制操作人权限等措施以保证系统的可用。

这里特别提一下降级,这是为了保证系统可用性采取的常用的措施,简单举几个例子

1.我们之前对接过一个第三方资金方由于自身原因借款功能出了问题导致无法借款,这种情况为了避免引起用户恐慌,于是我们在用户申请第三方借款的时候返回了一个类似「为了提升你的额度,资金方正在系统升级」这样的文案,避免了客诉

2.在流媒体领域,当用户观看直播出现严重卡顿时,很多企业的第一选择不是查 log 排查问题,而是为用户自动降码率。因为比起画质降低,卡得看不了显然会让用户更痛苦

3.双十一零点高峰期,我们把用户的注册登录等非核心功能给停掉了,以保证下单等核心流程的顺利

另外我们最好能做到事前防御,在系统出问题前把它扼杀在摇篮里,所以我们需要做单元测试,做全链路压测等来发现问题,还需要针对 CPU,线程数等做好监控,当其达到我们设定的域值时就触发告警以让我们及时发现修复问题(我司之前就碰到过一个类似的生产事故复盘大家可以看一下),此外在做好单元测试的前提下,依然有可能因为代码的潜在 bug 引起线上问题,所以我们需要在关键时间(比如双十一期间)封网(也就是不让发布代码)

此外我们还需要在出事后能快速定位问题,快速回滚,这就需要记录每一次的发布时间,发布人等,这里的发布不仅包括工程的发布,还包括配置中心等的发布
在这里插入图片描述

画外音:上图是我司的发布记录,可以看到有代码变更,回滚等,这样如果发现有问题的话可以一键回滚

最后我们以一张图来总结一下高可用的常见手段
在这里插入图片描述


http://chatgpt.dhexx.cn/article/Zk0ECWwH.shtml

相关文章

HTML Responsive Web Page

注&#xff1a;参考网站 https://www.w3schools.com HTML Responsive Web Page index.html <!DOCTYPE html> <html><head><link rel"stylesheet" href"style.css"><title>Responsive web page</title><meta lan…

响应式布局【Responsive】 与 自适应布局 【adaptive】、单页面【SPA】 和多页面【MPA】

1、响应式布局 是一个网址能兼容多个terminate【终端】&#xff0c;而不是为每个终端做一个特定的版本 优点&#xff1a; 用户体验好节约开发时间、节省设计seo友好可以适用所有设备屏幕 缺点 设计与风格有局限性《自由度太低&#xff0c;局部性较大》灵活性有所欠缺 基于不…

Bootstrap:Responsive Design with Bootstrap(一)

1.Use Responsive Design with Bootstrap Fluid Containers 现在让我们回到我们的Cat Photo应用。这次&#xff0c;我们将用流行的响应式框架Bootstrap来美化它。 Bootstrap将会根据你的屏幕的大小来调整HTML元素的大小 —— 强调 响应式设计的概念。 通过响应式设计&#x…

responsive tables

以上内容原本是整理为ppt格式的&#xff0c;贴过来格式有点乱&#xff0c;请见谅。 其他responsive tables参考&#xff1a; http://gergeo.se/RWD-Table-Patterns/ 3种类型的代码参考 unseen column&#xff1a; http://runjs.cn/code/zrhodpx5 flip scroll&#xff1a; ht…

CSS之responsive image gallery

responsive image gallery 这次实例主要是练习如何讲不同的图片设置为一个栏目&#xff0c;并且能够根据屏幕的大小进行自适应的变换。需要注意的是&#xff0c;本次实例中运用到的重要的关键的内容是&#xff1a;float-left&#xff1b;box-sizing; media screen and (max-wi…

html5 响应式表格插件,响应式表格jQuery插件 – Responsive tables

响应式表格jQuery插件 – Responsive tables 4月 24, 2014 评论 (1) Sponsor 这个Responsive tables jQuery插件依赖于Bootstrap 3使用&#xff0c;比BS自带的自适应多了一些好用的功能&#xff0c;比如筛选显示&#xff0c;Focus选定、Table头滑动固定等&#xff0c;下来看看介…

SAP Fiori 设计准则里的 Responsive 表格概述

Responsive Table 是 SAP Fiori 中的默认表控件。 它包含一组 Line item 并且完全响应(fully responsive)。 根据具体情况&#xff0c;用户还可以从行项目导航到更多详细信息页面。 一个行项目包含多个数据点(data point)&#xff0c;这些数据点被分类到列中。 数据点是指一个…

Responsive Web测试

什么是Responsive Web设计 Ethan Marcotte曾于2010年5月25日在A List Apart发表了文章《Responsive Web Design》&#xff0c;首次提出了RWD(Responsive Web Design)的概念。其理念是&#xff0c;Web页面的设计能够自适应多种设备、平台和浏览器&#xff0c;同时减少缩放、平移…

CSS之Responsive设计的关键三步

下面我们就通过这篇教程&#xff0c;帮助大家从三个步骤来了解和学习“Responsive”设计 第一步&#xff1a;Meta标签 大家都知道&#xff0c;现在智能手机上浏览web页面会让页面适应屏幕的大小&#xff0c;显示在屏幕上。不过我们可以通过“meta”标签对他进行重置&#xff…

CSS之Responsive网页设计的三个特性

Responsive网页设计无疑是网页设计中的一个热门话题。某种程度上&#xff0c;他将是一个最受欢迎的网页设计概念&#xff0c;因为随着网站用户日渐多样化的访问方法&#xff0c;比如说“iPad”、“iPhone”、“Android移动设备”、“平板电脑”、“台式机”以及“ 笔记本”等不…

下载Django中文官方文档

点击?地址&#xff0c;2.2是版本号&#xff0c;后续更新需自行更改对应的版本 https://docs.djangoproject.com/zh-hans/2.2/ 点击下载 HTML&#xff0c;即可下载全中文官方文档 有部分没有中文翻译的页面&#xff0c;请自行安装谷歌翻译插件

Django 文档 | Django

项目介绍 一款 Python 语言基于Django、Layui、MySQL等框架精心打造的一款模块化、高性能、企业级的敏捷开发框架&#xff0c;本着简化开发、提升开发效率的初衷触发&#xff0c;框架自研了一套个性化的组件&#xff0c;实现了可插拔的组件式开发方式&#xff1a;单图上传、多…

Django文档4.0(通俗易懂)

欢迎访问个人博客http://www.jkraise.top 初识 django project 01. 进入虚拟环境 创建Django 工程 使用django-admin.py 来创建 xxx 项目 django-admin startproject xxxx 创建完成后 我们查看 项目结构 目录说明&#xff1a; test——djgo_001: 项目容器 manage.py: 一…

Django技术文档

安装Django 安装python环境并添加到系统环境中 注意&#xff1a;安装的时候尽量避免路径中含有中文 virtualenv虚拟环境的使用 安装virtualenv pip install virtualenv创建virtualenv虚拟环境 CMD创建虚拟环境 cmd进入自己创建的虚拟环境文件夹输入virtualenv 虚拟环境名…

django-rest-framework文档导读

django-rest-framework文档导读 技巧反序列化校验数据保存数据ModelSerializer简化代码 APIViewrequest/responseGenericAPIViewMixinListAPIViewCreateAPIViewRetrieveAPIViewDestroyAPIViewUpdateAPIViewListCreateAPIViewRetrieveUpdateAPIViewRetrieveDestroyAPIViewRetrie…

Django Rest Framework中文文档:Serializer relations

文章目录 一&#xff0c;django模型间的关系二&#xff0c;检查序列化器实例详情三&#xff0c;序列化关系字段&#xff08;一&#xff09;StringRelatedField&#xff08;二&#xff09;PrimaryKeyRelatedField&#xff08;三&#xff09;HyperlinkedRelatedField&#xff08;…

Django官方文档

一、文档地址 https://docs.djangoproject.com/zh-hans/3.2/ 1.1 编写你的第一个 Django 应用&#xff0c;第 1 部分 1.1.1 创建项目 使用django的系统工具django-admin执行指令&#xff0c;即可创建 django-admin startproject mysite 目录结构显示如下 mysite/manage.…

WPF:WPF原生布局说明

前言 WPF在国内讨论度很小&#xff0c;我在这里记录一下WPF简单的原生控件是如何使用的&#xff0c;顺便回忆一下WPF的基础知识&#xff0c;有些忘记的比较厉害了 WPF简介 WPF是微软推出的桌面UI软件&#xff0c;是我觉得最早实现MVVM&#xff08;数据驱动事务&#xff09;&…

WPF界面美化(整体作用到控件),一步步教你使用FirstFloor.ModernUI

开发工具&#xff1a;VS2015 1、获取相关DLL(通过NuGet或者GitHub上下载的源码中获得)&#xff0c;并在项目中添加引用 FirstFloor.ModernUI.dll Microsoft.Windows.Shell.dll UIShell.OSGi(这个是我运行程序时报的错误"未能加载文件或程序集"&#xff0c;然后在…

WPF 极简风格登录界面

UI使用MaterialDesign&#xff0c;先看界面 一、界面 极简登录界面 二、下载MaterialDesign包 我使用的是VS2019&#xff0c;选择要引入MaterialDesign包的项目&#xff0c;鼠标右击选择NuGet程勋包 在浏览页签中输入MaterialDesign&#xff0c;下载MaterialDesignColors和Ma…