高可用系统,追求多个9的可用性,对于分布式系统来说,我们通常都认为遵守CAP理论,根据业务场景,取平衡。
高可用,首先想到的是避免单点,防止单点故障。
1.负载均衡
硬均衡:F5设备 ,standBy从,主备切换。
软均衡:类似,实现方式LVS之类。
具体均衡的策略:
A.集中策略:权重、随机、负载能力(静态与动态)、connection等
B.分布策略:基于Gossip模型的方式。一般是内部的均衡策略
对于负载均衡,也要进行细分,比如请求流程和返回响应流程:
请求流程:1.分配策略;2.web请求会话处理方式
返回数据:1.经由负载均衡点;2.直接返回
中心负载均衡的缺陷:将请求分发到业务机器,业务机器对请求进行queue,如果其中某一个请求耗时,则导致该queue的请求任务被延时,很多任务会超时,类似于超时收银柜台某一个客户耗时,但是其它柜台却无法协同解决该问题(按照理想设计应当其它节点协同处理)。基于此,twinter提出了一个unicorn的解决方案,该方案是负载均衡机器对所有请求只发到一个队列,然后业务机器在该队列获取任务处理。某一个业务机器的耗时操作,并不影响后面的任务处理。
2.分布式环境下的事务
分布式环境下的强事务性,2段式提交、3段式提交这种分段时提交方式,如果任意一个节点执行出错,则进行rollback操作;
另外一种方法是基于paxos算法,类似于“民主集中制”,以多胜少。不在意个别master节点操作失败,如果大部分master节点操作成功,则操作被认为是成功的。
paxos算法,是在一篇paper中提及的,模拟的是议员议会审议的一种制度安排,basic paxos算法角色众多,不易实现,工业界又提出了multi paxos算法,简化了角色,但是核心思想是一致的。
这一块在阿里关于中间件的技术中有详细说明。
机房隔离和机房切换的问题比较复杂,网络的延时不可控。缓存失败的切换,导致流量激增,很可能也会导致新接入的机器快速奔溃。所以很多时候经常听到“平滑过渡”的方案。负载均衡方案中,也会考虑业务请求到业务机器,业务机器失败后流量是否导致后端集群不稳定?比如分布式缓存系统,某部分失败,信息的同步?
3.应用的高可用
1.Fail Fast
2.对接口与对象的保护
在网站的设计中,也要避免第三方依赖导致系统宕机,最好有一个option。比如在数据库缓慢的query,导致请求队列堆积,可以考虑优先使用缓存策略,分担压力。
对于一个系统,避免单点和应用的高可用是两个核心方面。如何保障系统面临的压力,就有了垂直伸缩和水平伸缩的选择。
4.构建可伸缩系统
垂直伸缩:通过增加单机的cpu、内存等方法扩充系统容量。
1.增加CPU后,若系统性能未能提升,可以考虑以下几个问题:
A.是否存在锁竞争问题
B.支撑并发请求的线程数量固定(建议使用Runtime.getRuntime().availableProcessor()来合理分配线程数)
C.单线程处理方式改为多线程处理
水平伸缩:比较复杂,涉及面很广,一般采用系统的切分、分表分库、数据库的分离、分布式系统等,涉及到业务系统切分、文件系统的分布式、网络的弹性、计算的并行等,根据具体应用、具体的业务要求选择不同的方案,逐步“进化”。
数据库访问:异步访问,Jboss Netty的测试报告中,异步数据库的访问方式可以大大提高访问数据库的性能。