前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >又挂了!聊聊分布式系统级联故障

又挂了!聊聊分布式系统级联故障

作者头像
Java阿呆
发布2022-04-15 08:28:37
1.3K0
发布2022-04-15 08:28:37
举报
文章被收录于专栏:Java阿呆Java阿呆

大家好,我是阿呆,一个不务正业的程序员。

公司的系统又又又挂了!年终奖彻底没戏了。

回顾公司过去一年,发生了好几次P级事务,最严重的一次对外停止服务整整一下午,超过六小时。

据了解,大部分都是由于某一个服务的某一个节点挂掉,引发连锁反应,最终导致集体宕机。

我们今天就来聊一聊,为什么会出现这种连锁反应,也就是级联故障,发生故障的时候如何处理,以及如何来避免这种故障的发生。

因为现在公司级的服务基本都是分布式部署了,所以我们今天的讨论是基于分布式系统展开的。

级联故障

我们先来看看级联故障是什么。

级联故障是由于正反馈循环并且随时间的增加所产生的故障。典型的表现就是最初由单个节点或子系统故障触发连锁反应。

单节点故障后,将会把负载分散到系统剩余的节点上,从而进一步增加了系统故障的可能性,进而导致恶性循环或滚雪球效应。

级联故障主要有三个特征:

1、可以在短时间内关闭整个服务。 2、受影响的系统不会像处理更常见的问题那样恢复正常,而是会逐渐恶化,最终导致依赖于人为干预。 3、在最坏的情况下,级联故障可能会在没有警告的情况下突然发生,因为负载分布和故障会迅速发生。

尽管文章讨论的是分布式计算系统中的级联故障,但这种故障也可能发生在各种其他领域:例如电力传输、金融、生物学以及生态系统。因此,它们是一种相当普遍的现象。为了更好地了解计算机科学中的级联故障是什么样的,我们来看一个具体的案例。

真实案例:2015 年的AWS DynamoDB中断

AWS DynamoDB是一种高度可扩展的非关系型数据库服务,分布在多个数据中心,提供高度一致的读取操作和 ACID 事务。它被NetflixAirbnbIMDb等流行的互联网服务所使用。这个案例的事件发生在 2015 年 9 月 20 日,当时DynamoDB在美国东部地区超过四个小时不可用。涉及两个子系统:存储服务器和元数据服务。两者都跨多个数据中心复制。如下图所示。

存储服务器和元数据服务

存储服务器会向元数据服务请求数据,并且必须等待请求成功,同时存在超时机制。如果超时,相应的存储服务器会重试并将其自身排除在服务之外。

正好DynamoDB在当时刚引入了一个新的功能,称为全球二级索引(GSI)。为了让客户可以更好地访问他们的数据,但缺点是会显著增加元数据表的大小。因此,处理时间要长得多。对于元数据服务数据量的增长和请求的大量超时,没有做出相应的调整。

这场灾难真正始于一个短暂的网络问题,导致一些处理非常大的元数据表的存储服务器,没有收到他们的请求成功响应。导致这些服务器变得不可用并不断重试请求。这给元数据服务带来很大的压力甚至超载,进而减慢响应速度,并导致更多服务器请求超时重试。结果,元数据服务的状态进一步恶化。尽管多次尝试增加资源,系统仍然陷入故障循环数小时。最终,只能通过中断对元数据服务的请求来解决问题,即服务基本下线。

结果是美国东部地区发生了大面积的DynamoDB服务中断。

级联故障的原因

可能导致级联故障的触发点有很多,最终可能导致的情况包括服务器过载、资源耗尽和服务不可用。

服务器过载

最常见的原因是服务器过载。发生这种情况时,系统性能下降通常会影响到系统的其他部分。如下图所示,在初始场景(左)中,通过两个反向代理将负载分布在集群 A 和 B 之间,假设此时集群 A 以最大每秒 1000 个请求的容量运行。在第二种情况(右)中,集群 B 发生故障,所有流量都打到集群 A,这就可能导致过载。集群 A 现在必须每秒处理 1200 个请求并开始出现异常行为,导致性能远远低于每秒 1000 个请求。

集群 A 和 B 根据容量(左)接收负载,如果集群 B 发生故障,集群 A 接收过载(右)

资源耗尽

服务器的资源是有限的。如果负载到达某个阈值以上,服务器的性能指标(例如延迟或错误率)就会恶化。这意味着更高的崩溃风险。随后一些资源类型到达瓶颈,导致异常发生,例如,

  • 如果CPU不足,可能会出现各种问题,包括请求速度较慢、排队效应过多或线程不足。
  • 如果内存/ RAM被过度使用,任务可能会崩溃,或者缓存命中率会降低。
  • 此外,线程饥饿可能直接导致错误或导致健康检查失败。

在这种情况下进行故障排除通常很痛苦。因为所涉及的组件是相互依赖的,并且根本原因可能隐藏在复杂的事件链之后。例如,假设可用于缓存的内存较少,导致缓存命中次数减少,因此后端负载较高,以及此类组合。

服务不可用

当资源耗尽导致服务器崩溃时,流量会传播到其他服务器,从而增加这些服务器也崩溃的可能性。但是这些问题仍然存在于系统中,因为某些机器仍然处于关闭状态或正在重新启动的过程中,而增加的流量会阻止它们完全恢复。

一般来说,当我们将流量从不健康节点重新分配到健康节点时,总是存在级联故障的风险。这可能是编排系统、负载平衡器或任务调度系统的情况。为了解决级联故障,我们需要仔细研究所涉及的组件之间的关系。

跳出循环——如何修复级联故障

从DynamoDB的案例中可以看出,修复级联故障非常棘手。尤其是从大型科技公司的角度来看,负载均衡会给系统增加很多复杂性,这使得跟踪各种依赖变得更加困难。

这里说明(级联)关系的一种基本方法是所谓的因果循环图(CLD)。CLD 是一种建模方法,有助于可视化复杂系统中的反馈回路。下图CLD可视化了AWS DynamoDB的停电。

箭头表示初始变量和后续变量之间的动态。例如,如果元数据服务的延迟增加,超时次数就会增加,所需的重试次数也会增加。如果系统中的效应是高度不平衡的,即正负数相差很大,则存在增强循环。这意味着系统可能对级联故障很敏感。

2015 年 AWS DynamoDB 中断的因果循环图

现在,为了解决级联场景,可以采取各种措施。第一个也是最直观的选择是增加资源。在上图中,可以看到最上方的一个减号,代表增加元数据服务,然而,这可能没有用,正如我们在AWS中看到的那样。除了增加资源外,您可能还需要采用其他策略:

  • 尽量避免健康检查失败/死亡,以防止系统因过度健康检查而死亡。
  • 如果出现线程阻塞请求或死锁,请重新启动服务器。
  • 显着降低流量,然后慢慢增加负载,以便服务器可以逐渐恢复。
  • 通过丢弃某些类型的流量切换到降级模式。
  • 消除批处理/不良流量,以减少由于非关键或错误工作导致的系统负载。

由于这最终意味着系统的某些部分不可用并且对客户可见,因此最好首先避免级联故障。

避免级联故障

有许多方法可以使分布式系统对级联故障具有鲁棒性。

一方面,大型互联网公司已经在思考如何防止系统陷入错误的级联,例如通过错误的隔离。并为此开发了工具和框架。例如是Hystrix(来自Netflix),一个延迟和容错库,或者Sentinel。关于前者,Netflix已经做出了进一步的发展,即自适应 并发 限制。但总的来说,这些工具将外部调用包装成某种数据结构,试图抽象出关键点。

另一方面,还有更复杂的解决方案,例如所谓的侧车 代理的实现,例如,像istio这样的服务网格。还有一些技术例如EnvoyHaproxy

除了这些解决方案之外,还要牢记某些系统设计概念。例如,尝试减少系统中同步调用的数量。这可以通过应用发布-订阅 模式设计(例如,使用 Kafka)来完成。面对不断增加的流量,这种解决方案通常会变得更加强大。其他方法,例如执行容量规划(取决于用例)也可能有所帮助。这通常意味着实施自动供应和部署、自动扩展和自动修复的解决方案。在这种情况下,对 SLA 和 SLO 进行密切监控很重要。

结论

级联故障是分布式系统中一种可怕的同时又是特殊的现象。这是因为有时必须采取违反直觉的路径来避免它们,例如,实际上旨在减少错误的定制,例如看似智能的负载平衡,可能会增加完全失败的风险。有时,最好只向您的客户显示一条错误消息,而不是实施复杂的重试逻辑并冒着 DDoS 攻击您自己的系统的风险。然而,这里经常不得不做出妥协。测试、容量规划和在系统设计中应用某些模式有助于提高系统的弹性。

毕竟,大型科技公司的经验教训和事后分析为进一步采取行动以避免未来出现连锁故障提供了很好的指导。但是,也值得关注最新的炒作和趋势。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2022-04-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Coder阿呆 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 级联故障
  • 真实案例:2015 年的AWS DynamoDB中断
  • 级联故障的原因
    • 服务器过载
      • 资源耗尽
        • 服务不可用
        • 跳出循环——如何修复级联故障
        • 避免级联故障
        • 结论
        相关产品与服务
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档