设计高可用的软件架构,是每个互联网软件开发工程师的追求。尤其对于在线交易系统、在线广告系统而言,服务的可用性会直接影响商业变现。随着互联网技术在工业界的广泛使用,各大互联网公司在各自的业务领域内,沉淀了成熟的高可用架构方案。那么究竟什么是高可用?高可用架构该如何设计呢?
度量
服务处于不可用状态的时间称为故障时间。可用性每提高一个等级,故障时间就要降一个数量级。从天到时到分,相对来说比较容易实现。再往后每提高一个等级,将付出成百上千倍的努力。大型网站服务通常至少做个4个9,做到5个9及以上就比较困难了。不仅要解决技术挑战,还要面对极大的成本压力。对于网站核心服务,会尽可能做到5个9,而非核心服务4个9,甚至3个9也可以接受。做技术决策时必须考虑经济账。
方法
那如何做到高可用呢?方法很简单:冗余。通俗讲,就是双保险机制。背后的理论基础是概率论。假设某个服务的可用性是99%(故障率1%),那么两个服务的可用性就是1-0.01*0.01=99.99%。可以看到,冗余对可用性的提升是指数级的。再冗余一个服务,可用性就达到6个9了。哇!提高可用性等级似乎好简单啊!?
限制
真这么简单吗?当然不是。别忘了CAP定理!
设计
冗余的架构设计有三种模式:双主(Master & Master)、主备(Master & Co-Master)和主从(Master & Slave)。
双主模式中,两台服务是平等关系,同时对外提供读写服务,客户端任选一台即可。双主模式是可用性最好的,但是这种架构的一致性处理比较困难,需要两台服务进行双向数据同步。一旦它们之间的通信断开,就形成了网络分区,这种分区会带来脑裂(brain-split)问题,并且系统对此无解,必须人工介入。所以在架构设计时极少选择双主模式。
主从模式其实不是主要解决高可用问题的,更多的是为了实现读写分离,来解决高并发问题。实际场景中通常不是一主一从,而是一主多从架构,因为大部分应用都是的读多写少。主节点处理写请求,从节点处理读请求。由于存在多从,读服务的可用性远高于写服务。另外,写服务会存在单点故障。这个问题可以通过集群动态选主来解决:当主节点不可用时,集群自动选出一台新的主节点。基于zookeeper,动态选主很容易实现(延伸阅读《Zookeeper理论&应用&实操》)。不过动态选主在MySQL集群架构中不会使用,原因是主从同步数据必须在部署时配置好,切换了主节点还是需要运维人工介入修改配置并重启服务。
案例
上面是抽象的架构设计,实际场景的架构要更复杂,会组合使用主备和主从架构。下图是国内某互联网公司MySQL集群的简化版架构方案。