http://www.csdn.net/article/2013-01-05/2813427-Github-Downtime-last-Saturday
摘要:距离今年9月份在两天内两次宕机仅间隔3个月。12月22日,全球知名的开源托管服务GitHub意外遭遇了历史上最严重的一次宕机事件。GitHub官方确认了本次宕机是在例行的软件升级过程中发生的,并在官方博客上解释了事故发生的原因和反省,开源中国社区翻译了该博文的部分内容,CSDN整理并编译了余下的部...
CSDN.NET(子曰/编译)距离今年9月份在两天内两次宕机仅间隔3个月。12月22日,全球知名的开源托管服务GitHub意外遭遇了历史上最严重的一次宕机事件。GitHub官方确认了本次宕机(回放)是在例行的软件升级过程中发生的,并在官方博客上解释了事故发生的原因和反省,开源中国社区翻译了该博文的部分内容,但可惜漏掉了不少重要内容,CSDN整理并编译了余下的部分,与大家分享。
背景
周六上午我们按计划要做一次例行维护,以确保软件在聚合交换机上的顺利升级。这次升级是在网络供应商建议下进行的,目的是为了解决早些时候发生的宕机事故。在次之前,我们已经在类似设备上做过多次测试都没有出现任何意外,我们对本次升级也充满了信心。然而,即便准备充分,软件升级仍然总是伴随着风险,为此,我们预留了维护窗口期和技术支持人员提供电话服务,以防意外事件的发生。
问题出在哪里?
在GitHub的网络中,每一台接入交换机,也就是每一台服务器都连接着一对聚合交换机。这些聚合交换机成对安装并通过一种叫做MLAG的功能来伪装成一个单线路由,因为link aggregation,spanning tree和其他layer 2协议希望有一个单独的主设备。这使得我们能够在一个聚合交换机上进行升级,而不会影响其他合作伙伴交换机或其他接入连接的交换机。值得一提的是,我们之前已多次成功运行过(MLAG)功能。
我们打算每次升级一台聚合交换机,这一过程被称作在服务中软件升级(n-service software upgrade)。即首先上传新的软件到一台交换机,配置交换机后,在新版本上重新启动,并发出reload命令。余下的交换机探测到不能连接到它,就将开始一个故障转移过程接管原来由MLAG共同管理的资源。
在开始升级后,我们遇到了一些预料外的故障,这些故障引起了20-30分钟的网络不稳定,随后我们尝试在维护窗口期处理这些问题。我们为此关闭了一半的聚合交换机和接入交换机的链路,这样做能够缓和一些问题,然后我们继续与网络供应商协作,试图找到让网络不稳定的深层原因。这仍然没有起到作用,受累于冗余的制度,我们只能操作一半的上路链接,我们的流量是比较低的,这在当时并没有解决真正的问题。在太平洋时间11:00,根据我们以往的经验,如果我们对于这个新版本问题还不能有一个好的解决办法,我们打算回滚本次软件升级,并且回滚到太平洋时间13:00的状态。
在太平洋时间12:15分,我们的网络供应商开始从交换机上收集最后的取证信息,以便他们尝试找出本次事故的原因。绝大多数的信息收集是隔离开进行的,包括收集日志文件和检索交换机各部分的硬件状态。作为最后一个步骤,他们尝试收集一个运行在交换机上的代理的状态。这涉及到停止的过程和促使它以某种方式写入状态,并在稍后进行分析。于是我们断开了接入交换机之间的链路,让它们彼此不相互受影响。这与我们之前以MLAG模式重启交换机类似,而在此前多次测试中都是没有出过意外的。
这时候,事情开始变得糟糕起来。一个部署在交换机上的代理被终止,一个节点在等待再次响应时出现了5秒的延迟。节点间无法彼此响应,但它们之间的链路仍然是联通的,可以预想其他的交换机也在以类似的状态运行,但都已经处于不能同步(消息)的状态。在这种情况下,交换机之间无法安全的接管共享资源,因此它会默认回到link aggregation, spanning tree和其他两层协议下的独立交换机运行状态。
通常情况下,这并不是一个问题,因为该交换机在它的对端失效之前还会查看这条链路的状态。当链路失效时,交换机会等待2秒看看链路是否恢复。如果链路没有恢复,交换机会假设对端完全失效的同时接管MLAG资源。这一类接管并不会触发任何第二层(链路层)的变化。
当在第一台交换机上的代理被终止,节点间的链路并没有减少,只是代理无法指示硬件重置链路,直到代理重新启动,并再次向相关交换器硬件发出命令。
当发生这些的时候它引起巨大的流量损失并且我们所有的链路要重新建立,leader选择使用生成树协议(spanning-tree网络协议),并且所有网络中的链路通过生成树协议恢复。这使得通过接入层交换机的流量被阻塞了1.5分钟。
文件服务器影响
我们的文件服务器是由一些采用高可靠性保障软件Pacemaker, Heartbeat 和 DRBD管理的主/备服务节点对组成,其中DRBD软件可以将主节点上的磁盘数据变更同步到备节点,而Heartbeat和Pacemaker一起协同工作,管理主节点的服务进程和故障恢复。
通过DRBD,确定数据卷是否单独挂载在簇中的一个结点是非常重要的。DRBD保证数据挂载在一个链接的两端节点上并且保护接收端是只读的。再说明一点,我们使用STONITH(Shoot The Other Node In The Head)进程在等待失败或者过期之前去关闭活动的节点。我们想确保我们没有进入一个”精神分裂“状态,比如数据写入到了两个节点中而且还无法回复这个数据传输中断的情况。
当网络冻结后,很多为应对冗余而刻意部署在不同机架上的文件服务器,超出了他们的heartbeat集群系统的响应限时,而导致它们需要控制文件服务器资源。它们向合作节点发出STONITH命令,试图去控制(文件服务器)资源,然而,由于受累于网络,这些命令中的相当部分并没有传达出去。当网络恢复的时候,分布在节点间的簇信息传送回来,很多对结点都在抢相同的资源,由此导致严重竞争,我们关闭了这些节点。
当我们发现了这个问题后,我们立即采取了以下措施:
恢复
当双节点由于上诉故障停止工作后,待再次重新联机的时候再次激发这些活跃节点尤为重要,因为它们影响到文件系统的当前状态。在大多数情况下,当结对的文件服务器在检查集中式日志数据的过程中出现问题的时候,来确定哪个节点是活跃节点是一件容易的事。然而在某些情形下,依据日志数据尚不能得出最后的判断,我们只好在不开动文件服务器资源的情况下启动双节点中的一个,检查它的本地日志文件,以此来判断哪个节点才是主节点。
这种恢复是一个非常耗时的过程,我们决定在维护模式下离开现场,直到最终恢复每一个文件服务器对。由于问题广泛存在,这个过程花了五个多小时才完成。我们不得不对整个GitHub文件存储基础设施中的绝大比例部分进行重新启动,验证它们是否工作正常,并确保所有的对节点正确复制。这个过程中并没有发生其他的意外,我们在太平洋时间20:23返回现场工作。
从宕机事故中获得的五点重要反省
注:转载本站文章请注明作者和出处,请勿用于任何商业用途