Update ch9.md

This commit is contained in:
oyld 2022-05-26 23:41:52 +08:00
parent cad9c26559
commit a38953cbcd

6
ch9.md
View File

@ -153,7 +153,7 @@
#### 锁定和领导选举
一个使用单主复制的系统需要确保领导真的只有一个而不是几个脑裂。一种选择领导者的方法是使用锁每个节点在启动时尝试获取锁成功者成为领导者【14】。不管这个锁是如何实现的它必须是线性一致的所有节点必须就哪个节点拥有锁达成一致否则就没用了。
一个使用单主复制的系统,需要确保领导真的只有一个而不是几个脑裂。一种选择领导者的方法是使用锁每个节点在启动时尝试获取锁成功者成为领导者【14】。不管这个锁是如何实现的它必须是线性一致的所有节点必须就哪个节点拥有锁达成一致否则就没用了。
诸如 Apache ZooKeeper 【15】和 etcd 【16】之类的协调服务通常用于实现分布式锁和领导者选举。它们使用一致性算法以容错的方式实现线性一致的操作在本章后面的 “[容错共识](#容错共识)” 中讨论此类算法)[^iii]。还有许多微妙的细节来正确地实现锁和领导者选举(例如,请参阅 “[领导者和锁](ch8.md#领导者和锁)” 中的防护问题),而像 Apache Curator 【17】这样的库则通过在 ZooKeeper 之上提供更高级别的配方来提供帮助。但是,线性一致性存储服务是这些协调任务的基础。
@ -217,7 +217,7 @@
对于无主复制的系统Dynamo 风格;请参阅 “[无主复制](ch5.md#无主复制)”),有时候人们会声称通过要求法定人数读写( $w + r > n$ )可以获得 “强一致性”。这取决于法定人数的具体配置,以及强一致性如何定义(通常不完全正确)。
基于日历时钟(例如,在 Cassandra 中;请参阅 “[依赖同步时钟](ch8.md#依赖同步时钟)”)的 “最后写入胜利” 冲突解决方法几乎可以确定是非线性一致的,由于时钟偏差,不能保证时钟的时间戳与实际事件顺序一致。宽松的法定人数(请参阅 “[宽松的法定人数与提示移交](ch5.md#宽松的法定人数与提示移交)”)也破坏了线性一致的可能性。即使使用严格的法定人数,非线性一致的行为也是可能的,如下节所示。
基于日历时钟(例如,在 Cassandra 中;请参阅 “[依赖同步时钟](ch8.md#依赖同步时钟)”)的 “最后写入胜利” 冲突解决方法几乎可以确定是非线性一致的,由于时钟偏差,不能保证时钟的时间戳与实际事件顺序一致。宽松的法定人数(请参阅 “[宽松的法定人数与提示移交](ch5.md#宽松的法定人数与提示移交)”)也破坏了线性一致的可能性。即使使用严格的法定人数,非线性一致的行为也是可能的,如下节所示。
#### 线性一致性和法定人数
@ -287,7 +287,7 @@ CAP 定理的正式定义仅限于很狭隘的范围【30】它只考虑了
#### 线性一致性和网络延迟
虽然线性一致是一个很有用的保证,但实际上,线性一致的系统惊人的少。例如,现代多核 CPU 上的内存甚至都不是线性一致的【43】如果一个 CPU 核上运行的线程写入某个内存地址,而另一个 CPU 核上运行的线程不久之后读取相同的地址,并没有保证一定能一定读到第一个线程写入的值(除非使用了 **内存屏障memory barrier****围栏fence**【44】
虽然线性一致是一个很有用的保证,但实际上,线性一致的系统惊人的少。例如,现代多核 CPU 上的内存甚至都不是线性一致的【43】如果一个 CPU 核上运行的线程写入某个内存地址,而另一个 CPU 核上运行的线程不久之后读取相同的地址,并没有保证一定能读到第一个线程写入的值(除非使用了 **内存屏障memory barrier****围栏fence**【44】
这种行为的原因是每个 CPU 核都有自己的内存缓存和存储缓冲区。默认情况下内存访问首先走缓存任何变更会异步写入主存。因为缓存访问比主存要快得多【45】所以这个特性对于现代 CPU 的良好性能表现至关重要。但是现在就有几个数据副本(一个在主存中,也许还有几个在不同缓存中的其他副本),而且这些副本是异步更新的,所以就失去了线性一致性。