系统定位
一个系统明确之初,就应该定义它设计的目标,比如现有的很多大型电商系统,可用性是它设计的目标,全年要达到5个9,而很多银行系统要求很强的事务性,那强一致就是其设计目标,保证不能错;还有一些系统需要很低的延迟等;定义好我们系统的目标后,围绕这些东西可以有很多设计理念可以运用;
高可用系统
高可用系统设计上,首先定义好我们可用率的目标,比如是99.999%,表示全量最多不可用5分钟,有了指标后,我们就要拆分下如何如何达到这个目标,因为大部分系统肯定不能自己闭环,你要依赖外部服务,db,mq等;
- 强依赖(典型的后端的db,或者不可或缺的外部服务)
- 弱依赖(忍受容错,可以被降级掉)
整体服务的可用率就可以计算出来了,假设强依赖之间是相互独立的
$$
self * \prod_{dependencies}availability = 0.9999 * \prod_{dependencies} 0.9999 = 0.9997
$$
可以看出要达到最终的目标,我们需要提升自己,或者强依赖;还有一些情况是当我们不知道对方的SLA时,如何预估这个值来帮助我们设计系统,此时会用到两个指标来预估;
- Mean Time Between Failure (MTBF)
- Mean Time to Recover (MTTR)
$$
Availability Estimate = MTBF / (MTBF + MTTR)
$$
比如MTBF=150days,MTTR=1hour,我们可以预估一个可用率是99.97%,有了以上数据支撑后,需要技术上做一些事情来支撑,可用率的提升,简单总结为以下几点:容量管理
我们需要很清楚自己的系统,知道他在不同资源下的水位,如何设计系统限流等网络管理
你需要清楚自己服务的部署情况,是否会有跨机房的通信,网络延迟是怎样的,是否会导致堆积,如何处理Dos,如何做Load Balance,网络的FO等服务管理
将自身服务按照有状态和无状态进行拆分,因为你的业务特点,可能会面临每时每刻的峰值变换,要能方便的scale-outIsolation
有了独立的Replica之后,我们可以显著的提升可用率,它的计算模式变为了:
$$
self * \prod_{dependencies}not/availability = 0.9999 * \prod_{dependencies} 0.001 = 0.9997
$$level0
:我们需要互相独立的available zone来提供服务,方便基础设施出现问题后进行切换level1
:关键性的模块支持副本,提升这些模块的可用率,避免一些单点问题容灾管理
设计的目标是出现故障后,如何缩短恢复的时间,梳理业务的预案,出现问题后available zone的切换方案,关键模块的切换方案,或者能不能做到自动化的FO
;梳理主链路,一些弱依赖出现问题能否直接降级掉,减低风险;容灾也需要经常测试,因为不同场景的切换,可能导致流量超过某个zone的承载极限,最好能支持快速的auto-scaling;变更管理
系统出现问题的情况很多都是由于变更(部署,热变更)等,所以我们需要遵循一些变更的best practice:灰度发布
,小批量多次进行发布,减少影响范围蓝绿发布
,整个发布分成两个部分,当一个部分出现问题,可以FO到另外部分,然后快速回滚,进行恢复功能开关
,新功能上线的时候默认把开关关闭,少量打开确认无问题后,才全量放开测试
,包括代码部分的单测,集成测试;上线后的灰度测试等;测试需要覆盖正常和异常的情况监控&报警
我们需要对系统有深入且实时的了解,以便做出正确的应对