跳转到内容

NTP 1991 — 用四个时间戳和一棵服务器树,让全互联网的钟差几毫秒

待复核

NTP(Network Time Protocol)是让一台普通电脑通过不可靠的互联网,去和原子钟保持毫秒级一致的协议。Mills 1991 这篇论文是它的奠基设计。

日常类比:一个班里几百号人都戴着便宜电子表,每块表每天会快慢几十秒。班主任只有一块标准表。要让全班的表都对得上,不可能让大家排队让班主任挨个调;得搞一套”组长把时间传给小组、小组再传下去”的层级,再加上每次对表都要”扣掉传话花的时间”。

NTP 把这件事工程化:

  • 服务器树:根是接 GPS / 原子钟的少数权威机器(stratum 1),它们把时间传给 stratum 2,再到 stratum 3……
  • 四时间戳:每次客户端问服务器要时间,记下 4 个时刻,从中算出”我比你慢多少(offset)“和”路上花了多久(delay)”
  • 算法链:滤波 → 选择 → 组合 → 纪律环(PLL),把多个上游服务器的噪声测量收敛成一个稳定的本地时钟修正

公网上能稳定做到 10ms 级,局域网内亚毫秒级。

不理解 NTP,下面这些事都讲不清:

  • 你电脑右下角那个时间凭什么和北京天文台一致 —— 它每隔几分钟在偷偷和某台 NTP 服务器对表
  • 数据库的”时间戳排序”为什么不能直接用 wall-clock —— NTP 只能保证毫秒级,事务序需要纳秒
  • Spanner 为什么要造 TrueTime(GPS+原子钟+API 返回区间)—— 因为 NTP 给不出”误差上界”
  • 为什么 2014 年 NTP 反射型 DDoS 能打出几百 Gbps —— 协议早期的 monlist 查询设计有放大漏洞

NTP 同时是互联网计时基础设施早期分布式系统教科书案例:它示范了在不可靠网络上,如何用统计 + 控制论的组合扛住延迟抖动、对称性破坏、单点故障。

NTP 工作流程拆 四步

  1. 测量(四时间戳):客户端发包记 t0,服务器收到记 t1、回包记 t2,客户端收到记 t3。

    • 偏移 θ = ((t1 − t0) + (t2 − t3)) / 2
    • 时延 δ = (t3 − t0) − (t2 − t1)
    • 这套算法默认前向后向路径耗时一样——不对称就会有系统误差。
  2. 滤波(clock filter):保留最近 8 次测量,挑 dispersion 最小的那一个。类比:抽 8 次秒表读数,扔掉抖得最厉害的,留最稳的。

  3. 选择 + 组合(selection / combine):从多台上游里去掉falseticker(说谎或离群的),剩下的truechimer按 1/dispersion² 加权平均。类比:让 5 个朋友报时间,先剔掉明显瞎说的两个,剩下三个的平均更可信。

  4. 纪律环(discipline loop):用 PLL/FLL(锁相/锁频环)持续微调本地晶振的频率和相位,让它慢慢追上目标,不是猛地跳过去(跳过去会让 make 这种依赖时间戳的工具炸)。

整套加起来:多个上游 + 多次测量 + 控制论,把不可靠 UDP 网络的抖动磨成一条平滑曲线。

假设你发了一个 NTP 请求:

t0 = 100.000 (客户端发出,本地时钟)
t1 = 150.020 (服务器收到,服务器时钟)
t2 = 150.030 (服务器回包, 服务器时钟)
t3 = 100.030 (客户端收到,本地时钟)

代入:

  • offset θ = ((150.020 − 100.000) + (150.030 − 100.030)) / 2 = 50.010
  • delay δ = (100.030 − 100.000) − (150.030 − 150.020) = 0.020

结论:客户端比服务器慢 50.010 秒,单程时延约 10ms。客户端会慢慢加快本地时钟,几分钟内追上服务器。

案例 2:用 chrony 配一台内网客户端

Section titled “案例 2:用 chrony 配一台内网客户端”
# /etc/chrony/chrony.conf(教学迷你例)
server ntp1.example.internal iburst
server ntp2.example.internal iburst
server ntp3.example.internal iburst
server ntp4.example.internal iburst
makestep 1.0 3

逐部分解释

  • 四条 server:对应 Mills 强调的多上游;至少 4 台才能在一台说谎时仍多数决。
  • iburst:刚启动时连发几包,加快第一次收敛。
  • makestep 1.0 3:前 3 次若偏差 >1 秒允许跳变,之后改用平滑微调(纪律环)。
  • stratum 只是到根的跳数;真正看精度要盯 dispersion / jitter,不是数字越小就一定更准。

案例 3:NTP 给不出误差上界(对照 TrueTime)

Section titled “案例 3:NTP 给不出误差上界(对照 TrueTime)”
维度NTPTrueTime
输出单点估计(now)区间 [earliest, latest]
精度公网毫秒,LAN 亚毫秒数据中心约 7ms 区间宽度
用途通用计时跨大陆事务序(commit-wait)

逐部分解释:NTP 应用层通常只拿到“现在大概是 X”;TrueTime 把不确定区间显式返回。强一致数据库要的是上界,不是点估计——这就是 Spanner 另起炉灶的原因。

  1. 对称路径假设是脆弱前提:家庭宽带 100M 下行 / 10M 上行,路径不对称,offset 估计会系统性偏移;多上游互投票能抵消大部分。
  2. stratum 不等于精度:监控要看 dispersion / jitter,别只盯 stratum 数字。
  3. NTP 不能给强一致数据库做事务序:毫秒级误差对秒级业务足够,但纳秒级事务要 HLC 或 TrueTime;2010 年代很多团队在这上面栽过跟头。
  4. DDoS 反射放大:早期 NTP 有 monlist 等查询,请求几十字节回应几千字节,2014 年被滥用打出 400Gbps 级攻击;公网部署必须关掉这些查询、加速率限制、上 NTS(RFC 8915,给 NTP 套 TLS)。

适用

  • 通用服务器/桌面/手机的时间同步(毫秒级够用)
  • 日志系统的时间排序(容忍亚秒级偏差)
  • 大多数对时间精度要求”差不多就行”的业务

不适用

  • 强一致分布式数据库的事务序 → 用 TrueTime / HLC
  • 金融交易、5G 基站、PTP 网络 → 用 PTP(IEEE 1588,硬件时间戳,亚微秒)
  • 需要”误差上界”的场景 → NTP 只给点估计,不给区间
  • 1985 年:Mills 在 Univ of Delaware 部署 NTPv0,从 ARPA 时代就在做。
  • 1991 年:这篇 IEEE Trans on Communications 论文把多年工程经验形式化,是 NTP 进入主流学界的标志性文献。
  • 1992 年:NTPv3 RFC 1305 发布,是这篇论文的标准化版本。
  • 2010 年:Mills 出 Computer Network Time Synchronization 专著,被誉为”互联网计时之父”。
  • 2010 年代:Spanner TrueTime / HLC / NTS / PTP 等后续方案,都在不同维度补 NTP 的短板。
  1. 测量 + 滤波 + 控制环 是任何”在不可靠通道上估一个连续量”的通用模板(GPS、传感器融合、分布式追踪都用)
  2. 多上游冗余 + 投票 是分布式系统对抗 Byzantine 故障的最基本手段
  3. 不对称是真实世界默认状态——任何依赖”前向后向相等”的协议都要想清楚不对称时的退化
  4. 同一个抽象层不要让”工程足够”的方案去解”理论需要更强保证”的问题:NTP 不是为强一致设计的,强行用就会栽
  • 论文 PDF:Mills 1991 — Internet Time Synchronization
  • RFC 5905:NTPv4 标准(2010)
  • RFC 8915:NTS(NTP 的 TLS 安全层,2020)
  • 工具:chrony(现代 NTP 客户端,比传统 ntpd 收敛更快)
  • lamport-1978 —— 逻辑时钟:物理时钟之外的另一条思路
  • byzantine-generals-1982 —— 为什么至少要 3f+1 个上游才能容 f 个说谎者
  • spanner —— TrueTime 用 GPS+原子钟把”误差区间”显式暴露给上层
  • lamport-1978 —— Lamport 逻辑时钟,与 NTP 的物理时钟互补
  • fidge-1988 —— 向量时钟,捕捉因果序而非真实时刻
  • mattern-1989 —— 分布式快照中的时间一致问题
  • chandy-lamport-1985 —— 全局快照算法,假设有近似同步时钟
  • byzantine-generals-1982 —— NTP selection 阶段去 falseticker 的理论依据
  • spanner —— 后 NTP 时代如何获得”误差上界”
  • hlc-2014 —— Hybrid Logical Clock,把物理与逻辑时钟揉到一起
  • tcp —— NTP 不用 TCP 而用 UDP 的设计取舍
  • dns —— 同样靠层级 + 缓存解决全球分发的协议

(暂无反向链接)