16.1 严格一致性

一句话

严格一致性要求「读返回物理时间上最近的那次写」——它假设存在全局时钟且写生效瞬间对所有节点可见,所以在任何分布式系统里都不可实现;它的价值是当参照系与下界,不是工程目标。

定义:把「最近」钉死在物理时间上

给每个操作打上绝对时间戳,严格一致性要求:

  1. 每个写 W(x=v) 在某个物理时刻 t_W 生效;
  2. 生效后所有节点立即看到新值(零传播延迟);
  3. 任何读 R(x) 在 t_R 返回「所有 t_W < t_R 的写中时间戳最大」的那个值。
全局时间轴(假设存在)
t=0         t=1         t=2         t=3
│           │           │           │
W(x=1) ─────┤           │           │
            │           │  R(x) → ? │
            └───────────┴───────────┘
严格一致:R 必须返回 1(因为 W 在 t=1 已对全世界生效)

注意「已对全世界生效」这五个字:它比「写返回后能读到」强得多,要求的是写发生的那一刻,所有副本同时改变。

严格一致 ≠ 线性一致 ≠ 严格可串行化

这三个词经常被混用,差别在「排序依据」和「生效点」:

模型 排序依据 生效点 需要全局时钟? 分布式可实现?
严格一致 物理写时间 写发生的那一瞬,全局同时可见 是(且要求零延迟) 否
线性一致(16.2) 实时先后(只约束不重叠的操作) 调用与返回之间的某一点 否(逻辑排序) 是(付协调成本)
严格可串行化 事务的实时先后 事务区间内某一点 否(用时钟不确定度兜底) 是(Spanner 类系统)

三者的关键区别可以用「两个并发写」说明:W1 在 t=1 发出、W2 在 t=2 发出,两者重叠。

  • 严格一致:以物理时间为准,W2 更晚,所有副本最终必须是 W2 的值;
  • 线性一致:只要求存在一个与实时先后相容的全序,两个写谁在后都可以——只要所有读看到的顺序与这个全序一致;
  • 严格可串行化:只约束事务之间的实时先后,事务内部可以任意交错;它不要求「写瞬间全球可见」。

🔑 严格一致是单对象 + 物理时间的顶点;线性一致把「物理时间」换成了「实时先后 + 逻辑全序」,因此从不可实现变成可实现;严格可串行化再把它抬到事务粒度。

为什么不可实现:三个物理事实

① 没有全局时钟

分布式节点各有一个石英钟,漂移量级是 ppm(百万分之一):一天漂移几十毫秒是常态。NTP 能把误差压到毫秒级,PTP 在局域网能到微秒级,但:

  • 误差不为零,且会抖动;
  • 时钟可能回拨(NTP 校正、虚拟机迁移、闰秒处理);
  • 「同一时刻」在相对论意义上也没有绝对定义。

严格一致要求所有节点对「哪个写更近」有完全一致且精确的判断,时钟误差直接破坏这个前提。

② 传播有物理下界

信息在光纤里的速度约为 2.0×10^8 m/s(真空光速除以折射率约 1.47)。算一下单向传播时间:

链路 距离 光纤单向(物理下界) 往返(物理下界)
同城 50 km 0.2 ms 0.5 ms
北京–上海 1,067 km 5.2 ms 10.4 ms
纽约–伦敦 5,570 km 27.3 ms 54.5 ms
中国–美国西海岸 11,000 km 53.9 ms 107.7 ms

严格一致要求写生效瞬间「所有节点同时看到」,等价于要求传播时间为 0——光速不允许。即使只要求「读发生在写之后」,跨洲也要先付几十毫秒,这是 8.1 TCP/IP 与三次握手 里 RTT 表的物理根源。

③ 并发写无法在物理时间上定序

两个写如果时间戳相同(或差异小于时钟误差),谁先谁后无法从物理时间判断。要让所有节点达成一致,必须通信——而一旦通信,就回到了「用逻辑顺序替代物理顺序」的路子上,也就是线性一致,而不是严格一致。

🔑 严格一致要求的其实是「瞬时、全局、原子」的更新:瞬时 = 零延迟,全局 = 所有副本,原子 = 不可分割。三者同时满足在分布式系统里做不到;单机单副本可以近似,一旦跨节点就失效。

那它为什么还值得学

用途 说明
谱系图的顶点 它是最强的模型,用来给其他模型定位(16.7)
证明下界 「严格一致不可实现」直接推出「任何分布式强一致都要付协调成本」
识别营销话术 厂商说「全球严格一致」时,追问三个问题就能拆穿(见下)
理解术语演进 线性一致、严格可串行化都是为了「绕开严格一致的物理不可能」而设计的

三个追问,拆穿「严格一致」的宣传

追问 合格回答 危险信号
跨地域吗? 承认跨地域读有 RTT,或说明用共识/租约 「全球任何节点、任何时刻都一致」
并发写怎么排序? 说明用共识日志/时间戳/租约定序 「按服务器时间,绝对准确」
时钟误差多少? 给出 NTP/PTP/TrueTime 的误差界与处理方式 「时钟是同步的,不用管」

单机就严格一致吗

也不是。单机多核共享内存有 store buffer、cache 一致性协议、编译器重排:

  • 一个核的写要经过 store buffer 才对其他核可见,不是「瞬时」;
  • 缓存一致性协议保证的是单个地址的最终可见顺序,不是全局瞬时;
  • 需要内存屏障/原子指令才能得到「线性一致」的单对象语义(例如 Go 的 sync/atomic、C++ 的 std::atomic)。

所以即使在一台机器上,「严格一致」也只是近似;工程上追求的是线性一致(可证明、可实现),而不是严格一致。单机内的可见性与重排问题,与 15.7 竞态检测与数据竞争 讲的是同一套硬件事实。

术语对照:别被「强一致」三个字骗了

说法 通常指什么 可验收的规格
「强一致」 口语,含义随上下文漂移 不可验收,必须展开成下面某一种
严格一致 物理时间 + 瞬时全局可见 不可实现,只能当参照
线性一致 单对象实时原子性 「写返回后,任意节点读到的都是该写或更新的值」
严格可串行化 事务级实时原子性 「事务按实时先后等价串行,读不出现中间态」
外部一致 Spanner 对严格可串行化的叫法 同上,附 TrueTime 不确定度与 commit-wait

验收时把「强一致」翻译成第三列的一句话,再配故障注入(切主、分区、时钟偏移)验证,才算把话说清楚。

反模式

反模式 后果
用 NTP 同步来宣称严格一致 时钟误差与回拨仍在,并发写顺序不可判
把单机缓存一致性当分布式严格一致 跨节点没有共享缓存,结论不成立
宣称「全球严格一致」却读本地副本 读到的是本地已应用的前缀,不是全球最新
把「强一致」当验收标准 不可测试、不可度量;应写成「线性一致读/写」并给出 API 语义
用严格一致做容量规划 目标不可达,推导出的延迟/成本模型全错
忽略并发写的定序规则 用 LWW + 本地时钟,实际得到的是「按各自时钟排序」的弱一致

自检

Q1 严格一致与线性一致,在「两个并发写」的场景下有什么可观察差别?

▸ 答案:严格一致以物理写时间为准,较晚发出的写必须在所有副本上获胜;线性一致只要求存在一个与实时先后相容的全序,两个重叠的写可以按任意顺序排进全序——只要所有读与这个全序一致。因此同一段并发写历史,严格一致只允许一种结果,线性一致可能允许两种。前提是「物理时间可精确比较」,而这在分布式系统里不成立。

Q2 为什么说光速让严格一致不可能?用一个具体链路算给面试官看。

▸ 答案:严格一致要求写生效瞬间所有节点可见,即传播时间为 0。纽约到伦敦直线约 5,570 km,光纤中光速约 2.0×10^8 m/s,单向至少 27.3 ms、往返 54.5 ms。任何跨这条链路的写,都不可能「瞬时」到达对端;要等它到达,就已经不是严格一致,而是线性一致(在写返回后保证可见)或更弱的模型。

Q3 Spanner 宣称「外部一致(external consistency)」,它提供的是严格一致吗?

▸ 答案:不是严格一致,是严格可串行化(事务级):它保证事务按实时先后排序,读能看到已提交的、实时上更早的事务结果。它用 TrueTime 把「时钟不确定区间」显式暴露出来,并用 commit-wait 越过不确定区间,代价是提交延迟。它不要求「写瞬间全球所有副本同时可见」,也不依赖零延迟。

Q4 单机多核共享内存,能不能算严格一致?

▸ 答案:不能。写要经过 store buffer 才对其他核可见,缓存一致性与内存屏障保证的是可定义的可见顺序,不是「写瞬间全局生效」;而且核间没有精确共享的物理时钟。单机可以通过原子指令与屏障做到线性一致(对单个地址),但严格一致仍然是理想化。

Q5 既然不可实现,为什么教材还要定义严格一致?

▸ 答案:它是谱系的顶点与证明的起点:① 给出「最强」的参照,其他模型都是它的削弱;② 「不可实现」本身就是结论,解释了为什么强一致必须付协调成本与延迟;③ 它是识破宣传话术的标尺——任何声称「全球严格一致」的系统,只要追问跨地域、并发写定序、时钟误差,就会露馅。

跨篇相关:线性一致如何把「物理时间」换成「逻辑全序」见 16.2 线性一致性;顺序一致与它的差别见 16.3 顺序一致性;整套谱系与包含关系见 16.7 一致性模型谱系图;物理时钟漂移与 NTP/TrueTime 见 23.1 物理时钟与漂移、23.2 NTP 与 TrueTime;RTT 的物理来源见 8.1 TCP/IP 与三次握手;单机可见性与重排见 15.7 竞态检测与数据竞争;分区期间强一致要付出的可用性代价见 17.3 分区期间的取舍;Spanner 一类系统的实现见 44.19 分布式数据库(待补)。