论文地址:大型系统软件部分故障的理解、检测与定位 Lou et al., NSDI’20

    部分故障(灰色故障)是指当系统的某些功能(但不是全部)被破坏时发生的故障。表面上一切看起来都很好,但在表面下,事情可能会出现大规模错误。

    当发生部分故障时,通常需要很长时间才能检测到事件。与此相反,一个遭受完全故障的进程可以被现有机制快速识别、重新启动或修复,从而限制故障影响。

    因为表面上一切看起来都很好,传统的故障检测器或使用外部探针或监控统计的watchdog可能无法发现问题。今天的论文选择在NSDI’20为作者赢得了最佳论文奖。它包含对部分故障原因的研究,以及使用系统特定的、自动生成的watchdog进行故障检测的新方法。

    部分故障特征
    在设计一个更好的检测部分故障的系统之前,作者通过对五个软件系统(ZooKeeper、Cassandra、HDFS、Apache和Mesos)的研究,开始了解它们的性质和原因。对于这些系统中的每一个,他们都会对bug数据库进行爬网以找到关键问题,然后从这些问题中随机抽取样本,直到收集到每个系统的20个真正的部分故障案例。

    omegagen-table-1.jpeg

    以下是主要发现:

    • 在每个系统的发布历史中都会出现部分故障,在过去的三年中有54%。

    • 部分故障的原因是多种多样的,其中未发现的错误、不确定阻塞和错误错误错误占据前三位,占它们之间所有部分故障的48%。(另请参见:“简单的测试可以防止大多数生产故障”和“哪些错误导致云生产事件?’.

    omegagen-fig-2.jpeg

    • 48%的部分故障导致系统的某些部分无法取得进展(“卡住”)。还有17%的部分表现出速度非常慢,速度慢到足以成为一个严重的问题。

    omegagen-fig-3.jpeg

    • 在13%的情况下,一个模块变成了一个具有未定义故障语义的僵尸
    • 15%的部分故障案例是无声的(例如数据丢失、损坏、不一致、错误的结果)
    • 71%的故障是由特定的环境条件、输入或其他进程中的故障触发的。
    • 大部分(61%)的部分故障是粘性的,即除非进行某些干预(如重新启动),否则流程将无法恢复。
    • 诊断这些问题的平均时间为6天5小时。

    总的来说,我们的研究揭示了在大型软件系统中,部分失效是一个普遍而严重的问题。研究的大多数故障都依赖于生产,这需要运行时机制来检测。

    使用自定义看门狗程序检测部分故障
    所以,我们知道我们需要运行时检测器。这里的做法是基于API的健康检查。最先进的是全景。

    从业者通常依赖于运行特别的健康检查(例如,每隔几秒钟发送一个HTTP请求并检查其响应状态)。但这样的健康检查太肤浅,不能暴露出一大类的失败。该领域的最新研究工作是全景图,它将目标进程的各种请求者转换为观察者来报告该进程的灰色失败。这种方法受到请求者可以从外部观察到的东西的限制…

    为了暴露部分故障,检测器需要使用精心选择的有效负载来执行特定的代码区域。Heartbeat和基于HTTP的测试过于通用,与被监视进程的状态脱离得太远。因此,作者采取的方法是使用内部监视程序——这些监视程序与同一进程中的主程序同时运行。为了尽可能接近真实的程序执行条件,OmegaGen在代码库中找到长时间运行的方法,提取它们潜在的易受攻击的操作,并将结果打包到自定义生成的监视程序(“模拟样式的检查程序”)中。它捕获主程序的运行时执行上下文,并将其作为输入复制到看门狗,然后在沙盒环境中执行。

    生成监视程序,如下所示:

    • 第一个OmegaGen标识长时间运行的方法(例如while(true)或while(flag))
    • 然后,OmegaGen在这些长时间运行的方法的控制流中寻找潜在的易受攻击的操作。这在很大程度上是基于启发式的(同步、资源分配、事件轮询、异步等待、使用外部参数的调用、文件或网络I/O、复杂的while循环条件等等)。开发人员还可以显式地将操作注释为@vulnerable
    • 然后创建主程序的看门狗副本,从长时间运行的方法的入口点开始自上而下地还原程序,只保留每个还原方法中的易受攻击的操作。生成的程序保留原始结构,并包含所有易受攻击的操作。
    • 然后,OmegaGen插入钩子,钩子从主程序执行中捕获上下文并将其传递给看门狗,以便看门狗以与原始程序相同的键状态执行。
    • 最后,OmegaGen在watchdog中添加了检查,以捕获执行易受攻击操作时的失败信号。通过在运行检查器之前设置计时器(默认为4秒)进行活性检查。安全检查依赖于易受攻击的操作来发出显式错误信号(例如异常),并且还将捕获运行时错误。

    omegagen-fig-5.jpeg

    看门狗驱动程序运行看门狗并捕获有关任何检测到的错误的信息。在报告错误之前,验证程序将运行以确保它是真正的错误。默认验证程序只需重新执行检查程序并比较结果,这在出现暂时性错误时是有效的。如果需要,开发人员可以提供自己的验证器函数。

    总之,OmegaGen大约是8Kloc的Java代码,使用了Soot分析框架

    OmegaGen起到的作用
    OmegaGen使用ZooKeeper、Cassandra、HDFS、HBase、MapReduce和Yarn进行评估。它为每个系统生成10到100秒的看门狗,配置为每秒运行一次检查。根据系统的大小,生成看门狗需要5到17分钟。

    omegagen-table-1.jpeg

    然后,收集并再现了这六个系统中的22个实际部分故障。OmegaGen检测这些故障的能力随后在四个不同的基线检测器上进行了测试,如下表所示(现有的系统内置检测器根本无法处理部分故障)。

    omegagen-table-4.jpeg

    OmageGen监视程序检测到22个问题中的20个,而最好的基线检测器只处理了11个,其他三个检测器加起来只能处理14个。中位检测时间为4.2秒。
    omegagen-table-5.jpeg

    OmegaGen看门狗还能够比基线检测器更准确地确定错误的来源(例如,客户端和资源检测器只能指向错误的进程)。

    omegagen-table-6.jpeg

    最新版本ZooKeeper的随机故障注入测试触发了16个合成故障,其中13个被检测到,检测时间中值为6.1秒。OmegaGen的看门狗也在ZooKeeper的3.5.5版本中发现了一个真正的bug,开发者确认并修复了这个bug。

    OmegaGen看门狗在系统吞吐量方面增加了5.0-6.6%的开销。

    最终结论
    在六个大型系统上评估OmegaGen,它可以为每个系统生成数十到数百个定制的看门狗。生成的看门狗检测22个真实世界的部分故障中的20个,检测时间的中位数为4.2秒,并为18个案例确定故障范围;这些结果明显优于基线检测器。