从物理时钟到 NTP 与 PTP 协议
分布式系统里需要物理时间的地方不多,但一旦需要,精度就成了硬指标:日志要能按真实时间排序、事务要能判断先后、证书要能验证有效期。逻辑时钟(见 03-逻辑时钟:Lamport 与向量)解决「因果顺序」,但解决不了「两个事件相隔多少毫秒」。
这一篇走的是硬件到协议这条线:先把「物理时钟为什么不准」说清楚,再看 NTP 与 PTP 各自用什么办法把误差压到什么量级,最后落到两类协议的报文格式与实际抓包。
物理时钟:石英晶振与原子钟
石英晶振
石英晶振是绝大多数电子设备里提供时钟频率的元件,原理是压电效应:石英晶体在电场作用下会产生机械振动,振动频率由晶体的物理特性(切割角度、尺寸)决定,通常落在 MHz 量级。电路把这一振动转成电信号,就是时钟脉冲。
它的局限是频率随温度漂移。这个漂移量级可以直接对照:常见的 32.768 kHz 钟表晶振,每天可能有 ±1 秒的误差 —— 折算成相对误差约 ±20 ppm。这个数字决定了整条链路的起点:不做任何校正的话,两台机器的时钟一天就能差出一秒,一个月差半分钟。
原子钟
原子钟换掉了振荡源:用原子的能级跃迁频率代替石英振动。铯 133 原子基态超精细能级跃迁频率为 9,192,631,770 Hz —— 这个数字是国际单位制里「一秒」的定义,并非测量出来的常数:秒就是该跃迁辐射 9,192,631,770 个周期所持续的时间。
换来的是纳秒级精度,代价是成本与体积,所以原子钟只出现在时间标准(UTC)与高精度授时设备里,不会装到每台服务器上。
时钟同步的需求
两台机器的物理时钟都要靠协议对齐,这里的取舍决定了协议形态:
| 场景 | 精度要求 | 谁能满足 |
|---|---|---|
| 日志排序、粗粒度超时判定 | 秒级 | 用手表看着调都行 |
| 分布式事务、证书有效期 | 毫秒级 | NTP |
| 金融交易排序、5G 基站相位同步 | 微秒到纳秒级 | PTP(且必须硬件时间戳) |
原子钟买不起、装不下,所以精度只能从软件层面的协议里找 —— NTP 与 PTP 就是这两条路线。
NTP:广域网上的毫秒级同步
NTP(Network Time Protocol)由 David L. Mills 设计,1985 年随 RFC 958 定稿,目标是把互联网上设备之间的时钟误差压到毫秒级。它靠软件时间戳,跑在普通网络路径上,代价小、覆盖广。
四个时间戳与两条公式
同步的本质是解一个二元一次方程组:不知道双方时钟的偏差,也不知道网络单程延迟,两个未知量。NTP 用一次往返交换拿到四个时刻,把两个未知量解出来。
设 B 是客户端、A 是时钟源:
| 记号 | 记录方 | 含义 |
|---|---|---|
| B | 请求离开 B 的本地时刻(Origin Timestamp) | |
| A | 请求到达 A 的时刻(Receive Timestamp) | |
| A | 响应离开 A 的时刻(Transmit Timestamp) | |
| B | 响应到达 B 的本地时刻 |
于是:
两条式子的来历看一遍就记住了。
是总耗时减去服务端自己的处理时间。 是客户端看到的全程耗时, 是服务端内部从收到到发出的耗时,两者相减剩下的就是网络往返时间。 的分子里, 是「请求去程耗时 + 双方时钟偏差」, 是「响应回程耗时的相反数 − 时钟偏差」,两者相加把时钟偏差留下、把去程与回程的耗时消掉一半,再除以 2 就只剩偏差本身。
这里有一处隐含假设值得单独指出:
四个时刻的落点(
分层架构
NTP 用 Stratum 把时间源分成层级:
- Stratum 1:直接接原子钟或 GPS 的服务器,精度最高;
- Stratum 2 及以下:向上一层请求同步;同一层内的服务器也可以互相同步。
分层的作用是避免所有设备直连顶层时间源,同时提供冗余 —— 某个 Stratum 1 挂掉,下游可以从同层其他节点取时间。
Stratum 把时间源排成层级:
Stratum 0 原子钟 / GPS ← 时间基准,本身不跑 NTP
│
Stratum 1 [NTP 服务器] ← 直连基准设备
│
Stratum 2 [服务器] ⇄ [服务器] ← 同层之间也可以互相同步
│
Stratum 3 [客户端] [客户端] …报文格式(NTPv4)
NTP 报文走 UDP,端口 123。头部共 16 个字段:
| 字段 | 位宽 | 含义 |
|---|---|---|
| LI(Leap Indicator) | 2 | 闰秒警告:0 无警告 / 1 最后一分钟多一秒 / 2 少一秒 / 3 时钟未同步 |
| VN(Version Number) | 3 | 协议版本,当前为 4 |
| Mode | 3 | 0 保留 / 1 主动对称 / 2 被动对称 / 3 客户端 / 4 服务端 / 5 广播或组播 / 6 控制报文 / 7 预留 |
| Stratum | 8 | 层级:0 无效 / 1 一级源(原子钟、GPS)/ 2–15 二级及以下 / 16 无法同步 |
| Poll | 8 | 两个连续报文的轮询间隔,以 2 的幂表示,单位秒。例如 6 表示 64 秒 |
| Precision | 8 | 系统时钟精度,以 2 的幂表示,单位秒。例如 −5 表示 0.03125 秒 |
| Root Delay | 32 | 本机到时钟源的往返延迟 |
| Root Dispersion | 32 | 本机时钟相对时钟源的最大误差 |
| Reference Identifier | 32 | 时钟源的标识:Stratum = 0 时是 Kiss Code(调试用);Stratum 1–15 时是时钟源 IP 或哈希值 |
| Reference Timestamp | 64 | 系统时钟最后一次被设置的时间 |
| Origin Timestamp | 64 | 上述 |
| Receive Timestamp | 64 | 上述 |
| Transmit Timestamp | 64 | 上述 |
| Key Identifier | 32 | 客户端与服务端协商的通信密钥 |
| Message Digest | 128 | 报文完整性校验(MD5) |
| Extension Field | 变长 | NTPv4 新增,用于携带额外信息 |
注意 Timestamp 类字段都是 64 位:32 位整数秒 + 32 位小数秒,因此 NTP 的理论时间分辨率约为
抓包能看出的两件事
按同步方式分,抓到的报文不一样:
- 自动同步:广域网中的设备按固定间隔(如 1000 秒)自动同步。这类报文里可能不含 Key ID 与 MD5,因为未启用认证。
- 主动同步:用
sntp命令主动拉一次时间时,报文中会填充 Reference ID 等信息:
sntp 2.cn.pool.ntp.orgRoot Delay 能反推链路类型:与本地无线时钟同步时 Root Delay 可能为 0、延迟在微秒级;与远处的原子钟同步时延迟可能到毫秒级(例如 7 ms),这个差值就是广域网往返带来的。
PTP:局域网上的纳秒级同步
PTP(Precision Time Protocol,规范为 IEEE 1588)的目标是纳秒级,代价是它基本只能用在局域网,而且必须硬件支持。
四个时间戳与两条公式
PTP 同样解「偏差 + 单程延迟」两个未知量,但时间戳的来源与 NTP 不同 —— 前两个由主时钟侧记录,后两个由主从各记一个:
| 记号 | 记录方 | 报文 | 含义 |
|---|---|---|---|
| 主时钟 | Sync | Sync 离开主时钟的精确时刻 | |
| 从时钟 | Sync | Sync 到达从时钟的本地时刻 | |
| 从时钟 | Delay_Req | Delay_Req 离开从时钟的本地时刻 | |
| 主时钟 | Delay_Req | Delay_Req 到达主时钟的精确时刻 |
从时钟通过 Follow_Up 拿到
与 NTP 的式子对照着看:两者结构完全一样(都是「一对时间差相加除以 2」与「相减除以 2」),只是 PTP 用的是两次单向测量(正向 Sync、反向 Delay_Req),而 NTP 只用一次往返。PTP 之所以能这么做,是因为它双向都打了精确时间戳。
它的前提同样是路径对称:式子假设
PTP 的四步交换(方括号里是 two-step 模式才有的报文):
one-step 与 two-step
- one-step:Sync 报文本身携带发出时刻
; - two-step:Sync 只作信号,紧跟一条 Follow_Up 报文把
带过来。
出现 Follow_Up 就说明工作在 two-step 模式。
精度差在哪:硬件时间戳
| 打戳方式 | 打戳位置 | 典型抖动 |
|---|---|---|
| 软件时间戳 | 操作系统协议栈 | 10–100 微秒(受任务调度、中断延迟、驱动延迟影响) |
| 硬件时间戳 | MAC/PHY,在观测到帧起始定界符(SFD)的瞬间 | 10–100 纳秒 |
同一块网卡,换成硬件时间戳能把抖动压掉三个数量级。 这就是 PTP 能到纳秒级而 NTP 到不了的原因 —— 差的不是算法,是打戳位置。软件时间戳的抖动(几十微秒)比 NTP 想测的网络延迟还大,所以 NTP 只能止步毫秒级。
报文从应用到线路,能打时间戳的位置只有两处:
应用层
│
内核协议栈 ◀── 软件时间戳打在这里:受任务调度、中断延迟、驱动延迟影响
│ 抖动 10–100 微秒
NIC 驱动
│
MAC / PHY ◀── 硬件时间戳打在这里:观测到帧起始定界符(SFD)的瞬间
抖动 10–100 纳秒
⇒ 同一块网卡,换打戳位置能差三个数量级;
软件时间戳的抖动(几十微秒)比 NTP 想测的网络延迟还大 —— 这是 NTP 止步毫秒级的原因报文结构
PTP 走以太网,通常封装在 UDP 上。报文分三段:
- Header:Message Type(Sync / Follow_Up / Delay_Req / Delay_Resp 等)、Version、Domain Number(PTP 域,不同域互不干扰)、Source Port Identity(发送端标识)
- Body:Timestamp(发送或接收时间)、Correction Field(校正时间戳误差)
- Footer:Checksum
Correction Field 是 PTP 相对 NTP 多出来的一层机制,它由路径上的中间设备填写,见下一节。
配套的三种时钟角色
PTP 的精度不只靠端点,还靠网络设备参与:
| 角色 | 做什么 | 代价 |
|---|---|---|
| Ordinary Clock(OC) | 普通端点,只有一个 PTP 端口,作 master 或 slave | — |
| Boundary Clock(BC) | 对上游是 slave、对下游是 master,逐跳重新同步 | 每跳增加 50–100 ns 误差 |
| Transparent Clock(TC) | 不终止 PTP,只测量报文经过自己的驻留时间并写进 Correction Field | 消除交换机排队带来的不对称 |
TC 的存在正是为了对付上面那个「路径不对称」问题:报文在交换机里排队的时长两端都测不到,而 TC 把它量出来、写进 correction field,接收方减掉即可。
另外,网络里选谁当主时钟由 BMCA(Best Master Clock Algorithm) 决定 —— 各节点用 Announce 报文广播自己的时钟质量,按优先级自动选出 grandmaster,不需要人工指定。
NTP 与 PTP 的对比
| 特性 | NTP | PTP |
|---|---|---|
| 精度 | 毫秒级 | 纳秒级 |
| 适用范围 | 广域网、局域网 | 局域网(要求路径可控) |
| 时间戳位置 | 软件时间戳 | 硬件时间戳(MAC/PHY) |
| 测量方式 | 一次往返(四个时刻) | 双向各测一次(Sync + Delay_Req) |
| 是否依赖中间设备 | 不依赖 | 依赖:需要 TC / BC 消除排队不对称 |
| 协议复杂度 | 较低 | 较高(BMCA、域、profile、correction field) |
| 典型应用 | 互联网时间同步 | 工业自动化、金融交易、5G 基站相位同步 |
选择的分界线在路径是否可控:NTP 能穿过任意公网,但只能到毫秒级;PTP 能到纳秒级,但要求沿途设备配合,跨管理域就基本做不到。
相关
- 03-逻辑时钟:Lamport 与向量 —— 为什么要引入物理时钟、时钟精度
与走时误差 要小到什么程度,推导在那篇 - 01-全序、偏序 —— 全序与偏序的定义,以及「物理时钟 / 逻辑时钟 / 向量时钟」三条路线的对照
参考
- D. Mills et al. Network Time Protocol Version 4: Protocol and Algorithms Specification. RFC 5905, IETF, 2010.
- IEEE. IEEE 1588-2008 Standard for a Precision Clock Synchronization Protocol for Networked Measurement and Control Systems. 2008.
可信度说明:文中 NTP 的抓包观察(自动同步间隔、sntp 主动同步、Root Delay 量级)来自实测,不属于上述规范的内容。
可信度说明:硬件/软件时间戳的抖动区间(10–100 µs 与 10–100 ns)与 BC 每跳 50–100 ns 的量级来自厂商应用文档的转述,未核对规范正文。
YJ