fix typo in ch08.md

This commit is contained in:
qtmuniao 2023-10-29 13:32:08 +00:00 committed by GitHub
parent b6d6c0c7c1
commit fa05457cc8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

18
ch08.md
View File

@ -409,12 +409,12 @@ while (true) {
3. 需要处理**不可靠时钟**造成的多机时钟漂移问题 3. 需要处理**不可靠时钟**造成的多机时钟漂移问题
4. 任意的不确定的**进程停顿** 4. 任意的不确定的**进程停顿**
如果你没有习惯于应对分布式系统环境,可能会对由上述问题引起的异常感到十分困惑。分布式系统中编程复杂度高的本质在于:身处网络中的节点,不能直接**确信**任何事情,而只能根据从网络中得到的信息(没有得到回复也是一种信息)来**推测**guess只能通过与其他节点**交换信息**来确定其状态。如果一个对端节点**没有响应**,我们难以分辨是网络问题还是节点本身问题。 如果你没有习惯于应对分布式系统环境,可能会对由上述问题引起的异常感到十分困惑。分布式系统中编程复杂度高的本质在于:身处网络中的节点,不能直接**确信**任何事情,而只能根据从网络中得到的信息(没有得到回复也是一种信息)来**推测**guess只能通过与其他节点**交换信息**来确定其状态。如果一个对端节点**没有响应**,我们难以分辨是网络问题还是节点本身问题。
对这些系统边界的进一步讨论就有点偏哲学了: 对这些系统边界的进一步讨论就有点偏哲学了:
1. 在我们的系统中,哪些信息是真?哪些信息是假? 1. 在我们的系统中,哪些信息是真?哪些信息是假?
2. 在**感知**和**测量**手段本身都不准的情况下,我们对由上述手段得来的信息的真假又可以有几确信? 2. 在**感知**和**测量**手段本身都不准的情况下,我们对由上述手段得来的信息的真假又可以有几确信?
3. 软件系统是否需要遵循物理世界的法则,如因果关系? 3. 软件系统是否需要遵循物理世界的法则,如因果关系?
幸运的是,我们并不需要进一步追问到人生的意义是什么(笑)。在分布式系统中,我们可以做一些**基本假设**,并基于这些假设设计真实系统。基于特定假设,我们能够设计出能够**被证明正确性**的算法。那么,纵然底层系统不怎么可靠,我们仍能通过罩一层协议,使其对上提供相对可靠的保证(比如 TCP 幸运的是,我们并不需要进一步追问到人生的意义是什么(笑)。在分布式系统中,我们可以做一些**基本假设**,并基于这些假设设计真实系统。基于特定假设,我们能够设计出能够**被证明正确性**的算法。那么,纵然底层系统不怎么可靠,我们仍能通过罩一层协议,使其对上提供相对可靠的保证(比如 TCP
@ -435,7 +435,7 @@ while (true) {
其中,前面故事中的宣布某个节点死亡就是这样一种决策。如果有达到法定个数的节点宣布某节点死亡,那他就会被标记为死亡。即使他还活着,也不得不服从系统决策而出局。 其中,前面故事中的宣布某个节点死亡就是这样一种决策。如果有达到法定个数的节点宣布某节点死亡,那他就会被标记为死亡。即使他还活着,也不得不服从系统决策而出局。
最普遍的情况是,法定人数是集群中超过半数的节点,即**多数派**(其他比例的法定人数也有可能)。多数派系统允许少数节点宕机后,集群仍能继续工作(如三节点集群,可以容忍一个节点的故障;五节点集群,可以容忍两个节点故障)。并且在少数节点故障后,集群仍能安全做出决策。因为在一个集群中,根据鸽巢原理,系统中不可能有两个多数派做出不同的决策。第九章,讨论共识协议时,我们会展开更多细节。 最普遍的情况是,法定人数是集群中超过半数的节点,即**多数派**(其他比例的法定人数也有可能)。多数派系统允许少数节点宕机后,集群仍能继续工作(如三节点集群,可以容忍一个节点的故障;五节点集群,可以容忍两个节点故障)。并且在少数节点故障后,集群仍能安全做出决策。因为在一个集群中,根据鸽巢原理,系统中不可能有两个多数派做出不同的决策。第九章,讨论共识协议时,我们会展开更多细节。
### 领导者和锁 ### 领导者和锁
@ -469,7 +469,7 @@ while (true) {
注意到,该机制要求资源服务自己可以**主动拒绝**使用过期版本令牌的写请求,也就是说,仅依赖客户端对锁状态进行自检是不够的。对于那些不能**显式支持**防护令牌检查的资源服务来说我们仍然可以有一些变通手段work around如在写入时将令牌号写到文件路径中总之引入一些检查手段是必要的以避免在锁的保护外执行请求。 注意到,该机制要求资源服务自己可以**主动拒绝**使用过期版本令牌的写请求,也就是说,仅依赖客户端对锁状态进行自检是不够的。对于那些不能**显式支持**防护令牌检查的资源服务来说我们仍然可以有一些变通手段work around如在写入时将令牌号写到文件路径中总之引入一些检查手段是必要的以避免在锁的保护外执行请求。
也某种程度上的*真相由多数决定***客户端不能独自确定其对资源的独占性**。需要在服务端对所有客户端的情况做一个二次核验。 这也某种程度上的*真相由多数决定***客户端不能独自确定其对资源的独占性**。需要在服务端对所有客户端的情况做一个二次核验。
在服务端检查令牌粗看下是个缺点,但其无疑是个可以言明的优点:**默认所有客户端都是遵纪守法的并不明智,因为运行客户端的人和运行服务的人具有完全不同的优先考虑点**。因此,我们最好在服务端做好防护,使其免受不良客户端的滥用甚至攻击。 在服务端检查令牌粗看下是个缺点,但其无疑是个可以言明的优点:**默认所有客户端都是遵纪守法的并不明智,因为运行客户端的人和运行服务的人具有完全不同的优先考虑点**。因此,我们最好在服务端做好防护,使其免受不良客户端的滥用甚至攻击。
@ -483,7 +483,7 @@ while (true) {
> **拜占庭将军问题** > **拜占庭将军问题**
> >
> 拜占庭将军问题是**两将军问题**Two Generals Problem的**泛化**。两将军问题设想了一个需要达成作战计划的战争场景。有两军队,驻扎在两个不同的地方,只能通过信使来交换信息,但信使有时候会迟到甚至迷路(如网络中的数据包)。第九章会详细讨论这个问题。 > 拜占庭将军问题是**两将军问题**Two Generals Problem的**泛化**。两将军问题设想了一个需要达成作战计划的战争场景。有两军队,驻扎在两个不同的地方,只能通过信使来交换信息,但信使有时候会迟到甚至迷路(如网络中的数据包)。第九章会详细讨论这个问题。
> >
> 在该问题的拜占庭版本,有 n 个将军,但由于中间出了一些叛徒,他们想达成共识更具难度。但大部分将军仍然是忠诚的,并且会送出真实的消息;与此同时,叛徒会试图通过送出假的或者失实的消息来欺骗和混淆其他人(同时保持隐蔽)。大家事先都不知道谁是叛徒。 > 在该问题的拜占庭版本,有 n 个将军,但由于中间出了一些叛徒,他们想达成共识更具难度。但大部分将军仍然是忠诚的,并且会送出真实的消息;与此同时,叛徒会试图通过送出假的或者失实的消息来欺骗和混淆其他人(同时保持隐蔽)。大家事先都不知道谁是叛徒。
> >
@ -518,8 +518,8 @@ Web 应用确实可能遇到由任意终端用户控制的客户端(如浏览
对于时间的假设,有三种系统模型很常用: 对于时间的假设,有三种系统模型很常用:
1. **同步模型_synchronous model_**。这种模型假设**网络延迟**、**进程停顿**和**时钟错误**都是**有界**的。但这不是说,时钟完全同步的、网络完全没有延迟,只是说我们知道上述问题永远不会超过一个上界。但当然,这不是一个现实中的模型,因为在实践中,无界延迟和停顿都会实实在在的发生。 1. **同步模型_synchronous model_**。这种模型假设**网络延迟**、**进程停顿**和**时钟错误**都是**有界**的。但这不是说,时钟完全同步的、网络完全没有延迟,只是说我们知道上述问题永远不会超过一个上界。但当然,这不是一个现实中的模型,因为在实践中,无界延迟和停顿都会实实在在的发生。
2. **半同步模型partial synchronous**。意思是在大多数情况下,网络延迟、进程停顿和时钟漂移都是有界的,只有偶尔,他们会超过界限。这是一种比较真实的模型,即在**大部分时间里**,系统中的网络和进程都表现良好,否则我们不可能完成任何事情。但与此同时,我们必须要记着,任何关于时限的假设都有可能被打破。且一旦出现出现异常现象,我们需要做好最坏的打算:网络延迟、进程停顿和时钟错误都有可能错非常离谱。 2. **半同步模型partial synchronous**。意思是在大多数情况下,网络延迟、进程停顿和时钟漂移都是有界的,只有偶尔,他们会超过界限。这是一种比较真实的模型,即在**大部分时间里**,系统中的网络和进程都表现良好,否则我们不可能完成任何事情。但与此同时,我们必须要记着,任何关于时限的假设都有可能被打破。且一旦出现出现异常现象,我们需要做好最坏的打算:网络延迟、进程停顿和时钟错误都有可能错非常离谱。
3. **异步模型_Asynchronous model_**。在这种模型里,算法不能对时间有任何假设,甚至时钟本身都有可能不存在(在这种情况下,超时间隔根本没有意义)。有些算法可能会针对这种场景进行设计,但很少很少。 3. **异步模型_Asynchronous model_**。在这种模型里,算法不能对时间有任何假设,甚至时钟本身都有可能不存在(在这种情况下,超时间隔根本没有意义)。有些算法可能会针对这种场景进行设计,但很少很少。
除时间问题,我们还需要对节点故障进行抽象。针对节点,有三种最常用的系统模型: 除时间问题,我们还需要对节点故障进行抽象。针对节点,有三种最常用的系统模型:
@ -567,6 +567,6 @@ Quorum 算法多要求每个节点记住其所声明的内容。如果由于某
我们在对算法进行理论描述的时候,可以假设一些事情不会发生。比如,在非拜占庭系统中,我们假设对哪些故障会发生、哪些不会做了假设。但在系统实现的代码中,我们通常也会保留处理这些极端情况的代码,哪怕处理的很简单,比如打印一些文字:`printf("Sucks to be you")` 或者使用某个错误号来退出 `exit(666)`,然后让运维人员来做进一步排查(这种区别也是计算机科学和软件工程的不同之处)。 我们在对算法进行理论描述的时候,可以假设一些事情不会发生。比如,在非拜占庭系统中,我们假设对哪些故障会发生、哪些不会做了假设。但在系统实现的代码中,我们通常也会保留处理这些极端情况的代码,哪怕处理的很简单,比如打印一些文字:`printf("Sucks to be you")` 或者使用某个错误号来退出 `exit(666)`,然后让运维人员来做进一步排查(这种区别也是计算机科学和软件工程的不同之处)。
但这并不是说,理论的、抽象的系统模型毫无价值。事实上,恰恰相反,能帮助我们将复杂真实的系统,**提炼**为可处理、可推演的**有限故障集**。据此,我们可以剖析问题,并进行系统性解决问题。在特定的系统模型下,只要算法满足特定性质,我们就可以**证明算法的正确性。** 但这并不是说,理论的、抽象的系统模型毫无价值。事实上,恰恰相反,能帮助我们将复杂真实的系统,**提炼**为可处理、可推演的**有限故障集**。据此,我们可以剖析问题,并进行系统性解决问题。在特定的系统模型下,只要算法满足特定性质,我们就可以**证明算法的正确性。**
即使算法被证明是正确的,但在实际环境中,其实现并不一定总能够正确运行。不过,这已经是一个很好地开端了,系统的分析能够很快的暴露算法的问题。而在真实系统中,这些问题只有经过很长时间、当你的假设被某些极端情况打破后才可能发现。**理论分析**Theoretical analysis和**实践测试**empirical testing需要并重。 即使算法被证明是正确的,但在实际环境中,其实现并不一定总能够正确运行。不过,这已经是一个很好的开端了,系统的分析能够很快地暴露算法的问题。而在真实系统中,这些问题只有经过很长时间、当你的假设被某些极端情况打破后才可能发现。**理论分析**Theoretical analysis和**实践测试**empirical testing需要并重。