本文出自《SRE:Google运维解密》,由Google资深SRE 孙宇聪 担任译者,首次深度剖析Google SRE。
Google Music——2012 年 3 月 :一次意外删除事故的检测过程 此事故特殊点在于,海量数据存储所带来的后勤方面的挑战:去哪里存放5000盘磁带,以及如何能够迅速地(甚至是可行的)从离线媒介中读出数据—— 而这一切还要发生在一个合理的时间范围内。
一个 Google Music 用户汇报某些之前播放正常的歌曲现在无法播放了。Google Music 的用户支持团队通知了工程师团队,这个问题被归类为流媒体播放问题进行调查。
3 月 7 日,负责调查此事的工程师发现无法播放的歌曲的元数据中缺少了一个针对具体音频数据文件的指针,于是他就修复了这个歌曲的问题。
但是,Google 工程师经常喜欢深究问题,也引以为豪,于是他就继续在系统中查找可能存在的问题。
当发现数据完整性损坏的真正原因时,他却差点吓出心脏病:这段数据是被某个保护隐私目的的数据删除流水线所删掉的。Google Music 的这个子系统的设计目标之一就是在尽可能短的时间内删除海量音频数据。
Google 的隐私策略强调保护用户的个人数据。在 Google Music 服务中,该隐私策略要求音乐文件,以及对应的元数据需要在用户删除它们之后在合理时间范围内在系统中彻 底删除。
随着 Google Music 使用量呈指数级增加,数据量也飞快地增长,以至于原始的 删除机制被抛弃了,在 2012 年进行了重新设计。
在 2 月 6 日那一天,更新过的数据删除流水线任务进行了一次运行,当时看起来没有任何问题,于是工程师批准了流水线任务的第二阶段执行——真正删除对应的音频数据。
然而,难道真的是这次删除任务造成的问题吗?该工程师立刻发出了一个最高级别的警报,同时通知了相关的工程师经理,以及SRE团队。
Google Music的开发者和SRE组建了一个小团队专门调查这个情况,同时该数据删除流水线也被暂时停止了,以防扩大 问题范围。
接下来,手动检查分散在多个数据中心内部的百万条,甚至数十亿条文件元数据信息是 不可能的。该团队匆忙编写了一个 MapReduce 任务来评估问题的影响范围,焦急地等待 着任务执行结果。
3 月 8 日,任务终于完成了,看到结果时所有人都惊呆了:该流水线任务大概误删除了 60 万条音频文件,大概影响了 2.1 万用户。由于这个匆忙编写的检测程序还简化了一些检测步骤,实际的问题只会更严重。
距离有问题数据删除流水线第一次运行已经超过一个月了,正是那次首次运行删除了几十万条不该删除的音频数据。
现在还有恢复数据的希望吗? 如果这些数据无法恢复,或者不能及时恢复,用户还会使用Google Music吗? 我们怎么能没有注意到这个问题的发生呢!
解决问题的第一步是定位真正的 Bug 根源,以便了解 Bug 产生的原因和过程。如果不修复根源的问题,任何数据恢复工作都是做无用功。
团队承受着来自用户压力要求我们重新启用数据删除流水线,而无辜用户将会继续丢失刚刚购买的音乐,甚至是他们自己辛苦录制的音乐。这个 22 条军规的场景的唯一出路, 就是修复根源问题,并且要快。
然而数据恢复流程也没有任何时间可以浪费。音频文件虽然备份到磁带上,但是和 Gmail 不同, Google Music 由于数据量太大,加密过的备份磁带是由卡车运往异地存放于独立的 存储设施中的——这些设施可以存放更多磁带。
为了能够更快地为受影响的用户恢复数据,团队决定在调查根源问题的同时并行进行异地备份磁带的恢复操作(这将耗时很长)。
工程师分为两组。经验最丰富的 SRE 负责数据恢复,同时开发者负责分析数据删除逻辑代码,试着修复根源问题。由于问题的根源尚不清晰,整个数据恢复过程会按数个阶段进行。
首先,第一批超过 50 万条音频数据被选中进行恢复,负责磁带备份系统的团队 在美国西海岸时间 3 月 8 日下午 4 :34 分收到了恢复通知。
整个事件中只有一个好消息 :公司组织的年度灾难恢复演习刚刚在几周前结束。磁带备份团队由于在 DiRT 演习中刚刚评估过子系统的能力和限制,刚刚制作了对应的数据恢复新工具。
利用这个新工具,新团队开始缓慢地首先将几十万条音 频文件和磁带备份系统中注册的备份文件一一对应,然后再将备份文件与具体的物理磁 带一一对应。
通过这个方法,团队评估得出第一批恢复过程需要将 5000 盘磁带用卡车全部运回来。并且之后数据中心的技术人员需要清理出足够场地来放置这些磁带。
接下来还要通过一个极为复杂和耗时的流程来从磁带上读取这些数据。同时,还要处理磁带损坏、磁带读取设备损坏,以及其他不可预料的问题。
更不幸的是,60 万条丢失数据中只有 436223 条数据存在备份,也就意味着其他 161000 条数据在备份之前就已经丢失了。数据恢复团队最后决定先启动恢复流程,再想办法如 何恢复这 161000 条无备份数据。
同时,负责调查根源问题的团队找到了一个潜在问题,结果却最终被证伪 :他们本以为 Google Music 的底层的数据存储服务提供了错误数据,以至于数据删除流水线删除了错误的数据。但是经过详细调查,这个可能性被排除了。这个团队只能继续寻找这个看起来好像不存在的 Bug。
· 第一批数据的恢复
数据恢复团队确认了备份磁带之后,第一批数据恢复在 3 月 8 日正 式开始了。从分布在异地离线存储设施中的几千个磁带中请求超过 1.5PB 的数据看起来很难,从这些磁带中真正读取数据就更难了。
Google 自己定制的磁带备份软件设计时没 有考虑过这么大的恢复任务,所以第一批数据的恢复过程被切分成 5475 个小任务。
如果由真人每分钟输入一条命令,光输入就需要超过三天的时间。人在这个过程中很可能还会引入很多错误。仅仅是这一点准备工作,就需要 SRE 写代码来完成。
在 3 月 9 日午夜的时候,SRE 终于将 5475 个恢复请求输入了系统中。磁带备份系统计 算了 4 个小时,得出 5337 盘磁带需要从异地存储设施中恢复。8 个小时后,一系列卡 车运载着这些磁带抵达了数据中心。
在卡车奔波在路上时,数据中心的技术人员清空了几个磁带管理库,撤下了几千个磁带以便给这次大型数据恢复工作让路。接下来,工作人员又开始一点一点手动将刚刚抵达的几千盘磁带装进磁带管理机中。
由过去的 DiRT 演习证明,这种手动装载的方式要比磁带管理机厂商提供的基于机器手臂模式的装载方式快很多。3 个多小时过后,磁带管理机终于恢复了运行,开始将几千个恢复任务逐渐写入分布式存储中。
虽然之前有 DiRT 的经验,1.5PB 的海量数据恢复还是比预计时间长了 2 天。到 3 月 10 日早晨,436223 个文件中只有 74% 的文件从 3475 个磁带上成功转移到了数据中心中的 分布式存储中。
其他 1862 个磁带在第一次运输中完全漏掉了。更糟的是,整个恢复过 程还被 17 个坏磁带拖慢了。由于已经预计到会有磁带损坏,写入时已经采用了带冗余的编码。于是还需要额外安排卡车去取回这些冗余磁带,一并再去取回第一次漏掉的 1862 盘磁带。
到 3 月 11 日早晨,超过 99.95% 的恢复任务已经完成了,剩余文件的冗余磁带的取回也在进行中。虽然数据已经安全地存到了分布式存储中,还有额外的数据恢复过程需要完 成,才能使用户真正可以访问。Google Music团队开始在数据的一小部分上进行数据恢复过程的最后步骤,同时不停校验结果以确保这个恢复过程仍然能够成功执行。
同时,Google Music生产系统的报警信息又来了,虽然与数据丢失不相关,但却是非常严重的用户直接可见的生产问题——该问题又消耗了恢复团队整整两天的时间。
在 3 月 13 日,数据恢复过程得以继续,最终 436223 条文件再一次可以被用户访问了。仅仅花了 7 天时间,我们恢复了 1.5PB 的用户数据,7 天之内的 5 天用于真正的数据恢复操作。
当第一批数据恢复过程结束之后,团队开始关注如何恢复剩下的 161000 条音频数据,这些数据在备份进行之前就被错误地删除了。这些文件中的大部分都是商店出售的,或者是推广性质的音频,原始文件都还存在。这些文件很快被恢复了。
但是,161000条中的一小部分是由用户上传的。Google Music团队发出了一条指令, 远程遥控这些受影响的用户的Google Music客户端软件自动重新上传3月14日之后的文件。整个过程持续了一周时间,最终全部数据恢复工作结束。
4. 解决根源问题
最终,Google Music团队找到了重构过的数据删除流水线中的Bug。为了更好地解释这个Bug,我们需要先了解大型离线数据处理系统的演变过程。
和针对一个包括很多子系统和存储服务的大型服务来说,彻底删除已经标记为删除的数据需要分多个阶段进行,每个阶段操作不同的数据存储服务。
为了使得数据操作服务更快地结束,整个过程可以并行运行在几万台机器上,这会给很多子系统造成很大压力。这种分布式操作会影响到用户,同时导致某些服务由于压力过 大而崩溃。
为了避免这些问题,云计算工程师通常会在第二阶段保存一些短期数据,用它们来进行数据存储。如果没有仔细调整过这些短期数据的生命周期,这个方法可能会引入数据竞争问题。
例如,该任务两个阶段被设计成为严格隔离的,运行时间相隔 3 个小时。这样第二阶段的代码可以大幅度简化某些逻辑,否则这个阶段的处理逻辑可能很难并行化。
但是随着数据量的增长,每个阶段需要更多时间才能完成。最终,当初设计时候的某些假设,在这个新条件下就不再成立了。
一开始,这种数据竞争问题可能只会影响到一小部分数据。但是随着数据数量的增加, 越来越多的数据可能会受到该数据竞争的影响。这种场景是随机化的——对绝大部分数据,绝大部分时间来说,整个流水线任务是正确的。
但是一旦发生数据竞争问题,错误的数据就会被删除掉。Google Music 的数据删除流水线任务设计时考虑了协调机制,并且加入了很多防错机制。
当整个流水线的第一阶段花费的时间越来越长时,工程师加入了很多性能优化以保障整个Google Music的隐私策略不受影响。
结果,这导致了这种数据竞争问题发生的概率的提升。当整个流水线任务重构时,这个概率被再次大幅提高了,直接导致了这个问题经常性的发生。
经历过这次数据恢复之后,Google Music团队重新设计了该流水线任务,彻底消除了这种数据竞争问题出现的可能性。
同时,我们增强了生产系统的监控和报警系统,使得它们可以提前检测类似的大规模删除问题,以便在用户发现之前检测和修复这类问题。