高可用性概述
什么是高可用性
高可用性 = 高 + 可用性。可用性(Availability)表示系统能在客户需要的时候提供服务的能力,而高则表示系统具有相当高的可靠性。高可用性中的"高"针对不同的系统的含义是不同的,而不是简简单单的7x24。比如,上交所和深交所的股票交易系统的高可用性只的是股票交易日交易时段的服务可靠性,在非交易时段系统不提供服务不影响该系统的高可用性。下图是一个以7x24无间断服务可用性标准示意图。
上图的数据让我们直观地看到实现7x24的高可用性是多么的难。
数据化定义
A = MTBF / MTBF + MTTR
其中MTBF表示mean time between failures,而MTTR表示maximum time to repair or resolve。
由这个定义我们可以看出我们有两种方法提高系统的可用性:
提高MTBF;
降低MTTR。
事实上,大量公司和企业均把大量的精力花费在提高MTBF,却忽视了降低MTTR。要提高可用性,我们在这两点上需要同样出色。
高可用性是一个商业策略
下图是投入和可用性的关系图。
从上图可以看出,可用性和投资花费之间的关系图。随着可用性要求的提高,投入所产出的可用性边际效益相当的越来越小。任何时候我们都要清楚的意识到我们系统所需要的可用性,以做出满足公司可用性要求,有最高性价比的方案设计决策。总之高可用性是一个商业策略。
高可用性是一个Teamwork
高可用性是有多个层次组件共同决定的,一个系统的最终可用性计算如下:
A(x) = A_Hardware(x) * A_DB(x) * A_NETWORK(x) * A_APPSERVER(x) * ...
由上面的公司我们可以看出,高可用性是一个Teamwork,需要大家共同协调来提高。
可靠的硬件,OS,系统架构,高可用性的编程实践,系统的监控统计,故障转移和恢复预案的实战演练共同构成了高可用性的保障。
硬件相关
需要机械移动的设备更容易出错:磁盘、风扇、光盘等等。在大多数时候我们尽量使用更加可靠的设备来响应服务。内存的可靠性远远高于磁盘就是我们使用缓存的一个重要原因。无论是硬件还是软件架构,提高可靠性的一个基本做法就是冗余。另一个重要的原则是冗余组件的独立性。无论是跨硬盘、跨主机、跨机柜、跨机房等等最根本的原则都是冗余组件的独立性。当然冗余组件的独立性也带来了系统并行的可能性,从而也会提高系统的性能。
存储
磁带/光盘 :主要用来备份(backup)大规模数据。
冗余磁盘阵列(RAID),常用的包括RAID1,RAID5,RAID10等。
Storage Area Network(SAN):使用本地高速网络将各种存储硬件(比如磁盘,磁盘阵列等)连接起来,提供一个大容量,高速的块设备抽象。
Network Attached Storage(NAS):使用本地高速网络将各种存储硬件(比如磁盘,磁盘阵列等)连接起来,提供一个大容量,高速的文件系统抽象。SAN和NAS提供的抽象层次不一样。
网络
冗余路由
电源/风扇
系统架构
无状态架构
无状态架构是系统水平可扩展的重要前提。无状态意味当一个节点出现故障时无须状态转移,可以快速增加,减少,替换节点。Map Reduce就是一个典型的无状态架构,Erlang则从语言层面实现了无状态架构。
需要存储状态的系统能使用无状态架构吗?系统的关键是将状态的管理从系统中分离出来,系统的核心部分则不再需要关心状态相关的工作。
负载均衡
负载均衡的冗余模式:
1:Active-Standby;
2:Active-Active;
3:Virtual Router Redundancy Protocol(VRRP),请参考RFC2338。
负载均衡器(硬/软):F5, ARRAY, DNS, LVS, nginx/apache
异步消息架构
系统接收请求后,根据请求进行必要的业务处理,然后产生相应的消息(或事件),则服务返回成功响应。系统后续再异步处理该消息来完成整个业务。在整个业务处理过程中可能会消费消息,然后产生新的消息,整个系统的业务由消息来驱动。基于消息的架构系统的核心在于系统业务的分割,确定系统的业务关键点。如果系统的业务关键点执行成功,则可以保证整个请求业务最终的成功和一致性。消息的架构可能会导致系统的暂时不一致性,但是能保证系统业务的最终一致性。BASE原则(Base Availability / Soft State / Eventually Consistent)就是基于消息的架构的一个重要原则方法。
使用缓存
使用缓存的依据是存储的局部性访问原理。缓存能增快系统的访问速度,同时能增加系统的可用性。增加系统的可用性的原因是内存的可靠性远远大于磁盘等机械设备。使用缓存能有效避免磁盘的损耗,增加磁盘的使用时间。
缓存是多层次的,既有静态资源的缓存,也有服务端业务数据的缓存,还有OS层的缓存。
缓存需要考虑:主存和缓存的一致性、缓存清除策略、键/值结构设计、缓存的可用性、命中率。
目前流行的缓存包括:memorycache、redis等。其中memorycache是典型的KV型缓存,而redis则有更丰富的内存数据结构。
题外话:如果未来Flash DISK的价格进一步下降,容量增大的话,我们设计系统的方式可能会完全不同。
分布式系统
CAP定律(Brewer's theorem)
分布式系统无法同时保证以下三点:
1:一致性(所有的节点在同一时刻数据完全相同);
2:可用性(任何请求无论成功与否,均会获取相应);
3:分片容错(系统在强制消息丢失和系统部分失效的情况下仍然能继续工作)
BASE方法
1:基本可用性(Basic Availability)
2:软状态(Soft State)
3:最终一致性(Final Consistency)
BASE方法本质上是一个异步的方法,系统根据请求存储足够的能够最终完成请求的状态信息,这样可以保证即使部分系统不可用的情况下,仍然能先相应请求。然后根据状态信息来最终完成业务,保证一致性。
不要将BASE仅仅局限于狭隘的分布式系统,此处的一致性不仅仅是数据节点,更可以是广义的业务。
分布式存储数据库
节点关系:主主模式(Master-Master),主从模式(Master-Read);
查询支持:支持超大表的排序查询、支持高速的KV查询、支持范围查询、......;
事务支持:不支持事务、部分支持、完全支持;
任何时候,我们需要系统的需要,选择最合适的存储方法。
分布式文件系统
HFS、GFS
分布式协调系统
分布式协调系统通常作为一个完整的分布式系统的一部分,起到一个全局协调的作用。
Hadoop子项目Zookeeper主要有以下特点:
1:开放存储库,树形层次结构主要存储元数据信息;
2:保证部分节点失败的高可用性,保证在一半以上节点正常的情况下就能继续工作;
3:针对节点相关的监听机制。
集群概述
集群是一组协同工作的服务实体,用以提供比单一服务实体更具可用性、可扩展性的服务平台。
常见的分类有:
高可用性集群(HA - High Availability)。典型的有数据库的主从集群。
负载均衡集群(LB - Load Balancing)。典型的有web server。负载均衡设备DNS、LVS或者F5等。
高性能计算集群(HPC - High Performance Computing)。典型的有hadoop。又有诸多特征:
分布式计算 (DC - Distributed Computing)。把计算任务分配到多个计算单元,如何拆分,如何合并。
并行计算 (PC - Parallel Computing)。松耦合的计算任务如何充分利用计算资源。大到进程级并行,小到线程级并行。
目前,大多数集群是混合了其中几种特征。
程序实践
契约式编程:边界检查/参数检查/业务规则检查
防御式编程:不但提供和遵循契约,对于客户端不遵循契约的调用和服务端不遵循契约的实现提前进行防范,并进行妥善处理;
优雅退出:系统退出前,应该进行系统申请资源的释放等各种工作;
内存泄漏检查:系统应该进行代码形式测试发现可能出现内存泄漏的写法和运行内存测试、对内存使用状况进行监控发现内存泄漏;
检查点:系统可以设置检查点,进行检查点系统状态的快照,系统通过检查点可以进行系统恢复还原;
异常捕获处理:对于异常进行合理的处理;
死锁检测:对于少于允许产生死锁的系统或者非常重要的系统部件,需要提供相应的死锁发现机制,并在发现死锁后进行相应的处理;
网络超时:对网络操作进行Retry等相应处理;
监控线程:监控系统重要线程的生命状态,必要时进行重要线程的重启动;
通知机制:系统能够通过邮件、短信等方式报告系统的情况;
日志规划:合理地设计系统日志,有助于出现问题的准确定位。
流程实践
备份和故障转移方案
编写完善的Backup和故障转移方案,并且要进行实战演练。保证Bakeup的实际可行性是减少MTTR,来提高系统可用性的有效方法。
系统监控
系统应该进行各个层次的监控,包括底层硬件级别监控、操作系统监控、系统软件监控、系统内部服务状态的监控,外部监控。通过监控及时发现系统的问题和隐患,从而会解决问题争取时间。