在前文 ( 时间表征 ) 中描述了各种计时的标准。
有了准确计时的手段后,还需要对当前时间信息进行读取。
如何获知当前准确时间?#
既然有了计时标准,我们如何获知当前的准确时间?
👆😎,我有一计,大家都去测量现在的时间吧!🤯 显然这不现实。更合理的方式是由一个 / 几个机构协调出一个统一的标准时间,其他用户从这个标准源同步时间数据。其他用户内部的局部系统自己维护一份类似的计时系统(精度要求不需要那么高),通过这个计时系统为系统内部服务。然后定期从标准 UTC 校准时间、修正误差。
于是就可以得到这样的时间发布架构:
时间同步机制#
在这样的架构下,需要进行时间同步。
你说巧不巧,我又有一计👆😎,大家都去找时间发布机构读时间,每次要同步时间都去问它,然后手动录入吧!💩,显然这也不现实。还是看看别的方式吧。
首先时间同步存在一个需要解决的问题就是当前瞬时时间作为一个信息,从信息源传输到目的地也需要时间。为了提高精度,需要准确计算出这个延迟,才能实现精准同步。
单向同步#
一种朴素的方式是,时间源向用户发送时间信息,用户接收后将本地时钟进行同步,使得本地时钟与标准时钟的误差控制在一定范围内,要想降低误差,提高精度,用户需要计算出时间信息在传播链路中的延时,但这种方式因为是一次性的单向通信,难以计算延时。
对于卫星授时系统如(GPS / 北斗),可以通过计算用户定位与卫星之间距离确定传输延时,消除大部分误差。而对于光缆、电缆等传输系统,因为各层路由的不确定性(比如网络拥塞),无法准确计算单向链路时延。
双向同步#
在单向同步的基础上进行改进,用户在收到时间信息后将其返回,时间源收到返回信息后计算中间延迟,再告知用户端单向延迟,用户端结合单向延迟计算时间。可以有效的提高精度。
计算机系统中的同步协议#
现代各类系统中的时间同步协议包括 NTP 和 PTP(GPS 等授时系统就先略过了)。
NTP 协议#
时钟源与客户端的同步
NTP 协议将服务端作为时钟源。同步原理如下:
- 客户端首先向服务端发送一个 NTP 请求报文,其中包含了该报文离开客户端的时间戳
t1
- NTP 请求报文到达 NTP 服务器,此时 NTP 服务器的时刻为
t2
- 当服务端接收到该报文时,NTP 服务器处理之后,于
t3
时刻发出 NTP 应答报文。该应答报文中携带报文(t1, t2, t3)
- 客户端在接收到响应报文时,记录报文返回的时间戳
t4
最后客户端通过方程组
得到客户端与服务端的大致时间偏差。 客户端加上这个 offset
得到校准后的时间。
Tip
值得注意的是,这种校时方式基于一个重要假设:即来回两次的延时是相等的,无论传输带来的延时本身多大,只要往返延时相同,就可以准确同步。
显然这是不现实的,因为 NTP 本身是高层协议,会受到网络队列、网络拥塞的影响,这是延时的主要原因。实际应用中,误差在 100ms 级。
NTP 层次结构
NTP 除了解决时钟源与客户端之间的同步问题,还考虑到了层次结构。扁平化的结构会对 NTP 服务器造成过高的负载。因此在全局视角下,进行了分层。
NTP 分为 1-16 层,每层的 NTP 服务器与上一层级或同层级的时间进行同步。顶级 NTP 服务器从标准时间源同步时间。随着层次递增,与标准时间的误差逐渐增大。对于 16 层的设备,代表着不可用的时间,表示时间误差过大。
PTP 协议#
NTP 基于往返延迟相同的假设,而影响往返延时差距的一大原因是网络拥塞、网络队列导致的不确定性。因此,在部分高精度需求中,NTP 无法胜任。PTP 被提出。