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