谷歌架构从故障转移系统到多宿主架构的转变
运行单数据中心的系统难度很高,那么切换到双数据中心吧,如果你需要对多个位于不同地理位置的数据中心提供支持。谷歌有一篇发人深思的优秀论文,其中对这一过程有所描述——“大规模高可用性:打造谷歌的广告数据基础设施”。
文中的主要观点是:在将单个数据中心切换到多个数据中心时,典型的故障转移架构在实践中效果并不太好。能够起到作用,使用较少资源就能提供高可用性和一致性的方法,是原生的多宿主/多重连接架构(natively multihomed architecture):
我们目前的方式是构建原生多宿主架构。在这样的系统中,多个数据中心会持续运作,并根据情况自发平衡不同数据中心的负载,同时还能以完全透明化的方式解决任意规模的数据中心停机。此外,按计划执行的数据中心停机与维护事件也是完全透明化的,这样就会将对运营系统造成的影响降到最低。在过去,要想完成停机与维护事件,需要付出大量人力将运营系统从一个数据中心迁移到另一个。
“多宿主”这种说法也许会令人费解,因为多宿主这个词一般指的是一台电脑连接着多个网络。不过按照谷歌的规模,用这种说法描述连接着多个数据中心也是非常自然的。
谷歌构建了多个多宿主系统,以确保在出现数据中心级别的停机时,还能保持高可用性(99.99%到99.999%)与一致性,下面这些文章对这些系统进行了详细描述: Spanner:关系数据库;Photon:对多个连续数据流进行join的部署;Mesa:数据仓储。这些论文分别讨论了各系统所采用的方式,以及在构建多宿主系统时遇到的诸多挑战:全局状态同步、怎么设置检查点,以及可重复的输入与只执行一次的输出等。
为了保持可用性与一致性,系统受到了很大约束。这就凸显了谷歌持续在简化这些复杂系统,提高其易用性上付出的努力:
“多宿主系统的简单性对用户是极有价值的,没有多宿主系统的话,无论故障转移、系统恢复还是一致性问题,都是应用需要解决的问题。而借助多宿主系统,基础设施会处理这些麻烦的问题,应用开发者只要专注于自身应用即可,可用性和一致性有系统来保障。”
在这篇论文中最大的惊喜就是:实际中,多宿主系统比故障转移系统所耗费的资源还要少: 部署在3个数据中心之上的多宿主系统,总同步性能为稳定状态的20%,总资源占用为170%,远远小于故障转移系统所需的300%。
故障转移系统有什么问题?
“基于故障转移系统的方式并未真正实现高可用性,而且由于需要部署备用资源,会带来成本浪费。 以前我们在使用故障转移系统时,有很多不好的体验。由于非计划性停机很少见,故障转移系统多是后期才添加的功能,无法自动化执行,也没有经过很好的测试。很多时候,团队需要花费数日才能从停机中恢复,一个组件一个组件的上线,用自定义MapReduces之类的临时工具执行状态恢复,并在系统处理停机时的积压工作时,逐步执行优调。这些情况不仅让系统无法再进行扩展,还让团队由于所运行的关键任务系统太过复杂而承受了极大压力。 ”
多宿主系统的工作原理是什么?
相比之下,多宿主系统在设计之初就将运行多个数据中心作为核心设计属性,因此无需另外添加故障转移系统。多宿主系统一直保持多个数据中心运行。每个数据中心都在持续处理工作,同时各数据中心之间的负载会自动进行平衡。一旦某个数据中心的处理速度减缓,系统就会自动将一部分工作调整到速度较快的数据中心上去。一旦某个数据中心出现故障完全不可用,所有工作都会自动分发到其他数据中心上去。 只有持续的动态负载平衡,不再有故障转移的过程。多宿主系统通过实时同步的全局共享状态来协调数据中心之间的工作。所有关键的系统状态都有备份,以确保随时能从另一个数据中心的某个点重新开始工作,同时确保恰一次语义(exactly once semantics)。在出现数据中心级别的故障时,多宿主系统是唯一能够提供高可用性和完整一致性的系统。 在典型流系统中,事件处理基于用户交互来解决;同时,全世界范围内的多台数据中心会为用户提供流量服务和日志存储服务。日志收集服务会在全球范围内收集这些日志,并将其复制到两台或多台特定的日志数据中心上。每个日志数据中心都会保存完整的日志记录,并确保复制到某个数据中心中的所有事件都会(逐渐)复制到其他日志数据中心上。流处理系统运行在一个或多个日志数据中心之上,并处理所有事件。流处理系统所输出的内容通常会存储在全球范围内的一些复制系统中,这样从任何地方都能可靠地对输出执行消费。 在多宿主系统中,所有数据中心都会持续运行并处理事件,典型状况下会部署三台数据中心。在稳定状态下,这三台数据中心每个都能处理33%的流量。如果某台数据中心出现故障而停机,剩下的两台数据中心会分别承担50%的流量处理工作。