Twitter 是如何落地故障测试的

原文:blog.twitter.com/engineering...

作者:Mazdak Hashemi

当你在 Twitter 这样规模的基础架构上运行时,硬件和网络故障变得不可避免。每一个故障都有可能对用户体验产生负面影响,因此我们设计系统时要尽可能地使其对故障具有弹性。

为了测试我们的服务对意外故障的反应,我们创建了一个框架,可以向 Twitter 基础架构注入受控故障条件。这使我们能够发现漏洞,以便更好地准备处理整个站点的事件。通过在我们自己的系统中引发故障,我们能够构建更具弹性的服务。

框架

我们的框架由一个 Python 库和一个命令行可执行文件组成,旨在直接向生产基础架构引入故障条件、监控整个站点的健康指标,并在测试过程中向系统发送状态更新。它提供了灵活的、基于 YAML 的配置语法,并且可以通过模块化设计轻松地扩展额外功能。

该框架包括三种模块类型:

  • 淘气模块在生产服务和基础设施中引入和逆转故障条件。
  • 监控模块旨在检查 Twitter 服务的健康指标来源,寻找可能导致整个站点事件的状态。如果检测到至少一个这些状态,框架将立即逆转已引入的故障条件。
  • 通知器模块旨在与 HipChat 和 JIRA 等系统进行接口,以在故障测试执行过程中提供实时状态更新。

在 Twitter 基础架构中进行故障测试的目标是通过查询 Twitter 的资产清单数据库来选择的,该数据库是所有数据中心硬件和相关属性信息的来源。该框架结合了这些查询,允许针对支持单个 Twitter 服务的机器(如果在我们的内部云上运行)或机器角色精确定位测试。

目前,该框架支持引入以下故障条件:

  • 通过向 IPMI 控制器和 PDUs 发送命令来断电
  • Mesos 中运行的 Twitter 服务群集的部分到全部丢失
  • 通过推送包含交换机端口故障、部分数据包丢失、拒绝所有 IP 流量、所有流量到一个或多个 TCP/UDP 端口等的新交换机配置来丢失网络

为了演示工程师如何使用框架测试故障条件,以下是一个配置示例,将在 rack abc 中的所有 Hadoop DataNode 上引入 30 分钟的断电故障,监控测试执行期间的健康指标,并向聊天室发送状态更新:

yaml 复制代码
failure_test:
  name: Power loss within rack abc in datacenter abcd
  duration_mins: 30
  mischief:
    - power_loss:
        datacenter: abcd
        selectors:
          - group:
              type: role
              name: hadoop.datanode
          - group:
              type: rack
              name: abc
  notifiers:
    - chat:
        rooms:
          - Failure Testing
  monitors:
    - observability:
        datacenter: abcd
  queries: !snippet

将此配置传递给框架的命令行工具后,它将收集引入故障条件所需的所有信息,例如目标机器主机名和其 IPMI BMC 接口的地址。如果这个淘气准备步骤成功,框架将通过检查配置的监控确保所有测试系统处于健康状态。然后,它将尝试引入请求的故障条件。如果成功引入这些条件,框架将暂停配置的测试时间长度,以分钟为单位检查配置的监控,以确保所有监控在测试期间保持健康状态。

如果任何监控检测到不健康的基础架构条件,框架将认为故障测试失败。否则,如果监控在整个测试期间报告健康条件,框架将认为测试成功。在这两种情况下,框架将立即逆转所有引入的故障条件,终止测试。

测试过程的可视化:

挑战

由于我们在 Twitter 上运行的基础架构是异构的动态基础架构,因此引入针对特定服务的故障条件需要仔细设计和规划。托管在 Apache Aurora 中的服务与直接在硬件上运行的服务不同,因为它们是动态调度的。

为了确定意外服务行为的根本原因,我们需要捕获完整的测试环境,其中可能包括机架配置文件、服务类型、服务多样性统计数据、流量量等。在某些情况下,我们检测到的异常只是上游或下游问题的副作用,或者是服务的恢复行为。

使用和经验教训

这个框架在过去六个月启动了 Twitter 上所有的故障测试,并帮助我们发现了我们堆栈中的许多漏洞。此外,它还让我们对 Apache Mesos 和 Apache Aurora 等几个主要系统的故障弹性产生了信心,在这些系统中,我们测试了大规模的故障,但没有对用户造成影响。 在我们基础设施中常见的一个故障情况示例是顶部机架(TOR)交换机出现问题。当出现这种情况时,运行在这个机架内的服务将经历整个网络丢失或部分数据包丢失。我们发现,我们的服务很好地处理了完全网络丢失的情况,而部分数据包丢失几乎总会导致一些内部影响。我们还发现,这种影响的严重程度取决于机架配置文件和在该机架上运行的 Mesos 从属服务的服务类型。

该框架能够确定 Twitter 服务如何在各种常见的硬件故障场景下做出响应,为站点可靠性工程师提供了大量的实际数据。这些数据大多围绕着在面对故障条件时,由强大的 Finagle 库调解的服务间 RPCs 的行为。

Finagle 为所有服务间 RPCs 赋予了逻辑,以确保每个 RPC 尽可能顺利地进行;然而,为了充分利用这种逻辑,下游服务客户端需要正确调整请求超时和重试值。通过使用框架故障测试产生的数据,我们的工程师可以提供调整值和优雅降级逻辑,这可以更好地维持 SLAs 并防止用户面临的事件。

未来的工作

当然,我们将继续测试我们的基础设施抵御随机故障的能力。这个框架已经用于驱动探索性的故障测试,帮助我们找到并推动 Twitter 基础架构的极限。随着我们未来几个月故障测试计划范围的扩大,该框架将在工作时间内持续运行。通过这样做,该框架将帮助我们确保我们对硬件故障条件的弹性不会从已反复证明的情况中退化。此外,我们正在研究在我们可扩展的 RPC 系统 Finagle 的层面注入故障条件。

通过向 Twitter 基础架构注入受控故障条件,我们可以确保我们的系统在生产中更好地容忍意外故障。这使我们能够编写更能承受故障并在需要时优雅降级的服务。最终,通过运行这些测试,我们能够找到并解决基础架构中的这些漏洞。

如果故障和可靠性测试听起来像是一个有趣的挑战,我们可以用得上您的帮助 --- 加入我们吧!

相关推荐
前端李易安2 小时前
Web常见的攻击方式及防御方法
前端
PythonFun2 小时前
Python技巧:如何避免数据输入类型错误
前端·python
hakesashou2 小时前
python交互式命令时如何清除
java·前端·python
天涯学馆2 小时前
Next.js与NextAuth:身份验证实践
前端·javascript·next.js
HEX9CF2 小时前
【CTF Web】Pikachu xss之href输出 Writeup(GET请求+反射型XSS+javascript:伪协议绕过)
开发语言·前端·javascript·安全·网络安全·ecmascript·xss
ConardLi2 小时前
Chrome:新的滚动捕捉事件助你实现更丝滑的动画效果!
前端·javascript·浏览器
ConardLi3 小时前
安全赋值运算符,新的 JavaScript 提案让你告别 trycatch !
前端·javascript
凌云行者3 小时前
使用rust写一个Web服务器——单线程版本
服务器·前端·rust
华农第一蒟蒻3 小时前
Java中JWT(JSON Web Token)的运用
java·前端·spring boot·json·token
积水成江3 小时前
关于Generator,async 和 await的介绍
前端·javascript·vue.js