大厂都是如何对高并发系统做到高可用的?

高可用性(High Availability,HA)

系统具备较高的无故障运行的能力。

Hadoop1.0的NameNode是单点,一旦故障,整个集群不可用。Hadoop2提出的NameNode HA方案就是同时启动两个NameNode:

  • 一个处Active状态
  • 另一个处Standby状态

两者共享存储,一旦Active NameNode故障,可将Standby NameNode切换成Active状态继续服务,增强了Hadoop持续无故障运行能力,即提升可用性。

可用性度量:

MTBF(Mean Time Between Failure)

平均故障间隔,代表两次故障的间隔时间,也就是系统正常运转的平均时间。这个时间越长,系统稳定性越高。

MTTR(Mean Time To Repair)

故障的平均恢复时间,也可以理解为平均故障时间。值越小,故障对于用户的影响越小。

可用性与MTBF和MTTR的值息息相关,公式关系:

Availability = MTBF / (MTBF + MTTR)

这个公式计算出的结果是个比例,代表系统可用性。一般会使用几个9描述系统可用性:

三个9后,系统的年故障时间从3d锐减到8h。到了四个九之后,年故障时间缩减到1小时之内。在这个级别的可用性下,你可能需要建立完善的运维值班体系、故障处理流程和业务变更流程。 还需要在系统设计上有更多的考虑。比如,在开发中你要考虑,如果发生故障,是否不用人工介入就能自动恢复。 工具建设也需更完善,以便快速排查故障原因,让系统快速恢复。

五个9后,故障就不能靠人力恢复。这个级别的可用性考察的是系统的容灾和自动恢复的能力,让机器来处理故障,才会让可用性指标提升一个档次。

核心业务系统的可用性,需要达到四个九,非核心系统可用性最多容忍三个九。

2 高可用系统设计

2.1 系统设计

“Design for failure”,高可用系统设计时秉持的第一原则。在承担百万QPS的高并发系统中,集群中机器的数量成百上千台,单机的故障是常态,几乎每一天都有发生故障的可能。

系统设计时,要把发生故障作为重要考虑点,预先考虑如何自动化发现故障,故障后如何解决。 还需掌握具体优化方法,如failover(故障转移)、超时控制、降级和限流。

发生failover的节点可能:

  • 在完全对等的节点之间做failover
  • 在不对等的节点之间,即系统中存在主、备节点

在对等节点之间做failover相对来说简单些。在这类系统中所有节点都承担读写流量,并且节点中不保存状态,每个节点都可以作为另一个节点的镜像。在这种情况下,如果访问某一个节点失败,那么简单地随机访问另一个节点就好了。

比如Nginx可以配置当某一个Tomcat出现>500的请求时,重试请求另一个Tomcat节点:

针对不对等节点的failover机制会复杂很多。比方有一个主节点,多台备用节点,这些备用节点可以是热备(同样在线提供服务的备用节点),也可以是冷备(只作为备份使用),那么我们就需要在代码中控制如何检测主备机器是否故障,以及如何做主备切换。

2.2 故障检测机制 - 心跳

可在客户端上定期地向主节点发送心跳包,也可在从备份节点上定期发送心跳包。当一段时间内未收到心跳包,就可以认为主节点已经发生故障,触发选主。

选主结果需在多个备份节点达成一致,所以会使用分布式一致性算法Paxos,Raft。

2.3 系统间调用超时

高并发系统通常有很多系统模块组成,依赖很多组件服务,如缓存组件,队列服务。调用最怕延迟,因为失败通常瞬时,可重试解决。而一旦调用某模块或服务发生较大延迟,调用方就会阻塞在这次调用,它已占用的资源无法释放。当存在大量这种阻塞请求,调用方就会因为用尽资源而宕机。

系统开发初期,超时控制通常不重视或未设置合适超时时间。

某项目的模块间RPC调用,超时时间默认30s。平时系统运行稳定,但流量大时,RPC服务端出现一定数量慢请求时,RPC客户端线程就会大量阻塞在这些慢请求上长达30s,造成RPC客户端用尽调用线程而宕机。

确定超时时间

  • 超时时间过短 会造成大量超时错误,对用户体验产生影响
  • 超时时间过长 又起不到作用

推荐收集系统之间的调用日志,统计比如99%响应时间是怎样的,然后依据该时间指定超时时间。 若无调用日志,则只能据经验指定超时时间。 无论使用何方式,超时时间都不会一直不变,系统迭代维护过程中会不断修改。

超时控制实际上就是不让请求一直保持,而是在经过一定时间之后让请求失败,释放资源给其它请求使用。 这对于用户有损,但是必要的,牺牲少量请求却保证了系统可用性。

还有两种有损方案保证系统高可用:

2.4 降级

为保证核心服务的稳定而牺牲非核心服务。

比方发条微博会先经过反垃圾服务检测,检测内容是否是广告,通过后才完成诸如写DB逻辑。

反垃圾检测是相对较重操作,涉及很多策略匹配,在日常流量下虽然会比较耗时却还能正常响应。 但并发较高时,它可能成为瓶颈,而且它也不是发微博的主体流程,可暂时关闭,这就能保证主体的流程稳定。

2.5 限流

通过对并发请求进行限速保护系统。

比如对Web应用,限制单机只能处理每s 1000次请求,超过部分直接返回错误给客户端。 这种做法虽损害用户体验,但是在极端并发下的无奈之举,属短暂行为可接受。

3 系统运维

可从灰度发布、故障演练考虑提升系统可用性。

在业务平稳运行过程中,系统很少故障,90%的故障发生在上线变更阶段。 比如你上了个新功能,由于设计方案问题,DB的慢请求数翻了一倍,导致系统请求被拖慢而产生故障。

若未变更,DB怎会无缘无故产生那么多慢请求? 重视变更管理很重要。除了提供回滚方案,另一个方案就是灰度发布。

灰度发布

系统的变更不是一次性推到线上,而是按照一定比例逐步推进。 一般灰度发布以机器维度进行。比如先在10%机器变更,同时观察系统性能指标及错误日志。 若观察一段时间后,系统指标依旧平稳且无大量错误日志,再推动全量变更。

所以灰度发布给了开发和运维同学转运机会,能在线上流量观察变更的影响,这是保证系统高可用的关键流程。

灰度发布是在系统正常运行条件下,保证系统高可用的运维手段,那如何知道发生故障时的系统表现?

故障演练

对系统进行一些破坏性的手段,观察在出现局部故障时,整体的系统表现是怎样的,从而发现系统中存在的,潜在的可用性问题。

比如磁盘,DB,网卡等组件随时随地可能故障,一旦故障,会不会如蝴蝶效应造成整体服务不可用呢?我们也无法知道,因此,必须故障演练。 和“混沌工程”的思路类似,作为混沌工程鼻祖,Netfix在2010年推出的“Chaos Monkey”工具就是故障演练绝佳的工具。它通过在线上系统上随机地关闭线上节点模拟故障,让工程师能够知晓在出现此类故障时会有何种影响。

这一切是以你的系统可抵御一些异常情况为前提。 若你的系统还没做到这点,建议你另外搭建一套和线上部署结构一模一样的线下系统,然后在这套系统上做故障演练,从而避免影响生产系统。

4 总结

开发注重的是如何处理故障,关键词是冗余和取舍

  • 冗余指的是有备用节点,集群来顶替出故障的服务,比如文中提到的故障转移,还有多活架构等等
  • 取舍指的是丢卒保车,保障主体服务安全

从运维角度来看则更偏保守,注重的是如何避免故障的发生,比如更关注变更管理以及如何做故障的演练。

两者结合起来才能组成一套完善的高可用体系。

提高系统的可用性,有时是以牺牲用户体验或系统性能为前提,也需大量人力才能建设完善。所以不该优化。比如核心系统四个九的可用性已经可满足需求,不必盲目追求更高可用性了。

有没有不追求性能,只追求极致可用性的呢? 有的。比如配置下发的系统,只需在其它系统启动时提供一份配置,所以秒级返回也可,十秒钟也OK,无非就是增加其它系统的启动时间。但对可用性要求极高,甚至六个九,因为配置可以获取慢,但不能获取不到!

原文地址:https://cloud.tencent.com/developer/article/2192098

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


学习编程是顺着互联网的发展潮流,是一件好事。新手如何学习编程?其实不难,不过在学习编程之前你得先了解你的目的是什么?这个很重要,因为目的决定你的发展方向、决定你的发展速度。
IT行业是什么工作做什么?IT行业的工作有:产品策划类、页面设计类、前端与移动、开发与测试、营销推广类、数据运营类、运营维护类、游戏相关类等,根据不同的分类下面有细分了不同的岗位。
女生学Java好就业吗?女生适合学Java编程吗?目前有不少女生学习Java开发,但要结合自身的情况,先了解自己适不适合去学习Java,不要盲目的选择不适合自己的Java培训班进行学习。只要肯下功夫钻研,多看、多想、多练
Can’t connect to local MySQL server through socket \'/var/lib/mysql/mysql.sock问题 1.进入mysql路径
oracle基本命令 一、登录操作 1.管理员登录 # 管理员登录 sqlplus / as sysdba 2.普通用户登录
一、背景 因为项目中需要通北京网络,所以需要连vpn,但是服务器有时候会断掉,所以写个shell脚本每五分钟去判断是否连接,于是就有下面的shell脚本。
BETWEEN 操作符选取介于两个值之间的数据范围内的值。这些值可以是数值、文本或者日期。
假如你已经使用过苹果开发者中心上架app,你肯定知道在苹果开发者中心的web界面,无法直接提交ipa文件,而是需要使用第三方工具,将ipa文件上传到构建版本,开...
下面的 SQL 语句指定了两个别名,一个是 name 列的别名,一个是 country 列的别名。**提示:**如果列名称包含空格,要求使用双引号或方括号:
在使用H5混合开发的app打包后,需要将ipa文件上传到appstore进行发布,就需要去苹果开发者中心进行发布。​
+----+--------------+---------------------------+-------+---------+
数组的声明并不是声明一个个单独的变量,比如 number0、number1、...、number99,而是声明一个数组变量,比如 numbers,然后使用 nu...
第一步:到appuploader官网下载辅助工具和iCloud驱动,使用前面创建的AppID登录。
如需删除表中的列,请使用下面的语法(请注意,某些数据库系统不允许这种在数据库表中删除列的方式):
前不久在制作win11pe,制作了一版,1.26GB,太大了,不满意,想再裁剪下,发现这次dism mount正常,commit或discard巨慢,以前都很快...
赛门铁克各个版本概览:https://knowledge.broadcom.com/external/article?legacyId=tech163829
实测Python 3.6.6用pip 21.3.1,再高就报错了,Python 3.10.7用pip 22.3.1是可以的
Broadcom Corporation (博通公司,股票代号AVGO)是全球领先的有线和无线通信半导体公司。其产品实现向家庭、 办公室和移动环境以及在这些环境...
发现个问题,server2016上安装了c4d这些版本,低版本的正常显示窗格,但红色圈出的高版本c4d打开后不显示窗格,
TAT:https://cloud.tencent.com/document/product/1340