高可用性(High Availability,HA)是你在系统设计时经常会听到的一个名词,它指的是系统具备较高的无故障运行的能力。
在许多开源组件的文档中,我们经常会看到高可用性(HA)方案的提法,这些方案旨在提高组件的可用性,以确保系统在发生故障时不会宕机或无法提供服务。以Hadoop为例,早期版本中的NameNode是单点的,这意味着一旦NameNode发生故障,整个Hadoop集群就会变得不可用。然而,随着Hadoop 2版本的推出,引入了NameNode HA方案。该方案同时启动两个NameNode,一个处于Active状态,另一个处于Standby状态,它们共享存储。当Active NameNode发生故障时,Standby NameNode可以迅速切换成Active状态,继续提供服务。这样做增强了Hadoop的持续运行能力,提高了系统的可用性。这种HA方案可以确保系统在面临故障时仍能保持高可用性,不会中断服务。
在高并发大流量系统中,系统的可用性比性能问题更加关键。一分钟的故障可能会影响数千用户的使用体验,尤其是对于拥有数百万日活用户的系统。随着用户数量的增加,系统对可用性的要求也变得更高。因此,今天我们将探讨如何确保高并发环境下系统的高可用性,以为系统设计提供一些思路。
可用性的度量
可用性是一个抽象概念,用于衡量系统的稳定性和可靠性。为了度量可用性,我们通常关注两个关键指标:MTBF(Mean Time Between Failure,平均故障间隔时间)和MTTR(Mean Time To Repair,平均修复时间)。
MTBF表示系统正常运行的平均时间,而MTTR表示平均修复故障所需的时间。这两个值的关系可以用以下公式表示:可用性 = MTBF / (MTBF + MTTR) 这个公式计算出的结果是一个比例,代表系统的可用性。一般来说,我们使用几个九(例如,99.9%、99.99%等)来描述系统的可用性水平。
高可用系统设计的思路
确保高可用性的成熟系统需要同时从系统设计和系统运维两方面进行保障。让我们分别看看如何从这两个方面入手来解决高可用性问题
1. 系统设计
在高并发系统设计中,我们始终遵循”Design for failure”原则。在这类系统中,有成百上千台机器组成的集群,单个机器故障是常态,几乎每天都可能发生。
提前思考和准备是至关重要的。在系统设计中,我们必须将故障视为关键考虑因素,并提前考虑如何自动检测和处理故障。此外,我们还需要掌握一些具体的优化方法,如故障转移、超时控制以及降级和限流策略。
通常情况下,故障转移(failover)可以发生在两种类型的节点之间:
-
完全对等的节点之间进行故障转移。
-
主节点和备节点之间进行故障转移。
在对等节点之间进行故障转移相对较简单。在这种系统中,所有节点都能处理读写流量,并且不保存状态。因此,如果某个节点发生故障,可以简单地将请求随机重定向到另一个节点,以实现故障转移。
举个例子,Nginx 可以配置当某一个 Tomcat 出现大于 500 的请求的时候,重试请求另一个 Tomcat 节点,就像下面这样:
针对不对等节点的 failover 机制会复杂很多。比方说我们有一个主节点,有多台备用节点,这些备用节点可以是热备(同样在线提供服务的备用节点),也可以是冷备(只作为备份使用),那么我们就需要在代码中控制如何检测主备机器是否故障,以及如何做主备切换。
使用最广泛的故障检测机制是“心跳”。你可以在客户端上定期地向主节点发送心跳包,也可以从备份节点上定期发送心跳包。当一段时间内未收到心跳包,就可以认为主节点已经发生故障,可以触发选主的操作。
选主的结果需要在多个备份节点上达成一致,所以会使用某一种分布式一致性算法,比方说 Paxos,Raft。
降级是为了保证核心服务的稳定而牺牲非核心服务的做法。比方说我们发一条微博会先经过反垃圾服务检测,检测内容是否是广告,通过后才会完成诸如写数据库等逻辑。
反垃圾的检测是一个相对比较重的操作,因为涉及到非常多的策略匹配,在日常流量下虽然会比较耗时却还能正常响应。但是当并发较高的情况下,它就有可能成为瓶颈,而且它也不是发布微博的主体流程,所以我们可以暂时关闭反垃圾服务检测,这样就可以保证主体的流程更加稳定。
限流完全是另外一种思路,它通过对并发的请求进行限速来保护系统。
2. 系统运维
在系统运维阶段,我们可以采取一些方法来提高系统的可用性,其中包括灰度发布和故障演练。
-
灰度发布:灰度发布是一种逐步推进系统变更的方法,而不是一次性将变更推向全部用户。通常,这是以机器维度为单位进行的。例如,首先在10%的机器上进行变更,然后观察系统性能指标和错误日志。如果在一段时间内系统运行稳定,没有出现大量错误日志,那么可以逐步增加变更的比例,直到全部变更完成。灰度发布为开发和运维团队提供了在线上流量上观察变更影响的机会,是确保系统高可用性的重要手段。
-
故障演练:通过定期进行故障演练,可以帮助团队更好地准备和应对真正的故障情况。在故障演练中,团队模拟各种故障场景,并测试系统的应急响应和恢复能力。这有助于发现潜在的问题并改进应急计划,以确保系统在故障发生时能够快速恢复正常运行。
故障演练是一种破坏性测试方法,通过在系统正常运行条件下引入局部故障,观察整体系统的表现,以发现潜在的可用性问题。在复杂的高并发系统中,涉及许多组件(如磁盘、数据库、网络等),这些组件可能随时发生故障。我们需要了解这些故障是否会像蝴蝶效应一样导致整个服务不可用。因此,故障演练至关重要。
故障演练的思路与当前流行的”混沌工程”非常相似。Netflix在2010年推出的”Chaos Monkey”工具是故障演练的经典应用。它通过随机关闭在线系统的节点来模拟故障,使工程师能够了解在发生这类故障时系统会出现什么样的影响。这种方法有助于识别系统中的弱点,并采取措施提高系统的可用性。
当然,这一切是以你的系统可以抵御一些异常情况为前提的。如果你的系统还没有做到这一点,那么我建议你另外搭建一套和线上部署结构一模一样的线下系统,然后在这套系统上做故障演练,从而避免对生产系统造成影响。
原文始发于微信公众号(二进制跳动):国庆专栏-系统设计目标:系统怎样做到高可用?
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/166970.html