参考阅读:
分布式系统理论基础 - 时间、时钟和事件顺序
分布式系统的时间
分布式系统一致性的发展历史
分布式系统一致性的发展历史(一)
时间、时钟和事件顺序
- 分布式系统使用逻辑时钟记录事件顺序关系。
- 采用物理时钟,在分布式系统中仍然会有毫秒级别的偏差。
Lamport timestamps
每个事件对应一个Lamport时间戳,初始值为0
如果事件在节点内发生,时间戳加1
如果事件属于发送事件,时间戳加1并在消息中带上该时间戳
如果事件属于接收事件,时间戳 = Max(本地时间戳,消息中的时间戳) + 1
偏序关系 partial order,如下图方框内的编号:
全序关系 total order,除了上面的偏序关系外,加上以下排序,构成全序关系:
A1 => B3 、 A2 => C2 、 B4 => C3 、B5 => A3 。
Vector clock
Vector clock是在Lamport时间戳基础上演进的另一种逻辑时钟方法,它通过vector结构不但记录本节点的Lamport时间戳,同时也记录了其他节点的Lamport时间戳
如果 Tb[Q] > Ta[Q] 并且 Tb[P] < Ta[P],则认为a、b同时发生,记作 a <-> b。例如图2中节点B上的第4个事件 (A:2,B:4,C:1) 与节点C上的第2个事件 (B:3,C:2) 没有因果关系、属于同时发生事件。
True Time
- NTP是有误差的,而且NTP还可能出现时间回退的情况,所以我们不能直接依赖NTP来确定一个事件发生的时间。在Google Spanner里面,通过引入True Time来解决了分布式时间问题。
- NTP,network time protocol,网络时间协议。提供了一个服务,使得跨互联网的用户能精准地与 UTC 同步。
- 这个服务是可靠的,通常使用冗余服务器的方式。
- 提供对时间服务的保护,采用认证技术来检查数据和地址。
- Spanner通过使用GPS + Atomic Clock来对集群的机器进行校时,精度误差范围能控制在ms级别,通过提供一套TrueTime API给外面使用。
- 虽然spanner引入了TrueTime可以得到全球范围的时序一致性,但相关事务在提交的时候会有一个wait时间,只是这个时间很短,而且spanner后续都准备将其优化到 ε < 1ms,也就是对于关联事务,仅仅在上一个事务commit之后等待2ms之后就能执行,性能还是很强悍的。
- 最关键的是,TrueTime 是基于硬件的,对于很多企业来说,是没有办法搞定这套部署的。
Hybrid Logic Clock
- 从软件层面,基于 NTP ,解决分布式时间问题。
- 读取当前系统时间,对于一个 HLC 的时间t 来说,他总是等于或者略大于当前的系统时间。
- HLC 由两部分组成——physical clock 和 logic clock。某一结点 j 维护了 l.j 和 c.j ,前者是节点 j 当前已知的最大的物理时间,后者是当前的逻辑时间。
- 如果有两个事件,那么先判断物理时间 pt,再判断逻辑时间 ct。
HLC虽然方便,它毕竟是基于NTP的,所以如果NTP出现了问题,可能导致HLC与当前系统pt的时间误差过大