本文介绍了 PingCAP 的 TiDB 的时间戳预言机(TSO),它是如何提供时间服务的,以及它的优缺点。
今天,分布式数据库引领市场,但分布式系统中的时间同步仍然是一个难以破解的难题。由于时钟偏差,分布式数据库不同节点的时间无法完美同步。许多计算机科学家提出了解决方案,例如Leslie Lamport(2013 年图灵奖获得者)的逻辑时钟、混合逻辑时钟和 TrueTime。
PingCAP 的TiDB是一个开源的分布式 NewSQL 数据库,采用时间戳预言机(TSO)提供时间服务,并使用集中控制服务——Placement Driver(PD) ——分配单调递增的时间戳。
在这篇文章中,我将介绍 TiDB 的 TSO,它是如何提供时间服务的,以及它的优缺点。
TiDB 的架构
在深入了解 TiDB 的时间服务之前,我们先回顾一下 TiDB 的架构。
TiDB是一个开源的分布式数据库,具有水平扩展性、强一致性和高可用性。它由多个组件组成,包括 PD 集群、TiDB 集群、存储集群和 TiSpark。这些组件相互通信,形成一个完整的 TiDB 系统。
PD 是整个 TiDB 数据库的“大脑”,也是我们今天的重点。它有三个主要任务。它:
- 实时存储和管理整个 TiDB 系统的元数据
- 实时调度和平衡 TiKV 和 TiFlash 节点上的工作负载
- 提供时间服务
TiDB 的 PD 集群和 TSO
PD 集群通常由多个 PD 实例(大多数情况下为三个实例)组成,这些实例中的 PD Leader 对外提供服务。PD 集群中嵌入了 etcd 存储,以保证 PD 的可用性并提高其存储元数据的 能力。
如果 PD Leader 崩溃,会自动选出新的 Leader,以保证时间服务的可用性。etcd Leader 与 PD Leader 共享同一个 PD 实例,因此在 Leader 选举期间,etcd Leader 将优先于 PD Leader。选举过程如下:
TiDB 的 TSO 使用集中式混合逻辑时钟来提供时间服务。它使用 64 位来表示时间间隔。低 18 位代表逻辑时钟,其余 46 位代表物理时钟。由于其逻辑时钟为 18 位结构,每秒总共可以生成和分配 2^18 * 1,000 或 262,144,000 个时间戳。
接下来,我将介绍 PD 服务器中的 TSO 是如何发挥作用的。本节将描述PD 如何校准、传递和快进时间。
校准时间
When a new PD leader is elected, it does not know the current system time. 所以它的首要任务是校准时间。
First, the newly elected PD Leader reads the time stored in the etcd by the previous PD Leader. 存储的时间称为TLAST,是前一个 PD Leader 应用的物理时间的最大值。读取TLAST后,新的 PD Leader 知道前一个 Leader 分配的时间戳小于TLAST。
然后,新的 PD Leader 比较本地物理时间TLAST和TNOW :
- 如果TNOW – TLAST < 1 ms,则当前物理时间TNEXT = TLAST + 1;
- 否则,TNEXT = TNOW。
新的PD Leader完成这些步骤后,时间校准就完成了。
传递时间
完成时间校准后,新的 PD Leader 开始提供 TSO 服务。To ensure that the next elected PD Leader can successfully calibrate the time after the current PD Leader is down, the current PD leader should store TLAST in the etcd every time after it delivers the time services. 但是,如果PD领导每次都这样做,PD的表现就会受到很大影响。因此,为避免此类问题,PD Leader 预先申请了一个可分配的时间窗口Tx。它的默认值为 3。
它首先将等于TNEXT + Tx的 TLAST 存储在etcd中 ,然后将时间段 [ TNEXT , TNEXT + Tx ) 内的所有时间戳分配到内存中。
预分配修复了 etcd store 频繁操作导致的 PD 性能损失问题。然而,缺陷在于如果 PD Leader 崩溃,许多预先分配的时间戳将被浪费。
当客户端请求 TSO 服务时,返回一个 64 位混合逻辑时间戳。它的物理时间值是校准后的TLAST,它的逻辑时钟值会随着请求而原子地递增。如果其逻辑时钟值超过其最大值(1 << 18),则休眠 50 ms 以等待物理时间快进。物理时间快进后,如果还有时间戳需要分配,PD Leader继续分配。
TSO 服务请求是跨网络的,为了降低网络带宽消耗,TiDB 的 PD 服务器支持批量请求 TSO 服务。
快进时间
在时间服务过程中,PD 只能通过逻辑时间的增量来分配时间戳。当增量值达到上限时,无法再分配时间戳,需要快进物理时间。
PD 每 50 毫秒检查一次当前物理时间,然后快进时间。根据方程JetLag = TNOW – TLAST 如果JetLag > 1 ms,混合逻辑时钟中的物理时间比当前物理时间慢,需要快进以使TNEXT = TNOW。
此外,当逻辑时钟在时间服务期间达到其阈值时,它会停止并等待。因此,为了防止这种情况发生,当当前逻辑时钟超过其阈值的一半时,混合逻辑时钟内部的物理时钟也会提前。完成此操作后,逻辑时钟的值将重置为 0。
当TLAST – TNEXT <= 1 ms时,表示之前申请的时间窗口已经用完,需要申请下一个时间窗口。因此,PD Leader 将TLAST(等于TNEXT + Tx)存储到 etcd 中,并在新的时间窗口内继续分配时间戳。
TSO 的优缺点
TiDB 采用了 TSO,一种集中式时钟解决方案,本质上也是一个混合逻辑时钟。由于中心化时钟提供单点时间服务,所有事件都是有序的。实现起来也很简单。它也有以下缺点;幸运的是,他们中的大多数都有相应的解决方案:
- 跨区域提供时间服务时性能损失 。 为了解决这个问题,可以将PD集群部署在同一个区域。
- 单点故障。为了解决这个问题,将 etcd 嵌入到 PD 集群中,并使用Raft共识算法使时间服务高可用和一致。
- 可能的性能瓶颈。 由于 TSO 服务仅由 PD 负责人提供,因此从技术上讲,将来可能会出现性能瓶颈。幸运的是,PD Leader 每秒可以生成 2.6 亿个时间戳,并且经过多次优化。到目前为止,我还没有看到性能瓶颈。
作者: 高海涛
文章来源:https://dzone.com/articles/tidbs-timestamp-oracle