2.6 不说谎的中继站:透明时钟如何工作
一个“诚实“的问题
假设你给朋友寄了一封信。
信从北京出发,经过上海、广州、深圳三个中转站,最终到达朋友手中。
朋友收到信后,想知道这封信在路上走了多久。但他只看到信封上的邮戳:北京发信时间是1月1日,他收到时间是1月5日。这4天的差距,包含了真正的运输时间,也包含了在中转站的停留时间。
问题来了:中转站会诚实地告诉你,信在它那里停留了多久吗?
在传统的邮政系统,答案是:通常不会。
但在PTP网络中,有一种设备会主动、精确、诚实地告诉你:它叫透明时钟(Transparent Clock)。
透明时钟:一个“透明“的中继站
透明时钟的核心任务
透明时钟的核心任务只有一项:测量PTP报文在它内部停留的时间,并告诉下游设备。
这听起来很简单,但实际上非常重要。
为什么需要透明时钟?
场景一:没有透明时钟
主时钟 ---- 交换机A ---- 交换机B ---- 交换机C ---- 从时钟
假设:
- 主到从的真实传播延迟(光在光纤中传播):100ns
- 每个交换机的处理延迟:1μs到10μs不等(抖动大)
- 3个交换机,总处理延迟:3μs到30μs,变化范围27μs
从时钟测量到的路径延迟:100ns + (3μs到30μs) = 3.1μs到30.1μs
问题:
- 路径延迟的抖动:27μs
- 这27μs的抖动会直接加到offsetFromMaster上
- 同步精度被限制在27μs左右
场景二:有透明时钟
主时钟 ---- TC_A ---- TC_B ---- TC_C ---- 从时钟
透明时钟会:
- 记录报文进入时间戳
- 记录报文离开时间戳
- 计算驻留时间
- 将驻留时间写入报文的correctionField
从时钟收到报文后,知道:
- 真实传播延迟:100ns
- 在TC_A的驻留时间:5.2μs
- 在TC_B的驻留时间:3.8μs
- 在TC_C的驻留时间:6.1μs
- 总驻留时间:15.1μs
从时钟在计算offsetFromMaster时,会减去这15.1μs。
结果:
- 驻留时间被精确测量和补偿
- 剩余的不确定性只是:时间戳测量误差(通常<10ns)
- 同步精度可以接近时间戳精度(纳秒级)
透明时钟 vs 边界时钟
你可能问:边界时钟不也可以做这个事吗?
答案:可以,但成本和效果不同。
边界时钟的做法
边界时钟会:
- 接收上游的Sync报文
- 调整自己的本地时钟
- 生成新的Sync报文,发送给下游
问题:
- 边界时钟需要高精度的本地时钟(成本高)
- 边界时钟需要参与BMCA(复杂)
- 边界时钟会成为新的“主时钟“,层级增加
优点:
- 可以隔离误差累积
- 可以连接不同网络
透明时钟的做法
透明时钟会:
- 接收Sync报文
- 记录进入和离开时间戳
- 将驻留时间写入correctionField
- 转发Sync报文(不生成新报文)
优点:
- 不需要高精度本地时钟(成本低)
- 不参与BMCA(简单)
- 不增加层级
缺点:
- 不能隔离误差累积
- 不能连接不同网络
选择建议
| 场景 | 推荐使用 |
|---|---|
| 网络规模小,成本低 | 透明时钟 |
| 需要隔离误差累积 | 边界时钟 |
| 需要连接不同网络 | 边界时钟 |
| 已有普通交换机,升级PTP | 透明时钟 |
| 电信级高精度网络 | 边界时钟 + 透明时钟 |
透明时钟的两种类型
PTP定义了两种透明时钟:
E2E透明时钟(End-to-End Transparent Clock)
特点:
- 支持所有PTP报文类型
- 转发Announce、Sync、Follow_Up、Delay_Req、Delay_Resp等
- 只测量驻留时间,不测量链路延迟
工作原理:
对Sync报文的处理:
- Sync报文进入E2E TC,记录ingress时间戳(t1)
- Sync报文离开E2E TC,记录egress时间戳(t2)
- 计算驻留时间:residenceTime = t2 - t1
- 更新correctionField:correctionField += residenceTime
- 转发Sync报文
对Delay_Req报文的处理:
同Sync报文,也测量驻留时间并更新correctionField。
关键公式:
Sync.correctionField(出口) = Sync.correctionField(入口) + residenceTime
注意:如果入口报文和出口报文的twoStepFlag不同,处理会更复杂(见后续详解)。
P2P透明时钟(Peer-to-Peer Transparent Clock)
特点:
- 支持部分PTP报文类型:Announce、Sync、Follow_Up、Signaling、Management
- 丢弃Delay_Req和Delay_Resp报文
- 测量驻留时间和链路延迟
工作原理:
对Sync报文的处理:
- Sync报文进入P2P TC,记录ingress时间戳(t1)
- Sync报文离开P2P TC,记录egress时间戳(t2)
- 计算驻留时间:residenceTime = t2 - t1
- 获取入口链路延迟:meanLinkDelay(通过P2P延迟机制测量)
- 更新correctionField:correctionField += residenceTime + meanLinkDelay
- 转发Sync报文
对Delay_Req报文的处理:
丢弃,不转发。
关键公式:
Sync.correctionField(出口) = Sync.correctionField(入口) + residenceTime + meanLinkDelay
为什么P2P TC要丢弃Delay_Req?
因为P2P机制是逐链路测量延迟。每个P2P TC都知道自己两边链路的延迟(meanLinkDelay)。
当P2P TC转发Sync报文时,它会把“驻留时间 + 入口链路延迟“一起写入correctionField。
这样,下游设备就不需要再发Delay_Req来测量整个路径延迟了——因为路径延迟已经被P2P TC逐段累加到correctionField中了。
为什么E2E TC不丢弃Delay_Req?
因为E2E机制是端到端测量延迟。从时钟需要发送Delay_Req,主时钟回复Delay_Resp,测量整个路径的延迟。
E2E TC只负责测量驻留时间,不参与延迟测量,所以必须转发Delay_Req和Delay_Resp。
驻留时间测量:细节决定精度
时间戳生成的关键
驻留时间的测量精度,取决于时间戳生成的精度。
时间戳生成点:
PTP标准规定,时间戳应该在消息时间戳点通过参考平面时生成。
消息时间戳点:
- 对于以太网:帧起始分隔符(SFD)后的第一个符号的开始
参考平面:
- PTP实例与网络的边界
- 通常在PHY层(物理层)
理想情况:
在PHY层生成时间戳,不经过任何软件延迟。
实际情况:
有些设备无法在PHY层生成时间戳,只能在MAC层或更高层生成。这时需要测量并校正延迟。
时间戳校正
如果时间戳在MAC层生成,而不是PHY层,需要校正:
实际时间戳(参考平面) = 捕获的时间戳 + 校正延迟
校正延迟的测量:
设备制造商需要测量:
- ingressLatency:从参考平面到MAC层的延迟
- egressLatency:从MAC层到参考平面的延迟
这些延迟可以通过校准过程测量,并写入timestampCorrectionPortDS数据集。
correctionField的处理:累加的艺术
correctionField的含义
correctionField是PTP报文头部的一个8字节字段,用于携带各种校正值。
单位:纳秒 × 2¹⁶(即支持亚纳秒精度)
典型内容:
- 小数纳秒部分(originTimestamp的补充)
- 透明时钟的驻留时间
- 路径不对称校正值
E2E TC的correctionField处理
对Sync报文
one-step模式(Sync报文本身携带时间戳):
Sync.correctionField(出口) = Sync.correctionField(入口) + residenceTime + ingressAsymmetry
two-step模式(Sync后跟Follow_Up):
情况1:入口twoStepFlag=FALSE,出口twoStepFlag=TRUE
透明时钟需要“升级“为two-step模式:
- Sync.twoStepFlag设为TRUE
- 创建Follow_Up报文,携带residenceTime + ingressAsymmetry
情况2:入口twoStepFlag=TRUE,出口twoStepFlag=TRUE
透明时钟需要关联Sync和Follow_Up:
- 收到Sync时,记录correctionField和sequenceId
- 收到对应的Follow_Up时,更新Follow_Up.correctionField
- 转发Follow_Up
情况3:入口twoStepFlag=TRUE,出口twoStepFlag=FALSE
透明时钟需要“降级“为one-step模式:
- 等待Follow_Up到达
- 将Sync.correctionField和Follow_Up.correctionField合并
- Sync.twoStepFlag设为FALSE
- 转发Sync
情况4:入口twoStepFlag=FALSE,出口twoStepFlag=FALSE
最简单的情况:
- 直接更新Sync.correctionField
- 转发Sync
对Delay_Req报文
关键区别:Delay_Req使用egressAsymmetry(出口不对称),而不是ingressAsymmetry(入口不对称)。
公式:
Delay_Req.correctionField(出口) = Delay_Req.correctionField(入口) + residenceTime - egressAsymmetry
为什么符号不同?
- Sync:主→从方向,入口不对称是正向延迟的一部分,需要加上
- Delay_Req:从→主方向,出口不对称需要减去才能得到真实延迟
P2P TC的correctionField处理
对Sync报文
Sync.correctionField(出口) = Sync.correctionField(入口) + residenceTime + ingressAsymmetry + meanLinkDelay
关键:P2P TC会加上入口链路延迟(meanLinkDelay)。
这样,下游设备收到的Sync报文,correctionField已经包含了:
- 上游所有透明时钟的驻留时间
- 上游所有链路的延迟
下游设备只需要:
- 从Sync报文提取时间戳
- 减去correctionField
- 就能得到主时钟的真实发送时间
不需要发送Delay_Req。
路径不对称校正
什么是不对称?
定义:报文从主时钟到从时钟的延迟,与从时钟到主时钟的延迟不相等。
原因:
- 光纤长度不同(不同方向使用不同光纤)
- 光波长不同(波分复用,不同波长速度不同)
- 交换机处理延迟不同
- 无线链路上下行带宽不同
不对称的影响
PTP计算路径延迟时,假设对称:
meanPathDelay = [(t2 - t1) + (t4 - t3)] / 2
如果不对称:
- t_ms(主→从)≠ t_sm(从→主)
- 但公式仍然计算平均值
结果:计算的meanPathDelay不等于真实延迟。
透明时钟如何处理不对称?
E2E TC:
- 在Sync报文中加上ingressAsymmetry
- 在Delay_Req报文中减去egressAsymmetry
P2P TC:
- 在Sync报文中加上ingressAsymmetry
- meanLinkDelay的测量也需要考虑不对称
不对称值的来源:
- 配置值:管理员通过管理接口配置
- Profile规定:特定应用场景的默认值
- 动态计算:某些介质支持动态计算(如16.8选项)
一个完整的透明时钟处理示例
场景
主时钟A ---- TC_B ---- TC_C ---- 从时钟D
参数:
- 主时钟A发送Sync时间:t1 = 1000.000000000秒
- TC_B驻留时间:5μs
- TC_C驻留时间:3μs
- A→B链路延迟:100ns
- B→C链路延迟:150ns
- C→D链路延迟:120ns
- 光传播延迟(忽略):约5ns/米
P2P TC的处理
TC_B:
收到Sync报文:
- originTimestamp = 1000.000000000秒
- correctionField = 0(初始)
测量:
- residenceTime = 5μs
- meanLinkDelay(A→B)= 100ns
- ingressAsymmetry(假设)= 0
更新correctionField:
correctionField = 0 + 5μs + 0 + 100ns = 5.1μs
转发Sync报文。
TC_C:
收到Sync报文:
- originTimestamp = 1000.000000000秒
- correctionField = 5.1μs
测量:
- residenceTime = 3μs
- meanLinkDelay(B→C)= 150ns
- ingressAsymmetry(假设)= 0
更新correctionField:
correctionField = 5.1μs + 3μs + 0 + 150ns = 8.25μs
转发Sync报文。
从时钟D:
收到Sync报文:
- originTimestamp = 1000.000000000秒
- correctionField = 8.25μs
- 接收时间戳:t2 = 1000.000008470秒(假设)
计算:
主时钟发送时间(校正后) = originTimestamp + correctionField
= 1000.000000000 + 0.00000825
= 1000.000008250秒
路径延迟(C→D)= 120ns(由P2P机制测量)
主时钟真实发送时间 = 1000.000008250 + 0.000000120 = 1000.000008370秒
offsetFromMaster = t2 - 主时钟真实发送时间
= 1000.000008470 - 1000.000008370
= 100ns
从时钟D知道:自己比主时钟快了100ns,需要减去100ns。
如果没有透明时钟
假设TC_B和TC_C是普通交换机,不测量驻留时间。
从时钟D测量路径延迟:
- 真实传播延迟:100ns + 150ns + 120ns = 370ns
- 交换机驻留时间:5μs + 3μs = 8μs(但不知道)
- 测量的meanPathDelay ≈ 8.37μs(包含驻留时间)
计算offsetFromMaster:
- 假设t2 = 1000.000008470秒
- meanPathDelay = 8.37μs
- offsetFromMaster = t2 - t1 - meanPathDelay = 1000.000008470 - 1000.000000000 - 0.00000837 = 100ns
但实际上,真实的offsetFromMaster应该是340ns。
误差:340ns - 100ns = 240ns
这个误差就是由于交换机驻留时间没有被测量和补偿导致的。
透明时钟实现的关键挑战
挑战一:时间戳生成精度
驻留时间的测量精度,直接取决于时间戳生成精度。
要求:
- 时间戳分辨率:至少纳秒级
- 时间戳抖动:<10ns
- 时间戳时钟:可以是自由运行的Local Clock
解决方案:
- 使用硬件时间戳(PHY层)
- 使用高分辨率计数器
- 校正内部延迟
挑战二:报文关联
对于two-step模式,透明时钟需要关联Sync和Follow_Up报文。
关联条件:
- sourcePortIdentity相同
- sequenceId相同
实现:
- 维护一个缓存表,存储Sync报文的信息
- 收到Follow_Up时,查找对应的Sync
- 更新Follow_Up的correctionField,然后转发
注意:缓存表需要超时清理,避免内存泄漏。
挑战三:correctionField溢出
correctionField是64位有符号整数,理论范围:约±9.2毫秒。
如果透明时钟数量很多,或者驻留时间很长,可能溢出。
解决方案:
- 使用足够大的数据类型存储中间结果
- 检测溢出,丢弃报文或触发告警
挑战四:不对称测量
P2P TC需要测量链路延迟(meanLinkDelay),但这个测量也可能受不对称影响。
解决方案:
- 对于P2P机制,不对称会相互抵消(见11.4.2的分析)
- 但如果要求极高精度,仍需要额外的不对称校正值
小结:透明时钟的核心要点
透明时钟的作用:
- 测量PTP报文的驻留时间
- 更新correctionField
- 消除交换机处理延迟的不确定性
两种类型:
- E2E TC:转发所有报文,测量驻留时间
- P2P TC:丢弃Delay_Req,测量驻留时间+链路延迟
关键公式:
E2E TC:
Sync.correctionField += residenceTime + ingressAsymmetry
Delay_Req.correctionField += residenceTime - egressAsymmetry
P2P TC:
Sync.correctionField += residenceTime + ingressAsymmetry + meanLinkDelay
关键挑战:
- 时间戳生成精度
- 报文关联(two-step模式)
- correctionField溢出
- 不对称测量
下集预告
现在,我们知道了透明时钟如何测量驻留时间和链路延迟。
但还有一个核心问题:从时钟如何测量到主时钟的路径延迟?
下一节,我们将深入讲解E2E延迟测量机制——如何用四个时间戳,精确测量端到端路径延迟。
【悬念留给2.7】
你可能好奇:为什么需要四个时间戳(t1, t2, t3, t4),而不是两个?
答案是:因为主时钟和从时钟的时间还没有对齐。
如果主时钟和从时钟的时间已经一致了,那只需要两个时间戳就够了。但问题是:PTP协议的目的就是让主从时钟对齐,而在对齐之前,主从时钟的时间是有偏差的。
四个时间戳的设计,巧妙地绕过了这个问题,即使不知道时间偏差,也能计算出路径延迟。
下一节,我们详细解读这个精妙的数学设计。