高可用性指的是系统具备较高的无故障运行的能力。
可用性的度量
MTBF(Mean Time Between Failure) 是平均故障间隔的意思,代表两次故障的间隔时间,也就是系统正常运转的平均时间。这个时间越长,系统稳定性越高。
MTTR(Mean Time To Repair)表示故障的平均恢复时间。也可以理解为平均故障时间。这个值越小,故障对于用户的影响就越小
高可用系统的设计思路
- 系统设计。我们做系统设计的时候,要把发生故障作为一个重要的考虑点,预先考虑如何自动化的发现故障,发生故障之后要如何解决。还要掌握一些具体的优化方法,比如failover(故障转移)、超时控制以及降级和限流。
使用最广泛的故障检测机制是“心跳”。你可以在客户端上定期的向主节点发送心跳包,也可以从备份节点上发送心跳包。当一段时间内未收到心跳包,就可以认为主节点已经发生故障,就可以触发选主的操作。
超时控制实际上就是不让请求一直保持,而是在经过一定时间之后让请求失败,释放资源给接下来的请求使用。这对于用户来说是有损的,但确实必要的,因为它牺牲了少量的请求却保证了整体系统的可用性。
降级是为了保证和新服务的稳定而牺牲非核心服务的做法。比如发一条微博会先经过反垃圾服务检测,检测内容是否违规,通过后才会完成诸如写数据库等逻辑。
限流是另外一种思路。它通过对并发的请求进行限速来保护系统。
比如对于web应用,限制单机只能处理每秒1000次请求,超过的部分直接返回错误给客户端。虽然这种做法损害了用户的使用体验,但是这是在极端兵法之下的无奈之举,是短暂的行为,因此是可以接受的。
2.系统运维
在系统运维层面,我们可以用灰度发布、故障演练两个方面来考虑如何提升系统的可用性。
灰度发布指的是系统的变更不是一次性的推到线上的,而是按照一定比例逐步推进的。一般情况下,灰度发布是以机器维度进行的,比如说,先在10%的机器上进行变更,同时观察Dashboard上的系统高性能指标以及错误日志。如果运行了一段时间之后系统指标比较平稳并且没有出现大量的错误日志,那么再推动全量变更。
故障演练指的是对系统进行一些破坏性手段,观察在出现局部故障时,整体系统的系统表现是怎样的,从而发现系统中存在的,潜在的可用性问题。
一个复杂的高并发系统以来了太多的组件,比如说磁盘、数据库、网卡等,这些组件随时随地都可能发生故障,一旦它们发生故障,会不会导致整体服务不可用呢?因此故障演练尤为重要。Netfix在2010年推出的“Chaos Monkey”工具就是故障演练绝佳的工具。它通过线上系统上随机的关闭线上节点来模拟故障。
心跳检测是区分内部检测和外部检测,外部检测伴随着随机性,有时候可能系统的响应时间或者IO已经出现拐点了,但是心跳机制还是有可能会收到响应包,从而被错误的当做系统是“正常”的,所以很多高可用的系统基本都是采用内部心跳机制,比如kafka中的通过zookeeper的watch机制来做检测来做broker中controller的failover,mysql里面是通过内部的performance_schema库中的file_summary_by_event_name表来做监控,都是为了避免外部监测的随机性所带来的影响,不过对于老师提出的可用性和高性能当中出取舍无比赞同,不同的解决方案总是伴随着优势和劣势,无非是优势所带来的效果比劣势对业务更有帮助而已,比如之前在工作中碰到过mysql主从同步有延迟的情况,mysql的高可能性其实就是靠主备同步的数据一致性来保证的,经过排查发现,业务代码中存在有操作大事务的SQL语句,这个导致从库拿到binlog去做重放的时候,时间周期拖长了,从而影响了业务,另外一个情况就是,在做秒杀的时候,除了采用redis外,还会对用户划分成两部分,一部分用户是来了以后直接报秒杀已结束,另外一部分用户才会进入秒杀的逻辑中,心里觉得还是挺对不住那部分抢不到秒杀的用户的,所以,有时候我们需要在可用性和可靠性上需要做一个取舍,没有十全十美的技术解决方案。除此之外,其实大部分的时候采用的策略是需要对业务尽量是无损的,不然运营和产品会请你喝茶的
网友评论