什么是高可用?
高可用性 (High Availability – HA) 指的是系统具备较高的无故障运行的能力, 大白话的说, 就是你的系统在提供服务过程中, 不遇到或者几乎很少遇到影响服务质量的事件(诸如服务器宕机、一段时间内提供的数据都是错误的这种).
怎样才算是高可用?
对于可用性的度量, 有着两个相关度量参数:
- MTBF(Mean Time Between Failure) 平均故障间隔: 两次故障的间隔时间. 时间越长, 系统稳定性越高.
- MTTR(Mean Time To Repair) 平均故障时间。值越小,故障对于用户的影响越小。
一般用 MTBF / (MTBF + MTTR) 来代表系统的可用性, 表达式可以理解为: 系统正常运行的时间, 在系统总运行时间中的占比.
系统可用性 | 年故障时间 | 日故障时间 |
---|---|---|
90%(1个9) | 36.5天 | 2.4小时 |
99%(2个9) | 3.65天 | 14.4小时 |
99.9%(3个9) | 8小时 | 1.44分 |
99.99%(4个9) | 52分钟 | 8.6秒 |
99.999%(5个9) | 5分钟 | 0.86秒 |
99.9999%(6个9) | 32秒 | 86毫秒 |
在不同的可用性百分比要求下, 对应着不同的处理方式:
- 1/2个9的时候:
人肉管理, 人肉监控即可.
- 3个9开始:
- 运维值班体系: 设置监控、报警等, 出现问题时快速响应, 快速定位;
- 故障处理流程: 根据问题严重级别提升上线/修改的效率;
- 业务变更流程: 服务包的直接更替往往会出现服务的不可用, 考虑是否要考虑热部署来保障服务上线的平稳过度;
- 4/5个9的时候:
依赖机器的自动容灾处理(等到人发现、通知、上线, 远大于这个时间).
综上所述, 一般来讲, 对于核心系统的可用性要 >= 4个9, 非核心系统可用性 >= 3个9.
互联网应用, 提供服务的正确性收到的影响来自方方面面, 单纯的要求不出错是不现实的. 高可用是一个抽象概念, 是在对比中产生. 比如说: 日活用户1000的系统, 在衡量一分钟的故障时间时, 远没有日活用户1000w的系统来的严峻.
要怎么做到高可用?
系统设计
"Design for failure", 在设计系统的时候, 就要把故障的时候如何将影响降到最低考虑进去. 在成型的互联网应用中, 一个集群的机器经常可以达到三位数, 甚至四位数, 如此大的基数, 单机故障几乎是常态, 所以在设计系统之初就要提前考虑好故障的发现和解决, 包括但不限于:
- 故障转移:
a. 完全相同服务节点之间做替换, 比如Nginx可以配置在某一个Tomcat的返回code为500时自动重试其他的Tomcat节点;
b. 主备服务节点之间切换: 通常来讲, 由代码去检测提供服务的主节点是否能够继续提供服务, 比如心跳监测机制, 当监控者一段时间没有收到主节点的心跳信息, 视为主节点down, 开始重新选主(这里需要保证所有的备份节点在提供服务状态上保持一致, 通常会使用分布式一致性算法, 例如Paxos, Raft等). - 超时控制:
a. 复杂的业务中往往需要较多的RPC接口调用来组装数据, 如果没有对应的超时控制, 大量的慢请求就会把服务夯死;
b. 系统超时时间的制定, 通常以一个系统的普遍响应时间为准, 同时也要在系统的维护中不断修改;
c. 超时控制本身是通过牺牲少量超时请求来保证系统的整体可用性. - 降级: 通过减少某些服务流程来保证主流程的畅通, 比如发帖时的垃圾帖检测, 当可遇见的发帖高峰到来时, 就可以降低垃圾帖的检测标准, 甚至暂时去掉这一检测, 来保证主流程不会被这个非核心业务拖垮;
- 限流: 通过计算和故障演练后, 单个节点能够承受的Qps为100, 那么超过100Qps的时候, 多出来的并发请求就被丢弃掉, 虽然对于多出来的用户体验很糟糕, 但是在大量请求的场景下只能如此.
系统运维体系
- 灰度发布
代码是具有固定逻辑和运转条件的, 错误的代码轻易无法正常运行, 换言之正常运行的代码, 在正常的业务请求下也不会经常出现问题. 但是在版本更迭的时候, 由于存在较多的环境变化, 所以是问题多发期. 那么除了出现问题时的上线回滚外, 常见的运维手段就是 "灰度发布".
常见的灰度发布是指, 代码版本的变更不是一次性被推到线上的, 而是以机器节点为纬度, 按照一定的百分比逐渐推送到线上. 在这一过程中就可以通过各种看板对变动的系统进行监控, 如果运行了一段时间之后没有出现大量报错, 就可以推动全量升级.
- 故障演练
不打无准备之仗, 是我中华儿女自古而来就具备的战略思想, 灰度发布让我们有机会来减少故障发生的影响, 那么故障发生时我们又该怎么办? 有哪些故障会发生? 这些问题只通过代码review通常无法得到答案, 这个时候我们就需要故障演练来保证, 大多数问题我们是已经见到过的, 可以有组织有几率的处理问题.
故障演练不一定非要在线上进行, 因为某些系统的故障在业务场景是不被允许的(比如说一共就三台节点, 那么进行一台节点的down掉演练显然是不合适的). 可以通过环境隔离在线下模拟一套完全相同的环境和数据, 以此来模拟故障发生.
题外话
系统的可用性通常和性能是要做出取舍的, 追求极致的性能势必要舍弃一些可用性, 反之亦然.
暂无评论