fangpsh's blog

集群的NTP 对时问题

NTP 简单介绍

NTP 是互联网上设备之间进行对时的协议,如下图所表示,有多层NTP 服务器,下游服务器向上游进行对时(可以了解一下stratum 值)。
NTP

我们假设上游的服务器时间是可靠的,我们所要做的就是尽量使本地计算机时间和上游服务器时间一致,原理如下图(图片来自wikipedia):

NTP-Algorithm

  • t0 是客户端发送请求包时的客户端时间戳;
  • t1 是服务端收到请求包时的服务端时间戳;
  • t2 是服务端发送响应包时的服务端时间戳;
  • t3 是客户端收到响应包时的客户端时间戳。

如果我们假设数据包传输来回所花的时间一样(注意:这是主要的误差原因),并且客户端和服务端处理数据包的时间一致, 那么客户端和服务端的时间差就是:

(t1-t0)+(t2-t3)/2

简单推导下公式:

设服务端-客户端时间差为:offset
设请求包在网络上的传输时间为:s0
设响应包在网络上的传输时间为: s1

按条件得:
t0 + s0 = t1 - offset  => offset = t0 + s0 -t1
t2 + s1 = t3 + offset  => offset = t3 - t2 -s1

=> offset = (t0 - t1 + t3 - t2 + s0 - s1)/2

如果s0 - s1 = 0,即来回传输包所话的时间相等,那么对时的误差会相对来说小一点,但是在一些糟糕的网络环境下,例如移动网络,这个传输时间差常常很大,几百毫秒都有可能,所以在选择 移动端对时的方案时需注意这个问题。

服务端和客户端传输来回所花的时间为:( t3 - t0 ) - (t2 - t1)
这个时间在ntpd server 选择上游ntpd 服务器的算法中可作为重要的考察指标。我们知道如果来回传输总的延时增大,来回传输数据包所花时间差值增大的概率也随之增加。
关于NTP 协议的详细介绍可以参考:

服务器对时设置

首先需要考虑的是服务器整个集群时间一致性的问题,然后才是服务器时间和标准时间误差的问题。

我们知道集群内网的环境一般都比较好,即可以减少上文中的 (s1 -s0) 的差,所以最好的选择是在内网搭建NTP Server,供集群内的所有服务器使用,这样可以保证整个集群内的时间一致。
注意:NTP Server 没必要情况下不要暴露在外网,如果需要给外网访问,做好授权,避免被作为NTP 反射攻击的工具。

这台NTP Server 也需要上游同步时间。这里有一个,Linux 常用的ntpd 程序只会在ntpd 启动时去解析上游服务器的域名,如果这些上游的服务器宕机了,或者更改IP 了,下游是无法主动发现的。
对于这个问题,首先是配置多几个优质的上游服务器,ntpd 本身对于上游服务器有一个选择策略,可以避免某几个上游宕机而同步不到时间。对于上游的这些服务器最好选择ntp.org 官方的,或者知名厂商或者组织的,总之就是求稳定和可靠,恶意的NTP 数据包影响不是小事。土豪可以自己上硬件授时的工具了,23333。
国内常见的NTP 服务器:

阿里:
time1~7.aliyun.com
分别位于阿里北上深杭青不同的机房,上游据说是GPS 还是北斗授时,相对可靠。

ntp.org:
cn.pool.ntp.org, 0.asia.pool.ntp.org, 1.asia.pool.ntp.org
更多请查看 http://www.pool.ntp.org

上海交大:
ntp.sjtu.edu.cn

另外一个措施是定期重启内网NTP Server 的进程
集群内的其他机器的ntp 进程,ntp.conf 设置优先从内网NTP Server 对时。另外需要设置为开机启动,并对进程状态做好监控,同时也记得控制好这些ntp 进程的安全,禁止外网的查询请求。这些机器的ntp.conf 内的上游服务器可以配置成和内网NTP Server 一致,防止内网NTP Server 长时间宕机。。。

其他参考质料: