image.png

本章将会探讨计算机网络的痼疾、时钟和时间、以什么程度避免上述问题等等。所有上述问题的原因都隐藏的很深,本章会探索如何理解分布式系统当前所处状态、如何定位分布式系统问题原因所在。

故障和部分失败

单机系统通常具有一种很好地特性:要么正常运行、要么出错崩溃,而不会处于一种中间状态。这也是计算机的最初设计目标:始终正确的进行计算。

但在构建分布式系统时,系统行为边界变得模糊起来。在分布式系统中,有很多我们习以为常的假设都不复存在,各种各样的异常问题都会出现。其中最令人难受的是:部分失败(partial failure),即系统的一部分正常工作,另一部分却以某种诡异的方式出错。这些问题,多数都是由于连接不同主机的异步网络所引入的。

因此,面向容错进行设计是对分布式系统软件的基本要求,为此,我们首先要了解分布式系统中的常见问题,并依此设计、编写、测试你的系统。

基于不可靠组件构建可靠系统

乍一看,这是违反直觉的:想要整个系统可靠,起码其组件得可靠吧。但在工程领域,这种思想并不鲜见。如:

  1. 纠错码能够容忍信道中偶尔一两个比特的误传。
  2. IP 层不可靠,但 TCP 层却基于 IP 层提供了相对可靠的传输保证。

不过,所有容错都是有限度的。如纠错码也没办法处理信号干扰造成的大量信息丢失,TCP 可以解决 IP 层的丢包、重复和乱序问题,但没办法对上层隐藏解决这些问题带来的通信时延。

不可靠的网络

背景

image.png

因此,在异步网络中,当你发送出一个请求,并在一段时间内没有收到应答,任何事情都有可能发生:由于没有收到任何信息,你无从得知具体原因是什么。甚至,你都不知道你的请求是否已被送达处理。

应对这种情况的惯常做法是——超时(timeout)。即,设定一个时限,到点后,我们便认为这个请求废了。但在实际上,该请求可能只是还在排队、可能稍后到到达远端节点、甚至可能最终还会收到应答。

故障检测

在很多系统里,我们需要自动检测故障节点,并据此做出一些决策: