时间同步概述
本文涉及的时间同步协议包括:NTP、PTP。泛泛而谈,以构建对时间同步的基本认识。
当我第一次接触时间同步的概念时,是很疑惑的。为什么要做时间同步?时间同步是什么?为什么会有各种各样的协议?本文将尽量以我的认识从几个方面解答:
- 什么是时间同步;
- 为什么要做时间同步;
- 时间同步协议的基本原理;
1和2是困扰我比较久的问题,3则是可以通过代码和文档直接获得的知识,没有太多的阻塞点。
什么是时间同步
对时间同步最直接的理解,就是同步不同“设备”之间的时间,让他们保持一致。
比如我们日常使用的电脑、手机,在连网的状态下,可以发现这些设备的时间一般都可以在“秒”的数量级上保持一致。而对于一些机械手表、老式的电子手表等,它们显示的时间误差有时候可能到“分钟”甚至“小时”数量级。
对于机械手表之类的设备,一般通过人类手动做时间同步,一方设备是手表(目标时钟),另一方设备是电脑或者电视直播等可信度较高的时钟源,但是通过人类手动操作(同步方式),这种同步方式的精度和效率都不高。而对于电脑、手机等设备(目标时钟),一般通过网络(同步方式)和网络上的另一方设备(时钟源)自动同步时间,这种同步方式的精度和效率都较高。
这些方式可以总结出来一些包含共性:
- 源时钟
- 目标时钟
- 同步方式(协议)
源时钟和目标时钟不一定是具象的设备,也可以是软件等虚拟设备。上文涉及的同步方式,具体化就是:
- 私有协议(手动方式,每个人的操作不一定完全一致)
- NTP(网络时间协议)
我们日常使用的UTC时间是一个相对的时间,通过UTC时间,可以比较直观的判断出现在是上午还是下午,这种时间方式偏向于人类可读性。时间是相对的,我们所能接触到的所有时间都是从某个节点开始记为0时刻,然后按照某个周期时间计数器累加,这个累加的计数器给出的值就是时间戳,当然,其单位可以有很多,比如1ms、5ms、1/12ns等等,甚至也可以不需要单位,时间戳偏向于机器可读性。
为什么要做时间同步
首先,结合上文的例子,以及生活经验,可以认识到时钟设备一个问题:自身精度问题,比如某个时刻调整好了手表的时间,但是没准几天后就慢或快了几分钟,又需要再次调整。对于手机、电脑这些设备,出于成本考虑,精度也不会太高,只不过相较于机械手表等设备可能要好一些。造成精度差异的原因之一,就是定时器自身的频率和稳定性之间的差异。
对于这些设备,如果只在出厂后调整一次时间,那么在使用过程中,设备的时间和真实时间的偏差就会逐渐增大,直至完全无法满足需求。不会有人愿意,明明定好了早上8点的闹钟,按时起床,结果外面太阳居然已经落山了这样的事情发生。为了解决这个问题,很自然的想法就是,每间隔一段时间,就调整一次时间。时间同步一般具有周期性。
另外,通过上面的例子也可以发现,不同的同步方式(下文就以协议称呼了)带来的同步精度也是不一样的。手动调整手表的误差可能是几秒,又因为调整周期较长,这种误差会逐渐扩大到几分钟;NTP的误差可能是几十毫秒,又因为通过软件自动调整的周期较小,即使误差扩大,也会很快纠正回来,所以一般也不会超过秒的数量级。
对于日常使用来说,秒或毫秒级别的误差就已经足够了。但是对于某些工业生产或者安全性较高的自动化过程来说,毫秒级别的误差太大。对于搭载激光雷达的自动驾驶方案,激光雷达输出的点需要和摄像头采集的帧作匹配(或许也有其他信号),这时候厂商一般会需要微妙级的精度(不知是否是车规要求)。使用NTP协议,很难满足这种精度要求。所以会有其他的时间同步协议,比如PTP,来满足更高精度的同步要求。
所以,为什么需要时间同步?
我们生活的很多方方面面都需要查看时间,人需要查看时间,机器也需要查看时间,又考虑到高精度硬件时钟的成本原因,那么就一定会涉及到时间同步。如果未来我们所有的时间设备都使用独立的标准原子钟,那么时间同步就不再是一个问题了,只需要出厂时同步时间即可。
NTP、PTP和手动调表没有区别,它们可以理解为是为了不同的精度需求和场景限制,而发明的不同“调表”方式。
时间同步协议的基本原理
以上,解答是什么和为什么两个问题,现在简单总结一下:
- 时间同步是什么?时间同步就是调表。
- 为什么要做时间同步?一般的表容易走偏,一段时间后的误差就不可接受,所以需要经常调。如果每个表的走时都一样,那就不存在调整了,只需出厂时调整一次即可。
考虑了比较久这一小结应该如何构建,本想通过代码或者协议文档来细节讲解。但是那样文章篇幅可能很大,需要查阅的代码量也很大。以后自身回看时也不一定真的能全部看完。所以,还是决定按照我此前对时间同步的学习步骤来,先作概念和原理性的学习,未来再查阅也能提供思路和方向。如果之后再涉及到了代码,再来深究。
以下,将介绍NTP、PTP时间同步协议的主要思想。
NTP
NTP算是我们日常能接触最多的时间同步协议,基本每台手机、电脑都使用NTP协议做时间同步。这就容易想到,NTP要面对的是一个巨大且复杂的网络,这种情况下,一般就需要客户端主动和服务端通信以同步时间。NTP通过一次完整的通信,就可以获取时间差。
同步步骤为:
- 客户端向服务器发送请求,并将发送时间戳T1一并发送
- 服务器收到请求后,记录收到时间戳T2,然后向客户端发送响应,并将T1、T2和发送时间戳T3一并发送
- 客户端收到响应后,记录收到时间戳T4
通过这个步骤,客户端可以计算出网络延迟(delay)和偏差(offset)。原理如下:
- T1、T4是客户端的时间戳,T2、T3是服务器的时间戳
- 假设客户端和服务器完全同步,那么T2 - T1 = delay,T4 - T3 = delay
- 但是客户端和服务器存在偏差offset,先记为服务器 = 客户端 + offset
- 那么公式修改为:T2 - (T1 + offset) = delay,T4 + offset - T3 = delay
- 根据3, 公式调整为:T2 - T1 = delay + offset,T4 - T3 = delay - offset
- 根据4,可以计算出offset = (T2 - T4 + T3 - T1) / 2,delay = (T2 - T1 + T4 - T3) / 2
通过这个公式,可以看出NTP作了一些假设:
- 网络延迟是对称的,即客户端到服务器的延迟和服务器到客户端的延迟是一样的
- 同步的时间段内,偏差是不变的(一般来说同步时间段内的偏差会小于同步精度)
PTP
PTP相对NTP来说,使用场景里面涉及到的设备数量少的多,只需要面对若干已知设备。数量的减少和可信度的提高,可以想象PTP的一般模式:
- 广播(组播也可以单播)消息(设备数量少,所以对网络影响小)
- 同步频率高
- 自适应主从模式(设备可信度高,所以只要有满足条件的设备,就可以尝试设置为主时钟设备)
PTP时间同步的基本原理如何?如图:
用文字描述这个步骤就是:
- 主时钟发送Sync报文,并记录Sync报文的发送时间戳T1,从时钟收到Sync报文,并记录收到的时间戳T2
- 主时钟发送Sync报文后,立即发送Follow_Up报文,其中包含了记录的时间戳T1
- 从时钟受到Follow_Up报文后,向主时钟发送Delay_Req报文,然后记录发送时间戳T3
- 主时钟收到Delay_Req报文后,记录收到时间戳T4,然后向从时钟发送Delay_Resp报文,其中包含了T4
以上,从时钟获得了T1、T2、T3、T4四个时间戳,那么就可以计算出主从时钟之间的延迟(delay)和偏差(offset)。原理如下:
- T1、T4是主时钟的时间戳,T2、T3是从时钟的时间戳
- 假设主时钟和从时钟完全同步,那么T2 - T1 = delay,T4 - T3 = delay
- 但是主时钟和从时钟存在偏差offset,先记为主时钟 = 从时钟 + offset
- 那么公式修改为:T2 + offset - T1 = delay,T4 - (T3 + offset) = delay
- 根据4, 公式调整为:T2 - T1 = delay - offset,T4 - T3 = delay + offset
- 根据5,可以计算出offset = (T4 - T3 - T2 + T1) / 2,delay = (T2 - T1 + T4 - T3) / 2
通过这个公式也看出,PTP作了一些假设:
- 网络延迟是对称的,即主时钟到从时钟的延迟和从时钟到主时钟的延迟是一样的
- 同步的时间段内,偏差是不变的(一般来说同步时间段内的偏差会小于同步精度)
可以发现,这些基本假设和NTP是一致的,计算公式也是一致的,再参考上一篇文章《clockdiff时间差测量原理》,这两种假设看起来是网络时间测量、同步的共性。
PTP和NTP原理类似,但是也有一些区别:
- PTP作一次时间同步的通信次数为4次,而NTP为2次
- PTP由服务端主动发起通信,NTP由客户端发起通信
通信次数的区别影响的是携带时间戳的精确性。对NTP,收发时间戳来自应用层;对PTP,收发时间戳来自数据链路层。从数据链路层获取时间戳,可以减少报文在设备内部处理时间的影响,提高时间戳的精确性。
如果更进一步,PTP还有不少高级特性,比如:主时钟选择、E2E和P2P模式、透明时钟、硬件时钟、频率同步(“调表”可以认为是相位同步)等等。