架构师必知必会系列:高可用性与容错设计

发布于:2023-09-28 ⋅ 阅读:(89) ⋅ 点赞:(0)

作者:禅与计算机程序设计艺术

1.简介

互联网公司面临着极大的业务变革、技术创新、创业创新的压力,业务规模越来越大,同时用户需求也在不断增长。面对这一复杂的业务场景,如何设计出健壮、高可靠的系统架构成为一个难点课题。而云计算、微服务架构等新兴的架构模式,使得系统架构设计更加复杂。如果不能保证系统的高可用性及容错能力,将可能导致严重后果。因此,架构师应当具备丰富的高可用性设计知识,掌握其基础概念、核心算法原理及操作步骤,能够快速理解并实践运用这些知识解决实际问题。 本系列教程主要基于云计算、微服务架构的应用背景,从高可用性和容错设计的基础原理,到最佳实践方法,逐步带领读者掌握分布式系统中的高可用性与容错设计,提升个人和团队的整体架构设计水平。

2.背景介绍

什么是高可用性?

高可用性(High Availability)是指一个系统在任何给定的时间段内都可以正常运行,并且经受住各种故障的影响而仍然保持正常工作状态。通俗地说,高可用性就是保证一个系统持续提供服务能力,即便在出现硬件故障或软件故障时仍然可以保障正常运行。

目前,云计算、微服务架构、容器化、大数据时代的到来,都带来了极大的技术变革。面对巨大的计算和存储负载,以及复杂的网络和存储环境,如何设计一个健壮、高可靠的系统架构就显得尤为重要。而高可用性设计正是其中不可忽视的一环。

为什么需要高可用性?

当今社会生活被数字化、网络化、智能化的趋势所驱动,用户每天产生的数据量已远超以往的想象。这种数据量的增加,使得单个服务器无法承担日益增长的请求。为了能够同时满足大量的访问请求,需要部署多台服务器构成集群,以提高服务质量。因此,构建分布式系统架构是高可用性系统的重要组成部分。但是,如何通过有效的架构设计,降低整个系统的单点故障率,是实现高可用性不可或缺的要素。

分布式系统架构及组件

典型的分布式系统架构包括以下几个层次:

  1. 数据层:主要由数据存储、处理、分析等构成。
  2. 服务层:负责处理各个模块之间的交互,如消息队列、缓存、数据库等。
  3. 任务调度层:用于控制各个任务的执行顺序和资源分配。
  4. 通信层:用于数据的传输和接收。

一般情况下,分布式系统由若干节点组成,每个节点具有唯一标识符,通过网络进行通信。为了保证系统的高可用性,每个节点都应当具有冗余配置,即它具有相应的备份机制,能够在发生故障时,依据设定的策略快速恢复正常状态。因此,分布式系统的各个层次也需要设计成高度冗余的架构,防止单点故障引起的灾难性后果。

为了实现高可用性,通常还需考虑如下几个方面:

  1. 服务发现:不同节点上的服务可能会动态地启动和关闭,为了让客户端无缝感知到服务的变化,需要有一个服务注册中心,它记录了所有服务的地址信息,并实时通知客户端服务的位置。
  2. 熔断机制:当某个服务节点发生故障时,可能会拖累整个系统的性能。因此,需要引入熔断机制,在检测到节点故障时,限制流量进入该节点,避免造成系统瘫痪。
  3. 限流降级:系统会随着时间推移而持续产生新的请求。为了保证系统的整体性能,需要引入流控、降级等限流降级手段,以避免过多的请求涌入系统,引起性能下降。
  4. 流量切换:由于服务器的数量和配置不断变化,因此需要有一种自动化的机制,根据当前负载情况,调整流量的分发策略,确保服务的高可用性。
  5. 数据同步:为了保证数据一致性,需要确保各个节点上的数据都是同步的。因此,需要设计成数据复制或异步处理机制,确保数据最终一致。

因此,高可用性是一个综合性的设计要求,它涉及到系统的软硬件环境、服务结构和部署方式、服务发现机制、熔断机制、限流降级机制、流量切换机制、数据同步机制等多个层面,并通过一系列算法和操作流程完成。

3.基本概念术语说明

什么是服务治理?

服务治理,即服务管理的过程。服务管理是指组织跨部门协作,制定目标、计划、执行和监控服务于组织的生命周期的过程。服务治理的目标是通过一系列管理活动,增强服务的可靠性、可用性和性能,提升服务的投资回报率和竞争优势,并确保企业能顺利运营。

服务治理包括服务发现、服务路由、服务容量管理、服务流量管控、服务监控、服务降级、服务自愈等多个管理功能。服务治理的第一步,是识别和分类现有的服务,确定它们的功能和定位,然后制定相应的规范、流程和工具,以确保服务的可靠性和可用性。

什么是软硬件隔离?

软硬件隔离,即把计算、存储和网络资源按功能分别划分到不同的设备上,使它们之间彼此独立,互相不干扰。软硬件隔离的主要目的是提高资源利用率,减少资源冲突。硬件的软硬件隔离通常采用服务器托管、虚拟机、容器等技术。

什么是服务的容量规划?

服务的容量规划,是指决定系统的容量,例如每秒处理多少事务、每秒查询多少数据、每天能处理多少数据等。一般来说,服务的容量规划不是一蹴而就的,而是随着业务的变化而不断演进的。服务的容量规划应该以产品、运营、开发和测试等多个角度进行考虑。

容量规划的方法有固定的指标、动态指标和手动调节三种。固定指标是指按照某些性能标准和服务级别协议进行定量评估,例如,按照TPS、QPS、响应时间、错误率、饱和度等进行测算。动态指标则是根据系统的运行状况、负载变化以及用户的反馈等,进行预测和自动调节。

固定指标的好处是比较稳定,适用于系统容量的统一评价;动态指标的好处是能够更快地反映系统的实际运行情况,适用于快速响应的弹性扩容。

什么是服务的可靠性设计?

可靠性设计,是指对系统的可靠性进行全面的考虑。可靠性设计的目的是确保服务的可靠性,防止服务的故障或中断,以最小的风险和损失为客户提供最大的价值。可靠性设计可以分为两类:自我修复和恢复能力设计。

自我修复能力设计包括服务自愈和自动恢复能力,是在服务异常出现时,自动恢复服务,确保服务在指定的时间范围内可恢复正常运行。包括自动故障转移、自动主备切换、延迟超时、冗余备份、隔离设计等。自动恢复能力是指通过自动化工具或策略,将失败的服务快速恢复,提升系统的整体可用性。

恢复能力的另一类设计,是精细化的监控与告警系统,用来快速发现系统故障和异常,并进行自动处理。包括健康检查、监控、容量管理、自动扩缩容、弹性伸缩等。

因此,可靠性设计的目的是为了建立起可靠、高效的服务,确保服务在短时间内不可用或者部分可用,但不会对客户造成较大的影响。

什么是服务的可达性设计?

可达性设计,是指对服务的可达性进行设计。可达性设计的目的,是确保服务能够被正确调用和连接,以方便客户使用。对于分布式系统来说,可达性设计至关重要,因为它直接影响到客户的体验。

可达性设计的核心是服务注册与发现机制。服务注册与发现机制,是指当分布式系统中某个服务出现故障或停止时,通过一个中心化的服务注册表或目录,能准确快速的找到该服务并重新启动。服务注册与发现机制通常包括服务名称、主机地址、端口号、元数据等信息,包括自动注册、服务心跳检测、服务健康检查等。

除了服务注册与发现机制外,还有其他几种方式来提升服务的可达性,包括DNS域名解析、负载均衡、边缘路由、灰度发布等。

4.核心算法原理和具体操作步骤以及数学公式讲解

CAP原理

CAP原理(CAP theorem),又称 Brewer's theorem,是由加州大学柏克莱分校计算机科学系 professor E.E. Congress 提出的,是一个重要的分布式理论。他认为,对于一个分布式系统来说,不可能同时满足一致性(Consistency)、可用性(Availability)和分区容忍性(Partition tolerance)。简单地说,一致性表示多个副本的数据完全相同;可用性表示每次请求总是返回一个非错误的响应——但不保证它是最新的信息;而分区容忍性则表示系统可以在遇到网络分区的时候仍然能够继续运行——也就是说,分布式系统在遇到网络分区故障的时候,仍然可以接受写入。

一般来说,分布式系统选择使用CA或CP或AP。对于一个分布式系统,最多只能同时满足两个。对于一个特定的分布式系统,Consistency和Partition Tolerance是不能同时做到的。也就是说,为了达成一致性,系统需要进行复杂的同步操作,而为了实现分区容忍性,系统需要准备好接受分区,甚至需要切换到另一个子系统,所以在实际工程应用中,CAP理论往往都与BASE理论融合一起使用。

在工程实践中,CAP原理主要用于在一个分布式系统中选取一个模型来表示。有些论文中采用三个维度来描述分布式系统:Consistency、Availability、Partition Tolerance。但是,由于Consistency与Partition Tolerance是不能同时实现的,所以工程实践中更多地关注CA或CP或AP中的两个。

Raft算法

Raft算法(Randomized Replicated Algorithms)是一种分布式共识算法,它的前身是Paxos算法,也是Google Chubby和etcd的核心算法。Raft算法最初提出是为了解决的问题是,如何在不牺牲一致性的情况下,通过在一组服务器上复制日志的方式来确保分布式共识(consensus)。与Paxos算法不同,Raft算法中所有的服务器节点,都可以相互理解。

Raft算法基于两种假设:Validity和Termination。Validity假设是指任何一个日志条目只会被提交一次,只有被投票过的日志条目才能被视为已提交。Termination假设是指,一旦系统的一个超过半数的服务器确认了一个日志条目,那么这个条目就会被提交。Raft算法遵循以下的规则:

  1. 任何超过半数的服务器必须能够相互通信;
  2. 如果一个服务器收到了一个客户端请求,那么它必须将其日志条目追加到自己的日志末尾,并向其他的服务器发送一条消息,要求其他的服务器也将该日志条目追加到他们的日志末尾;
  3. 一旦一个日志条目被提交,则其后的所有日志条目必须以相同的顺序被提交;
  4. 如果一个服务器宕机,则其之后所有未提交的日志条目都需要被删除;
  5. 每个服务器都必须存活,否则就会出现脑裂。

Raft算法有一些优化:

  1. 只需维持跟随者角色即可,非跟随者角色可以过期;
  2. 使用随机选举超时时间来降低选举的冲突概率;
  3. 通过日志压缩来清除已经被提交的日志;
  4. 在安全模式下对客户端禁止自动提交日志,只有在大多数服务器都处于正常模式下才允许提交;

ZAB协议

Zookeeper atomic broadcast protocol,是Apache基金会开源的一种基于Paxos的分布式协同协议。ZAB协议是为ZooKeeper项目开发的,是一种崩溃可恢复(crash-safe)的原子广播协议。ZAB协议的特点是能够很好的处理网络分区和结点失效。它基于TCP/IP协议族,并使用了一系列的启发式方法来改善分布式数据一致性和容错性。

ZAB协议包含两种基本类型消息:投票消息(Vote)和广播消息(Broadcast)。当一个服务器出现以下任一情况时,会转换为“崩溃”状态:

  1. 接收不到来自Leader的消息;
  2. 不能在恢复阶段将消息写入磁盘;
  3. 发出投票或广播消息的时间太久,超过了Leader选举的时间窗口。

ZAB协议使用的三个基本模式如下:

  1. 崩溃恢复(Crash Recovery):当Leader失效时,ZAB协议进入崩溃恢复模式,来选举一个新的Leader。它在整个集群中广播请求,收集回复,然后确定哪个服务器的日志更新的最新,从而把集群恢复到一个正确的状态。
  2. 跟随者(Follower):在正常状态下,所有服务器都是Followers。他们只响应客户端请求,不参与决策。
  3. 领导者(Leader):当Leader出现故障时,需要选举一个新的Leader,这时集群的所有服务器都会进入“预提交”(Pre-Commit)状态。直到确定了先前Leader的日志位置,所有服务器才会提交日志。ZAB协议只对确定了自己历史上提交过的那个日志条目之后的条目进行提交。

ZAB协议通过使用确定性的、单调递增的序列号来维护集群的全局一致性。每个Proposal都关联了一个Epoch,它表示一个逻辑时钟,用于保证Proposal顺序递增。每一个Server在接受到消息之前,都验证了其Leader Epoch是否与自己保持一致。这样就可以防止旧Leader重放未知的消息,导致集群不可用。

ZAB协议还提供了一种特别的方式来处理客户端请求,它允许客户端将多个事务组合成一个单独的事务请求。这使得客户端不需要等待单个事务的执行结果,而是可以得到多个事务的执行结果的合并视图。

DNS解析与负载均衡

DNS域名解析是指将域名转换为IP地址,从而使用户可以访问互联网上的网站。域名解析系统需要分布在不同区域的服务器之间进行通信,以便将域名映射到相应的IP地址。

负载均衡器是指将网络流量分布到多个服务器上,以达到提高网站性能、提高可靠性和可用性的目的。负载均衡器通过分析网络流量,对进入请求的流量进行动态分配,将流量集中到最繁忙的服务器,以提升网站的响应速度。

负载均衡技术可分为四种:静态负载均衡、动态负载均衡、源站负载均衡和IP负载均衡。静态负载均衡指在配置中事先定义服务器的位置,使用固定的服务器进行请求分发。动态负载均衡指根据当前负载情况对服务器进行移动,根据流量调度算法,平衡集群中的负载。源站负载均衡又称为会话粘滞,是通过为客户端保留一个服务器连接,使得客户端始终连续向同一个服务器发送请求。IP负载均衡通过将客户端的IP地址映射到服务器的地址,将流量分配到不同的服务器上。

静态负载均衡的缺点是配置难度大,当服务器需要替换时,需要修改配置文件;动态负载均衡的缺点是无法应付短期波动,而且使用动态的负载均衡,需要占用大量的内存;源站负载均衡存在会话关联问题,当客户端的连接断开时,需要等待超时时间;IP负载均衡的缺点是需要使用专门的负载均衡设备,且配置复杂。因此,目前主流的负载均衡技术是使用软件实现动态负载均衡,如Nginx、LVS等。


网站公告

今日签到

点亮在社区的每一天
去签到