AWS 内部时间同步机制 - Amazon Time Sync Service 与闰秒平滑处理的设计
解析 AWS 自主运营的 Amazon Time Sync Service 的工作原理、基于 GPS 和原子钟的高精度时间源、通过平滑处理吸收闰秒的设计决策,以及分布式系统中时间同步的重要性。
为什么时间同步在云中如此重要
在分布式系统中,精确的时间同步比想象中更为重要。CloudTrail 日志、CloudWatch 指标、DynamoDB 条件写入、S3 对象版本控制、TLS 证书有效期验证等,AWS 几乎所有服务都依赖于精确的时间。时间偏差会导致日志时序混乱,使故障排查变得困难。TLS 证书有效期检查可能误判,将正常证书判定为无效。Kerberos 认证 (Active Directory) 在客户端与服务器时间差超过 5 分钟时会拒绝认证。在分布式数据库中,时间偏差直接影响数据一致性。Google 的 Spanner 数据库使用原子钟和 GPS 提供 TrueTime API,正是为了通过时间精度来保证分布式事务的一致性。AWS 针对同样的挑战,提供了 Amazon Time Sync Service 这一自研解决方案。
Amazon Time Sync Service 的工作原理
Amazon Time Sync Service 是部署在各 AWS 区域的高精度时间源。EC2 实例可通过链路本地地址 169.254.169.123 访问 NTP (Network Time Protocol) 服务器。该地址与元数据服务的 169.254.169.254 类似,属于链路本地地址,不依赖网络配置,实例启动后即可使用。Time Sync Service 的时间源是部署在各区域的 GPS 天线和原子钟(铷或铯)。GPS 卫星搭载原子钟,提供纳秒级精度的时间信息。AWS 将 GPS 时间信息与本地原子钟进行比对,确保即使 GPS 信号暂时中断也能维持精确时间。从 EC2 实例到 Time Sync Service 的延迟在微秒级别,与互联网上的公共 NTP 服务器(如 pool.ntp.org)相比精度高出数个数量级。公共 NTP 服务器的精度极限为毫秒级,而 Time Sync Service 可达微秒级精度。
闰秒平滑处理 - 不产生 23:59:60 的设计
闰秒是为补偿地球自转速度变化而在 UTC(协调世界时)中插入 1 秒的机制。插入闰秒时,23:59:59 之后会出现通常不存在的 23:59:60。这个 23:59:60 对许多软件来说是意外值,历史上曾引发多起大规模故障。2012 年的闰秒因 Linux 内核 Bug 导致 Reddit、Mozilla、Yelp 等服务发生故障。Amazon Time Sync Service 通过「平滑处理」(smearing) 来处理闰秒。在闰秒前后各 12 小时内,将 1 秒均匀分散进行时间微调。也就是说,23:59:60 这个时刻不会出现,取而代之的是在 24 小时内完成 1 秒的调整。每秒比正常长约 11.6 微秒,但这个差异对大多数应用来说可以忽略不计。Google 的 NTP 服务器也采用类似的平滑处理,但方式(线性、余弦波等)不同,混用不同平滑方式的 NTP 服务器会导致时间不一致。在 AWS 环境中建议仅使用 Time Sync Service。
ClockBound - 可视化时间的不确定性
2021 年 AWS 开源发布的 ClockBound 是一个提供当前时间「不确定性范围」的守护进程。通过 NTP 同步的时间包含网络延迟和时钟漂移带来的误差。ClockBound 计算该误差的上下限,提供「当前真实时间在 X ± Y 微秒范围内」的信息。该信息可用于分布式数据库的事务排序。如果两个事件时间戳的差值在不确定性范围内,则无法确定哪个先发生;超出不确定性范围则可以确定顺序。这与 Google Spanner 的 TrueTime API 概念类似,但 ClockBound 是开源的,可在 AWS 以外的环境使用。DynamoDB 和 Aurora 等 AWS 托管服务在内部已考虑了这种时间不确定性,但用户自建分布式系统时,可利用 ClockBound 防止因时间导致的数据不一致。
时间同步失败引发的实际问题
时间同步问题的症状不明显,原因难以定位。以下介绍几种实际发生的问题模式。第一,TLS 证书验证失败。实例时间偏向未来时,仍有效的证书会被判定为「已过期」;偏向过去时,会被判定为「尚未生效」。HTTPS 通信突然失败时,时间偏差可能是原因。第二,AWS API 认证失败。SigV4 签名包含时间戳,请求时间戳与 AWS 服务器时间差超过 5 分钟时,请求会被拒绝。第三,日志时序混乱。汇聚多个实例的日志时,时间偏差的实例日志无法按时间顺序排列,使故障排查变得困难。对策是在所有 EC2 实例上配置 chrony (NTP 客户端),将 Amazon Time Sync Service (169.254.169.123) 作为唯一时间源。Amazon Linux 2 及以后版本已默认配置。如需系统学习时间同步与分布式系统设计,可参考专业书籍 (Amazon)。