Update ch08.md

remove redundant *
This commit is contained in:
muniao 2023-01-08 15:54:54 +08:00 committed by GitHub
parent ade42f7223
commit 157a484ce1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

16
ch08.md
View File

@ -154,13 +154,13 @@
**静态设置**。在这种环境中,如果你要为远端故障检测设置超时时间,就只能使用做实验的方式,经过足够长的时间,统计请求延迟分布。进而结合应用需求,在**检测过久**(设置长超时间隔)和**故障误报**(设置过短超时间隔)做一个权衡。
**动态调整**。当然, 相比预先配置固定死超时间隔,更好的方式是,通过类似时间窗口的方式,不断监测过去一段时间内的**请求时延**和**抖动情况**,来获取请求时延的分布情况,进而动态调整超时间隔。 **Phi 累积故障检测算法** The Φ Accrual Failure Detector****便是这样一种算法Akka and Cassandra 中都用到了此种算法,它的工作原理和 TCP 重传间隔的动态调整类似。
**动态调整**。当然, 相比预先配置固定死超时间隔,更好的方式是,通过类似时间窗口的方式,不断监测过去一段时间内的**请求时延**和**抖动情况**,来获取请求时延的分布情况,进而动态调整超时间隔。 **Phi 累积故障检测算法** The Φ Accrual Failure Detector便是这样一种算法Akka and Cassandra 中都用到了此种算法,它的工作原理和 TCP 重传间隔的动态调整类似。
## 同步网络和异步网络
如果我们的底层网络传输数据包时能够保证延迟上界、且不会丢包,那么基于此构建分布式系统将会容易的多。那为什么不在硬件层面解决相关问题让网络更可靠,从而让分布式软件免于关心这些复杂的细节呢?
为了回答这个问题,我们先来看一种历史产物——**固定电话网***fixed-line telephone network*非 VOIP、非蜂窝网络。在固话线路中高延迟音频帧和意外断线都是非常罕见的。固话网会为每一次通话预留**稳定低延迟**和**充足的带宽**链路以传输语音。如果计算机网络中也采用类似的技术,生活不会很美好吗?
为了回答这个问题,我们先来看一种历史产物——**固定电话网***fixed-line telephone network* ,非 VOIP、非蜂窝网络。在固话线路中高延迟音频帧和意外断线都是非常罕见的。固话网会为每一次通话预留**稳定低延迟**和**充足的带宽**链路以传输语音。如果计算机网络中也采用类似的技术,生活不会很美好吗?
当你在固网内拨打电话时,会建立一条贯穿贯穿全链路的保证足量带宽的固定链路,我们称之为**电路**circuit该电路会保持到通话结束才释放。以 ISDN 网络为例,其每秒能容纳 4000 帧语音信号,当发起通话时,它会在每个方向为每帧数据分配 16 比特空间。因此,在整个通话期间,两端各自允许每 250 微秒250us * 4000 = 1s发送 16 比特语音数据。
@ -175,7 +175,7 @@
应用层给到 TCP 的任意大小的数据,都会在尽可能短的时间内被发送给对端。如果一个 TCP 连接暂时空闲,则他不会占用任何网络带宽。相比之下,在打电话时即使不说话,电路所占带宽也得一直被预留。
如果数据中心和互联网使用**电路交换***circuit-switched*)网络,他们应该能够建立一条保证稳定最大延迟的数据链路。但是事实上,由于以太网和 IP 网采用**封包交换**协议(*packet-switched protocols*常翻译为**分组交换**,但我老感觉它不太直观),没有电路的概念,只能在数据包传送的时候对其进行排队,也不得不忍受由此带来的无界延迟。
如果数据中心和互联网使用**电路交换***circuit-switched*)网络,他们应该能够建立一条保证稳定最大延迟的数据链路。但是事实上,由于以太网和 IP 网采用**封包交换**协议(*packet-switched protocols* ,常翻译为**分组交换**,但我老感觉它不太直观),没有电路的概念,只能在数据包传送的时候对其进行排队,也不得不忍受由此带来的无界延迟。
那为什么数据中心网络和互联网要使用封包交换协议呢?答曰,为了应对互联网中无处不在的**突发流量***bursty traffic*)。在电话电路中,音频传输所需带宽是固定的;但在互联网中,各种多媒体数据(如电子邮件、网页、文件)所需带宽却是差异极大且动态变化的,我们对他们的唯一要求就是传地尽可能快。
@ -183,7 +183,7 @@
不过,也有一些尝试来建立同时支持电路交换和封包交换的网络,如 ATM。**IB 网络**InfiniBand与 ATM 有一些类似之处它在链路层实现了端到端的流量控制从而减少了排队。具体来说IB 使用 **QoS **quality of service对数据包区分优先级并进行调度控制和**准入控制**admission control对发送方进行速率控制在封包网络上模拟电路交换或者提供概率意义上的有界时延。
但,现有的数据中心网络和互联网都不支持 QoS。因此我们在设计分布式系统时不能对网络传输的时延和稳定性有任何假设。我们必须要假定我们面对的网络会发生网络拥塞、会产生排队、会有无界延迟在这种情况下没有放之四海而皆准的**超时间隔**针对不同的具体情况,需要通过经验或者实验来确定它。
但,现有的数据中心网络和互联网都不支持 QoS。因此我们在设计分布式系统时不能对网络传输的时延和稳定性有任何假设。我们必须要假定我们面对的网络会发生网络拥塞、会产生排队、会有无界延迟在这种情况下没有放之四海而皆准的**超时间隔**针对不同的具体情况,需要通过经验或者实验来确定它。
> **通信时延和资源利用**
>
@ -211,7 +211,7 @@
7. 该缓存条目何时超时?
8. 日志中这条错误消息的时间戳是什么?
例子 1~4 测量的是**时间间隔**durations例子 5~8 描述的是**时间点**points in time。在分布式系统中时间是一个棘手的问题。因为两个机器间的通信不是瞬时完成的虽然我们知道一条消息的接收时间一定小于发送时间但由于**通信延迟的不确定性**,我们无法知道具体晚了多久。因此,发生在分布式系统内多个机器的事件,很难准确地确定其先后顺序。
例子 1-4 测量的是**时间间隔**durations例子 5-8 描述的是**时间点**points in time。在分布式系统中时间是一个棘手的问题。因为两个机器间的通信不是瞬时完成的虽然我们知道一条消息的接收时间一定小于发送时间但由于**通信延迟的不确定性**,我们无法知道具体晚了多久。因此,发生在分布式系统内多个机器的事件,很难准确地确定其先后顺序。
更进一步,网络中的每个机器都有自己的系统时钟,通常是用**石英振荡器**做成的特殊硬件计时的,并且通常是独立供电的,即使系统宕机、断电也能持续运转。但这种时钟通常不是非常准确,即有的机器可能走的稍微快一些,有的可能就慢一些。因此,实践中,常通过 **NTP**(网络时间协议)对机器进行自动校准。其大致原理是,首先使用更精确时钟(如 GPS 接收器)构建一组**可信服务器**作为时钟源(比如阿里云的源),然后再利用这组服务器通过网络校准其他机器。
@ -311,7 +311,7 @@
但不幸,大多数服务器的时钟系统 API 在给出时间点时,并不会一并给出对应的不确定区间。例如,你使用 `clock_gettime()` 系统调用获取时间戳时,返回值并不包括其置信区间,因此你无法知道这个时间点的误差是 5 毫秒还是 5 年。
一个有趣的反例是谷歌在 Spanner 系统中使用的 *TrueTime* API会显式的给出置信区间。当你向 TrueTime 系统询问当前时钟时,会得到两个值,或者说一个区间:`[*earliest*, *latest*]`,前者是最早可能的时间戳。后者是最迟可能的时间错。通过该不确定预估,我们可以确定准确时间点就在该时钟范围内。此时,区间的大小取决于,上一次同步过后本地石英钟的漂移多少。
一个有趣的反例是谷歌在 Spanner 系统中使用的 *TrueTime* API会显式的给出置信区间。当你向 TrueTime 系统询问当前时钟时,会得到两个值,或者说一个区间:`[earliest, latest]`,前者是最早可能的时间戳。后者是最迟可能的时间错。通过该不确定预估,我们可以确定准确时间点就在该时钟范围内。此时,区间的大小取决于,上一次同步过后本地石英钟的漂移多少。
### 用于快照的时钟同步
@ -391,7 +391,7 @@ while (true) {
我们需要在全软件栈进行优化才能提供实时保证:
1. **在操作系统上**,需要能提供指定所需 CPU 时间片的实时操作系统(*real-time operating system*RTOS
1. **在操作系统上**,需要能提供指定所需 CPU 时间片的实时操作系统(*real-time operating system* RTOS
2. **在依赖库中**,所有的函数都需要注释其运行时间的上界。
3. **在内存分配上**,要限制甚至禁止动态内存分配(会有实时 GC 器,但不会占用太多时间)。
4. **在观测和测试上**,需要进行详尽的衡量和测试,以保证满足实时要求。
@ -578,4 +578,4 @@ Quorum 算法多要求每个节点记住其所声明的内容。如果由于某
但这并不是说,理论的、抽象的系统模型毫无价值。事实上,恰恰相反,他能帮助我们将复杂真实的系统,**提炼**为可处理、可推演的**有限故障集**。据此,我们可以剖析问题,并进行系统性的解决问题。在特定的系统模型下,只要算法满足特定性质,我们就可以**证明算法的正确性。**
即使算法被证明是正确的,但在实际环境中,其实现并不一定总能够正确运行。不过,这已经是一个很好地开端了,系统的分析能够很快的暴露算法的问题。而在真实系统中,这些问题只有经过很长时间、当你的假设被某些极端情况打破后才可能发现。**理论分析**Theoretical analysis和**实践测试**empirical testing需要并重。
即使算法被证明是正确的,但在实际环境中,其实现并不一定总能够正确运行。不过,这已经是一个很好地开端了,系统的分析能够很快的暴露算法的问题。而在真实系统中,这些问题只有经过很长时间、当你的假设被某些极端情况打破后才可能发现。**理论分析**Theoretical analysis和**实践测试**empirical testing需要并重。