mirror of
https://github.com/DistSysCorp/ddia.git
synced 2024-12-25 20:30:39 +08:00
Update ch09.md fix some typo
This commit is contained in:
parent
dbae38160a
commit
d349cb36e5
16
ch09.md
16
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)研究范畴的一部分,该研究可以上溯到上世纪八十年代,对于构建高可用系统非常重要,如空中交管系统。
|
||||
|
||||
成员服务可以确定当前**集群中哪些节点当前时存活的**。如第八章中所说,在具有无界延迟的网络中,不可能可靠的检测出一个节点是否故障。然而,如果你综合使用故障检测和共识算法,所有节点能够对哪些节点存活这件事达成共识。
|
||||
成员服务可以确定当前**集群中哪些节点当前是存活的**。如第八章中所说,在具有无界延迟的网络中,不可能可靠的检测出一个节点是否故障。然而,如果你综合使用故障检测和共识算法,所有节点能够对哪些节点存活这件事达成共识。
|
||||
|
||||
使用共识协议也有可能错将一个节点认为下线了,尽管它事实上是存活的。但尽管如此,只要系统能够对当前系统包含哪些节点达成共识,就仍然很有用处。例如,选主算法可以是——在系统当前所有节点中选一个具有最小标号的节点。如果所有节点对系统当前包含哪些节点存在分歧,则这种方法就不能正常工作(不同节点眼中的的最小编号节点可能不一致,从而让大家选出的主不一致)。
|
||||
|
Loading…
Reference in New Issue
Block a user