From d349cb36e5cf044cb96b0e95cad0dbc413e622da Mon Sep 17 00:00:00 2001 From: qtmuniao Date: Fri, 1 Dec 2023 13:38:55 +0000 Subject: [PATCH] Update ch09.md fix some typo --- ch09.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/ch09.md b/ch09.md index 071b034..afaff7d 100644 --- a/ch09.md +++ b/ch09.md @@ -637,7 +637,7 @@ Lamport 时间戳不依赖于物理时钟,但可以提供全序保证,对于 1. 处理协调者宕机恢复所需要的额外刷盘(fsync) 2. 协调者和参与者额外的网络往返开销 -相较于完全弃之不用,我们应当更加细致的考量分布式事务,因为可以从其中学到相当多的经验教训。首先,我们需要精确地定义什么是“分布式事务”。有两种完全不同的分布式事务经常被混淆: +相较于完全弃之不用,我们应当更加细致地考量分布式事务,因为可以从其中学到相当多的经验教训。首先,我们需要精确地定义什么是“分布式事务”。有两种完全不同的分布式事务经常被混淆: - **数据库内部分布式事务** 在一些分布式数据中(标配支持多分区和多副本的数据库),支持跨节点的**内部分布式事务**。如,VoltDB 和 MySQL 集群的 NDB 存储引擎就有这样的内部事务支持。在这种情况下,所有事务参与节点都运行着同样的二进制代码。 @@ -672,7 +672,7 @@ XA 不是一个网络协议——它定义了一组和事务协调者交互的 C 事务的**协调者**实现了 XA API。XA 的标椎并没规定协调者该如何实现,并且在实践中协调者通常以**库的形式**被加载进应用程序中(作为应用程序的一部分,而非额外单独的一个服务)。它会追踪事务中的所有参与者,在要求参与者准备提交(prepare)后收集其回复,使用本地磁盘上的日志来跟踪每个事务的**提交/中止**决策。 -如果应用进程崩溃、或者应用所在机器宕机,协调者也会随之而宕机。所有已经进行过提准备过,但未真正提交的事务(未定事务)无疑会阻塞住。由于协调者的日志在应用程序的本地磁盘里,则该服务器必须能够重启,从而让协调者库能够读取磁盘上的日志,以恢复之前所做提交或中止的决策。据此,协调者才可以使用 XA 协议的回调,要求所有参与者提交或者中止。数据服务器不能直接和协调者进行通信,所有的通信必须要通过客户端的 XA 库。 +如果应用进程崩溃、或者应用所在机器宕机,协调者也会随之而宕机。所有已经进行过提前准备过,但未真正提交的事务(未定事务)无疑会阻塞住。由于协调者的日志在应用程序的本地磁盘里,则该服务器必须能够重启,从而让协调者库能够读取磁盘上的日志,以恢复之前所做提交或中止的决策。据此,协调者才可以使用 XA 协议的回调,要求所有参与者提交或者中止。数据服务器不能直接和协调者进行通信,所有的通信必须要通过客户端的 XA 库。 ### 阻塞时持有锁 @@ -713,13 +713,13 @@ XA 事务解决了一些很现实而重要的难题:让异构的数据系统 在这种形式化表述中,一个共识协议必须满足以下条件: -- **全局一致性**(_Uniform agreement_) +- **全局一致性**(*Uniform agreement*) 没有任何两个节点最终做出不同决策。 -- **正直性**(_Integrity_) +- **正直性**(*Integrity*) 没有任何节点会做出两次决策(不会反复横跳) -- **有效性**(_Validity_) +- **有效性**(*Validity*) 如果一个节点做出了决策,该决策所对应的值一定来自系统内某个节点的提议 -- **可终止性**(_Termination_) +- **可终止性**(*Termination*) 任何没有宕机的节点,最终都会给出对某个值的决策 全局一致和正直性定义了共识协议的核心概念:**所有节点都要决策出同样的结果,并且一旦做出决策,就不能反悔**。加入有效性更多的是为了排除一些无效(trivial)结果:如果无论其他节点提议什么,一个算法都会选择 null 作为决策值;该算法虽然满足一致性和正直性约束,但却不满足有效性。 @@ -842,12 +842,12 @@ ZooKeeper,etcd 和 Consul 也会用于**服务发现**(service discovery) 然而,服务发现是否真的需要共识协议暂时存疑。传统上,人们使用 DNS 服务来通过服务名找到其对应 IP 地址。DNS 通常使用多级缓存来获取高性能和高可用性。从 DNS 读取信息肯定不满足线性一致性,而且从 DNS 中偶尔读到过期的结果通常问题不大。相比线性一致性,**高可用性和对网络的鲁棒性**才是更重要的事情。 -尽管服务发现不需要共识协议,但领导者选举需要。因此,如果你的共识系统已经知道领导者是谁,他就可以利用这些信息帮助别的服务来发现谁是领导者。处于这种目的,一些共识系统支持**只读的缓存副本**(如 Raft 中的 learner)。这些副本从共识协议中异步的接收数据,但并不参与投票。因此可以提供不在意线性一致性的读取。 +尽管服务发现不需要共识协议,但领导者选举需要。因此,如果你的共识系统已经知道领导者是谁,他就可以利用这些信息帮助别的服务来发现谁是领导者。出于这种目的,一些共识系统支持**只读的缓存副本**(如 Raft 中的 learner)。这些副本从共识协议中异步的接收数据,但并不参与投票。因此可以提供不在意线性一致性的读取。 ### 成员服务 ZooKeeper 及类似服务可以视为**成员服务**(membership services)研究范畴的一部分,该研究可以上溯到上世纪八十年代,对于构建高可用系统非常重要,如空中交管系统。 -成员服务可以确定当前**集群中哪些节点当前时存活的**。如第八章中所说,在具有无界延迟的网络中,不可能可靠的检测出一个节点是否故障。然而,如果你综合使用故障检测和共识算法,所有节点能够对哪些节点存活这件事达成共识。 +成员服务可以确定当前**集群中哪些节点当前是存活的**。如第八章中所说,在具有无界延迟的网络中,不可能可靠的检测出一个节点是否故障。然而,如果你综合使用故障检测和共识算法,所有节点能够对哪些节点存活这件事达成共识。 使用共识协议也有可能错将一个节点认为下线了,尽管它事实上是存活的。但尽管如此,只要系统能够对当前系统包含哪些节点达成共识,就仍然很有用处。例如,选主算法可以是——在系统当前所有节点中选一个具有最小标号的节点。如果所有节点对系统当前包含哪些节点存在分歧,则这种方法就不能正常工作(不同节点眼中的的最小编号节点可能不一致,从而让大家选出的主不一致)。