GitHub服务中断24小时11分钟事故分析报告

640?wx_fmt=jpeg

来源 | The GitHub Blog

译者 | 无明

UTC 时间 10 月 21 日 22:52,为了更换发生故障的 100G 光纤设备,美国东海岸网络中心与美国东海岸数据中心之间的连接被断开。连接在 43 秒后恢复,但这次短暂的中断引发了一系列事故,导致 24 小时 11 分钟的服务降级。

前几日,GitHub 经历了一次事故,导致服务降级 24 小时 11 分钟。虽然平台的某些部分不受事故影响,但仍然有多个内部系统受到了影响,向用户显示了过时且不一致的内容。所幸没有用户数据丢失,但针对几秒钟数据库写入的手动调整工作仍在进行当中。在发生事故期间,Webhook 无法提供服务,也无法构建和发布 GitHub Pages。

我们对每个受影响的用户深表歉意。我们深切感受到用户对 GitHub 的信任,并为构建能够保持平台高可用性的弹性系统而感到自豪。在这次事故中,我们让用户失望了,我们深感抱歉。虽然我们无法撤销导致 GitHub 平台长时间无法使用的问题,但我们可以解释导致这次事故的原因、我们从中吸取的教训以及我们将要采取的措施,以便确保类似情况不会再次发生。

   背 景   

大多数面向用户的 GitHub 服务都运行在我们自己的数据中心。数据中心拓扑旨在提供强大且可扩展的边缘网络,位于多个区域数据中心的前面,这些数据中心负责处理计算和存储工作负载。尽管我们的物理和逻辑组件中内置了冗余层,但我们的站点仍然有可能在一段时间内无法相互通信。

UTC 时间 10 月 21 日 22:52,为了更换发生故障的 100G 光纤设备,美国东海岸网络中心与美国东海岸数据中心之间的连接被断开。连接在 43 秒后恢复,但这次短暂的中断引发了一系列事故,导致 24 小时 11 分钟的服务降级。

640?wx_fmt=png

之前,我们已经介绍过如何使用 MySQL 存储 GitHub 元数据以及我们实现 MySQL 高可用性的方法。

GitHub 拥有多个 MySQL 集群,大小从几百 GB 到 5TB 不等,每个集群最多有几十个只读副本来存储非 Git 元数据,因此我们的应用程序可以提供拉取请求和问题管理、身份验证管理、后台处理协调等原始 Git 对象存储之外的其他功能。应用程序不同部分的数据通过功能分片存储在各种集群中。

为了大规模提高性能,应用程序将数据直接写入每个集群的主数据库,但在绝大多数情况下将读取请求委派给副本服务器。我们使用 Orchestrator 来管理 MySQL 集群拓扑和处理自动故障转移。Orchestrator 以 Raft 的共识算法为基础,可以实现应用程序无法支持的拓扑,因此必须十分小心让 Orchestrator 配置与应用程序的期望保持一致。

640?wx_fmt=png

事故时间表

UTC 时间 2018 年 10 月 21 日 22:52

在发生网络分区时,主数据中心的 Orchestrator 根据 Raft 共识机制启动了首领卸任(deselection)过程。美国西海岸数据中心和美国东海岸公有云的 Orchestrator 节点获得了法定票数,并开始对集群进行故障转移,将写入操作定向到美国西海岸数据中心。当连接恢复时,应用层立即开始将写入流量引向西海岸站点的新主节点上。

美国东海岸数据中心的数据库包含了一小段时间的写入数据,这些数据尚未被复制到美国西海岸的数据中心。由于这两个数据中心的数据库集群包含了其他数据中心不存在的数据,因此我们无法安全地将主数据库转移到美国东海岸数据中心。

UTC 时间 2018 年 10 月 21 日 22:54

我们的内部监控系统开始发出警报,告知我们的系统出现了大量故障。这个时候,已经有几位工程师正在对收到通知进行分类。UTC 时间 23 点 02 分,第一响应团队的工程师已经确定很多数据库集群的拓扑处于不正常状态。Orchestrator API 显示的数据库复制拓扑只包含美国西海岸数据中心的服务器。

UTC 时间 2018 年 10 月 21 日 23:07

到了这个时候,响应团队决定手动锁定我们的内部部署工具,以防止引入任何其他变更。在 UTC 时间 23:09,响应团队将网站置为黄色状态。这样会自动将事故升级,并向事故协调员发送警报。在 UTC 时间 23:11,事故协调员加入,两分钟后决定将网站置为红色状态。

UTC 时间 2018 年 10 月 21 日 23:13

这个问题影响了多个数据库集群。来自 GitHub 数据库工程团队的其他工程师也收到了通知。他们开始着手调查,看看需要采取哪些措施将美国东海岸数据库配置为每个集群的主数据库并重新构建复制拓扑。这项工作具有很大的挑战性,因为到目前为止,西海岸数据库集群已经从应用层接收了近 40 分钟的写入数据。另外,东海岸集群中有几秒钟的写入数据未被复制到西海岸,并阻止将新写入的数据复制回东海岸。

保护用户数据的机密和完整是 GitHub 的首要任务。30 多分钟的美国西海岸数据中心数据写入让我们不得不考虑 failing-forward,这样才能保证用户数据的安全。然而,在东海岸运行的应用程序依赖于西海岸 MySQL 集群的写入信息,目前无法应对由于跨国往返而带来的额外延迟。这个决定将导致很多用户无法使用我们的服务。最后我们认为,延长服务降级时间可以确保用户数据的一致性。

640?wx_fmt=png

UTC 时间 2018 年 10 月 21 日 23:19

通过查询数据库集群的状态,我们发现需要停掉元数据写入作业。我们暂停了 Webhook 和 GitHub Pages,避免对已经从用户收到的数据造成损坏。换句话说,我们的策略是优先考虑数据完整性,而不是站点可用性和恢复时间。

UTC 时间 2018 年 10 月 22 日 00:05

事故响应团队的工程师开始制定解决数据不一致问题的方案,并实现 MySQL 故障转移。我们的计划是从还原进行备份,同步两个站点的副本,回退到稳定的服务拓扑,然后继续处理排队的作业。我们更新了状态,告诉用户我们将要执行一次内部数据存储系统的可控故障转移。

640?wx_fmt=png

MySQL 数据备份每四个小时进行一次并保留多年,但备份远程存储在一个公有云的 blob 存储服务中。恢复数 TB 备份数据需要数小时时间,大部分时间用于从远程备份服务传输数据。对大型备份文件进行解压缩、校验、预处理并加载到新配置的 MySQL 服务器上也花费了大量时间。在整个过程中,我们每天至少进行一次测试。在这个事故之前,我们从来没有基于备份完整地重建整个集群,而是依赖其他策略,例如延迟复制。

UTC 时间 2018 年 10 月 22 日 00:41

这个时候我们已经启动了所有受影响的 MySQL 集群的备份过程,工程师正在监控进度。同时,多个团队的工程师正在研究如何加快传输和缩短恢复时间,并且不会进一步降低站点可用性或者损坏已有数据。

UTC 时间 2018 年 10 月 22 日 06:51

美国东海岸数据中心的几个集群已经从备份中恢复,并开始从西海岸复制新数据。这导致必须通过跨国链接执行写入操作的页面的加载时间变慢,但如果读取请求落在新恢复的副本上,那么从这些数据库集群读取的页面将返回最新结果。其他更大的数据库集群仍在恢复中。

我们的团队已经知道如何直接从西海岸进行恢复,以突破从异地存储下载导致的吞吐量限制,并对恢复过程越来越有信心,建立复制拓扑所需的时间取决于复制需要多长时间才能赶上来。这个估计是根据我们现有的复制遥测数据线性插值得出的,我们更新了状态页面,设置了两个小时作为我们估计的恢复时间。

UTC 时间 2018 年 10 月 22 日 07:46

GitHub 发布了一篇博文,提供了更多的背景信息。我们在内部使用了 GitHub Pages,但因为几个小时前所有的构建都已暂停,所以发布这些内容需要额外的工作量。我们对造成的延迟深表歉意。我们希望能够更快地发布这些信息,并确保在未来可以在这些限制条件下发布更新。

UTC 时间 2018 年 10 月 22 日 11:12

美国东海岸的所有主数据库都已就绪。网站的响应能力也随之提升,现在写入操作被引向了与应用程序层同处同一物理数据中心的数据库服务器上。虽然这大大提高了性能,但仍有数十个数据库读取副本比主数据库延迟了几个小时。这些延迟的副本导致用户在与我们的服务进行交互时看到不一致的数据。我们将读取负载分散到大量的只读副本中,每个请求都有可能到达已经有几个小时延迟的只读副本上。

实际上,要让复制赶上主数据库,所需的时间遵循的是功率衰减函数(power decay function)而不是线性轨迹。当欧洲和美国的用户醒来并开始工作时,数据库集群的写入负载增加,恢复过程所耗费的时间比原先估计的要长。

UTC 时间 2018 年 10 月 22 日 13:15

到目前为止,我们正在接近 GitHub.com 的高峰流量负载。事故响应团队就如何开展后续的工作展开了讨论。很明显,复制延迟在增加。我们已经在美国东海岸公有云中配置额外的 MySQL 只读副本。一旦这些实例就绪,就可以更容易在更多服务器上分摊读取请求。减少跨副本聚合可以让复制更快赶上。

UTC 时间 2018 年 10 月 22 日 16:24

在副本进入同步状态后,我们对原始拓扑进行了故障转移,解决延迟和可用性问题。为了优先保证数据完整性,我们在开始处理积压数据时保持服务状态为红色。

UTC 时间 2018 年 10 月 22 日 16:45

到了这个阶段,我们必须平衡积压数据所带来的负载,因为过多的通知可能会导致生态系统的其他系统发生过载,我们还要尽可能快地将服务恢复到 100%。这个时候队列中有超过 500 万个 Webhook 事件和 8 万个页面构建请求。

当我们重新开始处理这些数据时,我们处理了大约 200,000 个 Webhook 负荷,这些负荷已经超过内部的 TTL 并被丢弃。在发现这个问题后,我们暂停了处理,并临时延长了 TTL。

为避免进一步破坏状态更新的可靠性,我们一直处于降级状态,直到处理完所有积压数据并确保我们的服务已明确恢复到正常的水平。

UTC 时间 2018 年 10 月 22 日 23:03

已处理完所有待处理的 Webhook 和 Pages 构建,并确认了所有系统的完整性和正常操作。网站状态已更新为绿色。

下一步解决数据不一致问题

在恢复过程中,我们捕获了 MySQL 二进制日志,其中包含我们在主站点中写入但未被复制到西海岸站点的数据。未复制到西海岸的写入数量相对较少。例如,我们最忙的一个集群在受影响期间有 954 个写入。我们目前正在分析这些日志,并确定哪些写入可以自行解决,哪些需要与用户进行确认。我们有多个团队参与了这项工作,并确定了有一类写入已经被用户重复操作并成功保留。我们的主要目标是保持用户数据的完整性和准确性。

沟通

我们希望在事故期间向用户传达有意义的信息,我们根据积压数据的处理速度对恢复时间进行了多次公开估算。回想起来,我们的估算并没有考虑到所有的变数。我们对此造成的混乱感到抱歉,并希望在将来能够提供更准确的信息。

技术举措

在此次分析过程中,我们确定了很多技术举措。随着我们继续在内部进行广泛的事故后分析,我们发现我们有更多的工作要做。

  1. 调整 Orchestrator 配置,以防止跨区域选举主数据库。Orchestrator 只会按照配置的参数运行,不管应用程序层是否支持这种拓扑变更。单个区域内的首领选举通常是安全的,但突然出现的跨国延迟是导致这次事故的主要因素。这是系统的紧急行为,因为我们之前没有遇到过这么大规模的内部网络分区。

  2. 我们已经建立了一个可以更快报告状态的机制,可以更清晰地谈论事故的进展。尽管 GitHub 的很多部分在事故期间仍然可用,但我们只能将状态设置为绿色、黄色和红色。我们意识到,这并不能让我们准确了解哪些部分在正常运行,哪些部分出现了故障,在将来,我们还将显示平台的不同组件,这样就可以了解每项服务的状态。

  3. 在事故发生前的几周,我们启动了一项全公司范围的工程计划,通过多活设计让多个数据中心为 GitHub 流量提供支持。这个项目的目标是在设施层面支持 N+1 冗余,在不影响用户的情况下容忍单个数据中心故障。这是一项很重要的工作,需要一些时间。我们相信这种跨地理位置相连接的网站可以提供了一系列良好的权衡。这次事故加剧了这个项目紧迫性。

  4. 我们将在验证我们的假设方面采取更积极主动的立场。GitHub 是一家快速发展的公司,在过去十年中已经具备了一定程度的复杂性。随着公司不断的发展,捕捉和转移权衡和决策的历史负担将变得越来越困难。

组织举措

这次事故导致我们对站点可靠性的看法发生了转变。我们已经意识到,更严格的运维控制或改进的响应时间对于像我们这样复杂的服务系统的站点可靠性来说仍然是不够的。我们还将启动一种系统性实践,在故障场景有可能对用户产生影响之前对其进行验证,我们将在故障注入和混沌工程方面进行投入。

   结 论   

我们知道用户有多依赖 GitHub 给项目和企业带来成功。没有人比我们更关心服务的可用性和数据的正确性。我们将继续分析这次的事件,以便为用户提供更好的服务并赢得用户对我们的信任。

英文原文:

https://blog.github.com/2018-10-30-oct21-post-incident-analysis/

1.微信群:

添加小编微信:tangguoyemeng,备注“进群+姓名+公司职位”即可,加入【云计算学习交流群】,和志同道合的朋友们共同打卡学习!


2.征稿:

投稿邮箱:lijy@csdn.net;微信号:tangguoyemeng。请备注投稿+姓名+公司职位。


推荐阅读


  • 2018中国企业云计算应用现状及需求调研报告

  • 全面梳理百度世界大会,李彦宏又新吹了几个牛!

  • 腾讯将创办腾讯云启商学院,马化腾任荣誉院长

  • 扎堆出海的抖音、今日头条、UC 头条们后来怎么样了?

  • 创业者老板被程序员「割」了韭菜?

  • 唇语识别技术的开源教程,听不见声音我也能知道你说什么!

  • 月薪30k+项目分红,哥大教授带你探索“区块链+AI”,抓紧时间投简历吧!手慢无

  • 她说:真的,没事别嫁程序员


640?wx_fmt=jpeg


扫描以下二维码即可参与“2018 年 CSDN 软件开发者大调查活动”!我们还为你准备了精美的礼品,华为 nova3 智能手机、小爱智能音箱、CSDN 背包、CSDN 定制T恤、数百本技术图书等你来拿!参与即有机会获赠,还等什么,快来试试吧!

640?wx_fmt=jpeg


↓↓↓  点击【阅读原文】查看「CSDN云计算」往期精彩内容

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/525322.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

BugkuCTF-Crypto题MathEnglish

题目hint:口语需要读出来? 下载文件,打开 得到一些数字: 21 33 1 22 3 44 54 5 1 35 54 3 35 41 52 13 出题人给了hint2,让我们往元音上想 然后找到了一篇元音密码的文章 简单替换一下得到flag:bugku{yuanyinpwd}

Cloud一分钟|茅台4.5亿入股云上贵州大数据,后者已接管苹果中国iCloud; 阿里云进入印度市场,增长速度远超当地平均水平...

Hello,everyone:11月05日早,星期一,新的一天祝大家工作愉快!一分钟新闻时间:完1.微信群:添加小编微信:tangguoyemeng,备注“进群姓名公司职位”即可,加入【云…

BugkuCTF-WEB题文件包含

1.打开网页,点击click me? no链接 URL栏里显示:http://114.67.246.176:15077/index.php?fileshow.php,可能存在文件包含漏洞 这里介绍一下:php:// 协议 条件: allow_url_fopen:off/on allow_url_include :仅php:…

Python 进程池 multiprocessing.Pool - Python零基础入门教程

目录 一.Python 进程池 multiprocessing.Pool 介绍二.Python 进程池 multiprocessing.Pool 使用三.猜你喜欢 零基础 Python 学习路线推荐 : Python 学习目录 >> Python 基础入门 Python 进程池 Pool 和前面讲解的** Python 线程池** 类似,虽然使用多进程能提…

Cloud一分钟 | Facebook隐私泄露事件继续发酵,黑客明码标价出售聊天信息

Hello,everyone:11月06日早,星期二,新的一天祝大家工作愉快!一分钟新闻时间:完1.微信群:添加小编微信:tangguoyemeng,备注“进群姓名公司职位”即可,加入【云…

php:// 协议

这里介绍一下:php:// 协议 条件: allow_url_fopen:off/on allow_url_include :仅php://input php://stdin php://memory php://temp 需要on 作用: php:// 访问各个输入/输出流(I/O streams),在CTF里经常…

Python GIL 锁 - Python零基础入门教程

目录 一.并行和并发二.GIL 锁 案例一:单核多线程案例二:单核多线程案例三:双核多线程 三.如何解决 GIL 锁问题四.猜你喜欢 零基础 Python 学习路线推荐 : Python 学习目录 >> Python 基础入门 Python 中除了线程互斥锁 Lock 还有 GIL …

Facebook隐私泄露事件继续发酵,黑客明码标价出售聊天信息

2018年对于Facebook来说,是命运多舛的一年,此前曝光的隐私泄露事件如今又在持续发酵。据BBC近日报道,有黑客宣称其已经窃取1.2亿个Facebook用户账号的私人信息,并试图以每个账户10美分的价格在网站上出售,目前也公布了…

BugkuCTF-WEB题好像需要密码

一个五位数密码 老实说burp跑的话能跑一天 89999次 burp真的太慢了 这次用python脚本 顺便学一学requests库 输入密码,得到flag

为了释放AI在边缘计算的力量 英特尔又出手了

无论是现在还是未来,生活中AI的影子都无处不在,智能机器人会为你安排行程、提供可行性方案;智能医疗可以帮助人们提升医疗技术水平,改善就医条件和环境;在自然灾害发生时处理海量信息;购物认证时&#xff0…

Python print 函数- Python零基础入门教程

目录 一.Python print 函数简介二.Python print 函数语法三.Python print 函数使用 1.objects 参数2.sep 参数3.end 参数4.flush 参数 四.猜你喜欢 零基础 Python 学习路线推荐 : Python 学习目录 >> Python 基础入门 一.Python print 函数简介 Python 中内置函数我们使…

BugkuCTF-Crypto题python_jail

题目可通过nc远程连接 输入nc建立连接 测试发现最多只能输入10个字符,要想有输出,需要print() (7个字符) 若print(flag)则有11个字符,超出限制,报错 可利用python里help()函数,借报错信息带出f…

Python format 函数- Python零基础入门教程

目录 一.format 函数简介 1.format 函数不设置下标2.format 函数设置下标 二.format 函数实战三.猜你喜欢 零基础 Python 学习路线推荐 : Python 学习目录 >> Python 基础入门 一.format 函数简介 format 函数主要是用来构造字符串,基本语法是通过 {} 符号操…

Cloud一分钟 | 北京13部门召开座谈会,要求阿里京东等平台规范开展双11促销活动...

Hello,everyone:11月07日早,星期三,新的一天祝大家工作愉快!一分钟新闻时间:完1.微信群:添加小编微信:tangguoyemeng,备注“进群姓名公司职位”即可,加入【云…

BugkuCTF-Reverse题love

下载附件 先查壳 发现没加壳 再拖进 IDA 分析 按shiftF12查找字符串,可以看到如下 Base64 加密的痕迹,可判断基本是一个反解 flag 的题目 找到主函数按F5查看伪代码,如下: 可以发现这样的一个关键函数,也就是会将 …

技术争鸣!七大主题报告,四大技术专题,AI开发者大会首日议程全回顾

技术争鸣,座无虚席!11 月 8 日,北京诺金酒店,2018 AI开发者大会(AI NEXTCon)第一天议程圆满结束,这是值得铭记的一天。上午 9 点,由中国 IT 社区 CSDN 与硅谷 AI 社区 AICamp 联合出…

BugkuCTF-Reverse题Timer(阿里CTF)

知识点 JEB相当于Windows平台上的IDA smali代码:双击Bytecode,出现smali代码;相较于C之汇编,那么smali之于Java onCreate: 一个activity启动回调的第一个函数就是onCreate,这个函数主要做这个activity启动的一些需要的初始操作的工作。 onCreate之后调用了还有onRestart()和o…

大数据重新定义未来,2018 中国大数据技术大会(BDTC)豪华盛宴抢先看!

随着信息技术的迅猛发展,数据的重要性和价值已毋庸置疑,数据正在改变竞争格局,成为重要的生产要素,更被定义为“21世纪的新电力”。在信息高速传播的今天,数据已经渗透到每一个行业和业务职能领域,指数级的…

BugkuCTF-Reverse题signin

知识点 reverse() 功能:反转数组里的元素的顺序 语法:arrayobject.reverse.() 这类方法会改变原来的数组,不可逆转 tostring() 功能:将各类进制的数字转化为字符串 语法:number.toString(radix)(radix代表…

BugkuCTF-Reverse题SafeBox(NJCTF)

先下载软件,发现是个安卓的apk安装包,安装之后打开: 一、反编译查看源代码 只有一个输入框,其他的点不了。应该是要输入某个字符串然后判断是否正确,之后返回flag。 打开apk反编译: 两个类主要的差别就是…