Post

DDIA笔记-第八章-分布式系统的麻烦

DDIA笔记-第八章-分布式系统的麻烦

高度总结

并没有太多需要总结出来的,偶尔回顾原文吧。

这一章都是举例和证明,分布式的世界是巨大的草台班子,

即使程序写得很好,依然会获得各种不确定的错误,

本章更多是纠正一个态度,当开发分布式系统时,需要考虑系统各部分出现不可靠的问题时,后果是什么?

要带着这样的心态去编码业务。

本章小结(抄写原文)

在本章中,我们讨论了分布式系统中可能发生的各种问题,包括:

  • 当你尝试通过网络发送数据包时,数据包可能会丢失或任意延迟。同样,答复可能会丢失或延迟,所以如果你没有得到答复,你不知道消息是否发送成功了。
  • 节点的时钟可能会与其他节点显著不同步(尽管你尽最大努力设置 NTP),它可能会突然跳转或跳回,依靠它是很危险的,因为你很可能没有好的方法来测量你的时钟的错误间隔。
  • 一个进程可能会在其执行的任何时候暂停一段相当长的时间(可能是因为停止所有处理的垃圾收集器),被其他节点宣告死亡,然后再次复活,却没有意识到它被暂停了。

这类 部分失效(partial failure) 可能发生的事实是分布式系统的决定性特征。每当软件试图做任何涉及其他节点的事情时,偶尔就有可能会失败,或者随机变慢,或者根本没有响应(最终超时)。在分布式系统中,我们试图在软件中建立 部分失效 的容错机制,这样整个系统在即使某些组成部分被破坏的情况下,也可以继续运行。

为了容忍错误,第一步是 检测 它们,但即使这样也很难。大多数系统没有检测节点是否发生故障的准确机制,所以大多数分布式算法依靠 超时 来确定远程节点是否仍然可用。但是,超时无法区分网络失效和节点失效,并且可变的网络延迟有时会导致节点被错误地怀疑发生故障。此外,有时一个节点可能处于降级状态:例如,由于驱动程序错误,千兆网卡可能突然下降到 1 Kb/s 的吞吐量【94】。这样一个 “跛行” 而不是死掉的节点可能比一个干净的失效节点更难处理。

一旦检测到故障,使系统容忍它也并不容易:没有全局变量,没有共享内存,没有共同的知识,或机器之间任何其他种类的共享状态。节点甚至不能就现在是什么时间达成一致,就不用说更深奥的了。信息从一个节点流向另一个节点的唯一方法是通过不可靠的网络发送信息。重大决策不能由一个节点安全地完成,因此我们需要一个能从其他节点获得帮助的协议,并争取达到法定人数以达成一致。

如果你习惯于在理想化的数学完美的单机环境(同一个操作总能确定地返回相同的结果)中编写软件,那么转向分布式系统的凌乱的物理现实可能会有些令人震惊。相反,如果能够在单台计算机上解决一个问题,那么分布式系统工程师通常会认为这个问题是平凡的【5】,现在单个计算机确实可以做很多事情【95】。如果你可以避免打开潘多拉的盒子,把东西放在一台机器上,那么通常是值得的。

但是,正如在 第二部分 的介绍中所讨论的那样,可伸缩性并不是使用分布式系统的唯一原因。容错和低延迟(通过将数据放置在距离用户较近的地方)是同等重要的目标,而这些不能用单个节点实现。

在本章中,我们也转换了几次话题,探讨了网络、时钟和进程的不可靠性是否是不可避免的自然规律。我们看到这并不是:有可能给网络提供硬实时的响应保证和有限的延迟,但是这样做非常昂贵,且导致硬件资源的利用率降低。大多数非安全关键系统会选择 便宜而不可靠 ,而不是 昂贵和可靠

我们还谈到了超级计算机,它们采用可靠的组件,因此当组件发生故障时必须完全停止并重新启动。相比之下,分布式系统可以永久运行而不会在服务层面中断,因为所有的错误和维护都可以在节点级别进行处理 —— 至少在理论上是如此。(实际上,如果一个错误的配置变更被应用到所有的节点,仍然会使分布式系统瘫痪)。

本章一直在讲存在的问题,给我们展现了一幅黯淡的前景。在 下一章 中,我们将继续讨论解决方案,并讨论一些旨在解决分布式系统中所有问题的算法。

This post is licensed under CC BY 4.0 by the author.