时间、时钟与事件顺序
分布式系统的核心困难之一:没有全局时钟——每台机器的时钟各走各的。本章讲物理时钟的漂移、Lamport 逻辑时钟、向量时钟与混合逻辑时钟,以及"先后"为什么需要重新定义(→ 复制与一致性模型)。
物理时钟不可靠
Section titled “物理时钟不可靠”机器时钟是石英振荡器,漂移(每秒几十微秒到毫秒)让各机器的时钟逐渐偏离;NTP 对时修正,但精度是毫秒级(网络延迟不可忽略),且对时的跳变本身会破坏"时间只增"的假设。
结论:分布式系统不能把物理时钟当作"先后"的依据——两台机器各自记的时间戳无法可靠排序事件。Google TrueTime 是例外(见下)。
Lamport 逻辑时钟
Section titled “Lamport 逻辑时钟”Lamport (1978) 的解法:不问几点,只问谁先。每个进程维护计数器:
- 本地事件:计数器 +1;
- 发消息:带上计数器;
- 收消息:计数器 = max(本地, 收到的) + 1。
(a 因果先于 b)蕴含 ——时钟与因果一致。
Lamport 时钟给出与因果一致的全序,但不能检测并发: 不能推出 (可能只是两个无关进程各自计数)——Lamport 时钟回答"全序"但不回答"是否真的因果相关"。
向量时钟:检测并发
Section titled “向量时钟:检测并发”每个进程维护全系统的计数向量:本地事件加自己的分量,收消息做逐分量 max 再加自己的。
- 当且仅当 (逐分量);
- 两个向量不可比 = 并发——向量时钟能检测并发,这是 Lamport 时钟做不到的;
- 代价是 O(n) 空间( 为进程数,每个事件带全向量)——向量时钟能检测并发,代价是 O(n) 空间。
应用:冲突检测(Dynamo 的多版本读写)、分布式调试(事件图)。
混合逻辑时钟与 TrueTime
Section titled “混合逻辑时钟与 TrueTime”- 混合逻辑时钟(HLC):物理时间戳为主、逻辑计数为辅——时钟既接近物理时间(对人类与外部系统友好)又保持因果一致(CockroachDB、YugabyteDB 的选择);
- Google TrueTime:硬件(GPS + 原子钟)把时钟误差变成显式区间——API 返回 的保证区间。Spanner 用它实现外部一致性:提交前等待区间上界过去(commit wait),保证"提交时间戳"真实序——误差显式化后,物理时间也能参与一致性。代价是专用硬件。
"先后"的重新定义
Section titled “"先后"的重新定义”单机的"先后"由时间戳定义;分布式系统重新定义为因果(happens-before):
- 同进程的程序序;
- 消息的发送先于接收。
"先后"在分布式系统中需要重新定义——不是物理时间,而是因果链。一致性的谱系(线性一致、因果一致)本质上都是"对先后顺序承诺多少"的不同回答(→ 复制与一致性模型)。
- 物理时钟漂移 + NTP 毫秒级精度:不能作为"先后"的依据
- Lamport 时钟给出与因果一致的全序,但不能检测并发
- 向量时钟能检测并发,代价是 O(n) 空间
- HLC 融合物理与逻辑;TrueTime 用硬件把误差变成显式区间(Spanner 的基础)
- "先后"的分布式定义是因果(happens-before),不是时间戳