神不知鬼不觉,阿里程序员把地球多出的1秒“变没”了

在谈到“闰秒”的时候,大部分人可能会有点陌生,也许大家都知道有“闰年”,“闰月”一说,但是可能还真没有想到还有“闰秒”这一说。事实上,这几年,随着科技的发展,尤其IT和金融业的突起,在计算精细的领域,对一秒也不容忽视,所以“闰秒”这个概念也被越来越多的人知道。对于阿里巴巴这么一个大体量的互联网公司,面对的挑战总是巨大的。下面我们来讲讲阿里巴巴是如何应对闰秒的。

秒的定义

为了让大家对“秒”有更深的理解,我们来回顾一下“秒”的历史,究竟是怎么过来的?“秒”究竟是如何定义的?

  • 1956年,秒定义为平均太阳日的1/86400
  • 1960至1967年之间,定义为1960 年地球自转一周时间的1/86400
  • 1967年,国际计量大会决定,以铯原子基态的两个超精细能级间在零磁场下跃迁辐射 9,192,631,770 周期所持续的时间。
  • 1977年,人类认识到了引力时间膨胀会导致在不同高度的原子钟时间不同,重新定义为”水平面的铯 原子”基态的两个超精细能级间在零磁场下跃迁辐射 9,192,631,770 周期所持续的时间。
  • 2019年,国际时间频率咨询委员会将讨论“秒”的重新定义问题。 随着人类认知的进步,对秒的定义逐渐发生了变化,从1967年开始,时间的计量标准便正式由天文学的宏观领域过渡到了物理学的微观领域。

随着科技的发展,科学家对“秒”的定义其实也在发生变化。

时间的定义

在这个地球上,每个地区,国家的人都有自己本地的时间。由于历史的原因,和近代国际组织对时间的统一,使得现在有多种对时间的定义方法。

UT(世界时)

UT(Universal Time,世界时)是一种以格林尼治子夜起算的平太阳时,由于以地球自转为基准,观测精度受限于地球的自转速度的稳定,地球体积不均匀、潮汐引力以及其他星球的扰动的原因,导致地球转速不稳定,每日误差达数毫秒。

TAI(国际原子时)

TAI(international atomic time)为国际原子时,1971年建立,利用某些元素(如铯、氢、铷)的原子能级跃迁频率有极高稳定性的特性定义时间标准,现为国际计量局(BIPM)的时间部门维持,综合全球约60个实验室中的大约240台各种自由运转的原子钟提供的数据进行处理,得出“国际时间标准”称为国际原子时 (TAI),每日误差为数纳秒。

TAI时间原点为UT 1958 年1月1日 00:00:00 ,在此之后TAI就沿着原子秒的节拍一直走下去,和UT误差也越来越大。

UTC(协调世界时)

上面已经说过,科学上有两种时间计量系统:基于天文测量而得出的“世界时”和以物理学发展发现的原子振荡周期固定这一特性而来的“原子时”,UTC就是用于将世界时(UT,天文时间)和国际原子时(TAI,原子时间)协调起来的另外一套计量系统, 1971年国际计量大会通过决议,使用UTC(协调世界时)来计量时间, 协调的原则就是UTC以原子秒长节拍,在时刻上尽量接近于世界时(UT)。

目前UTC是事实上的时间标准,比如所有计算机中的时间就是UTC时间(通过时区换算为本地时间), 而闰秒,实际上就是UTC特有的。

闰秒产生的原因是什么?

地球自转被称为“世界时间”。不过,由于潮汐、地壳运动、冰川融化、地震等自然现象,地球的自转速度并非恒定,而是有时快,有时慢。
1967 年原子钟的出现意味着人类计时不用再依赖于地球的自转,时间的计量标准正式由天文学的宏观领域过渡到物理学的微观领域,也就是所谓的“原子时间”。

细心的科学家发现,两者之间存在微妙差异。于是,国际地球自转和参考系服务会(IERS)在差异超过 0.9秒时,会协调“世界时间”加上或减去 1 秒,消除这个误差。

这多出来的1秒,就是闰秒。

第27次闰秒

闰秒究竟是多一秒,还是少一秒,也是有依据的,国际地球自转和参考系服务会(IERS)基于实际观测,地球自转和参考系服务会提前六个月公布下一次闰秒的时间。

通常在该年度的 6 月 30 日或 12 月 31 日午夜进行。

由于北京时间与格林尼治时间相差8小时,中国是在2017年1月1日迎来7时59分60秒的特殊现象。

最近四次闰秒分别发生在 2005 年 12 月 31 日、2008 年 12 月 31 日和 2012 年 6 月 30 日,2015年7月1日。

从 1988 年这一做法被确立至今,一共发生过 26 次闰秒。2017 年 1 月 1 日这次是第 27 次闰秒。

本次闰秒公告在 国家授时中心闰秒公告和IERS关于闰秒公告中有权威的发布。

由于我们在正八区,所以,闰秒时刻我们是在早上八点,所以这次闰秒实际是这样子的:

没错,我们的生活多了整整1秒哦~

闰秒的影响

北京时间2017年1月1日7时59分59秒后,全球同步多出1秒这事儿,对日常生活影响不大。但是对于IT,金融,航天行业,若处理不当,也可能引发危机。比如说,2012年闰秒发生时,包括LinkedIn在内不少国外知名网站都曾遇到故障。

因为“闰秒”不是一个规律的东西,而是那些科学家发现,“哎呀,今年地球转的有点快,我们年底要加个闰秒吧”,于是,“闰秒”就产生了。但是,程序员在写代码的时候,却没有考虑到会有闰秒,除了程序员写的代码,其实还有大量的操作系统处理不了闰秒也会有影响,会导致各种异常。

最常见的情况是,如果服务器操作系统是Linux,在一些老的内核版本中存在BUG无法处理闰秒,导致收到闰秒通告消息可能会宕机、插入闰秒可能会宕机、打印闰秒日志也能引发宕机。就说说红帽的老发行版,出现的“Systems hang due to leap-second livelock.,High CPU usage after inserting leap second”。

链接:https://access.redhat.com/solutions/154793

即便不宕机,在应用层,应用程序也可能无法处理这多出来的1s导致应用core掉。甚至可能影响到那些对时间敏感、事务性较强的应用,比如DB。

目前,国际大公司通用的解决方案是将这一秒分成许多份,再平均分配到一整天中。

日本有一家股票交易所将这一秒平均分成 7200 份,分摊到两个小时里,在分摊结束时间恢复同步时,刚好赶上开市。

Google则是在闰秒时刻前的24小时开始逐步调慢时间,理论上在闰秒时刻前,和标准UTC时间最大误差趋近于1秒。

阿里如何应对?

这次我们依然采用的方案是“将1秒拆分成86400份”应对本次闰秒,缓慢同步消除闰秒带来的 1 秒误差这一基本方案。

在NTP中存在两种时间同步机制:一种是“slew”,一种是“step”,虽然“slew”的方式也是缓慢的调整,但是面对阿里巴巴复杂的业务,这种方式并不能满足和解决这个问题,我们在5k集群下测试和验证,探索出一个更佳优秀的方案,就是将1s拆分成86400份。这个方案相比之间的“slew”的方案有如下改进:

  • 同步速率由 0.5ms/s 调整为 0.011574ms/s
  • 同步窗口由之前的 2000 秒调整为 86400 秒(24 小时)
  • 同步起止时刻由之前的闰秒时刻后,调整为闰秒时刻前 12 小时开始,闰秒时刻后 12 小时终止
  • 整个同步窗口和标准 UTC 时间的最大误差由之前的 1 秒减小到 0.5 秒(500 毫秒)

方案测试

在闰秒发生前2个月,我们对闰秒过度方案进行了多次测试,并且在超大规模的集群中测试,结合过去经验,根据我们的方案如果把在client的每分钟采集的时间和标准时间产生的offset数据汇总成图,可以看到时间的变化是极其缓慢和微小的。

横坐标: 时间,单位:分钟,24小时一共有1440分钟

纵坐标: offset, 单位:ms

方案实施

时间点 动作 结果
闰秒发生前36个小时 一级时间源切断GPS信号,使用内部铷钟守时。扫描内部节点,清除闰秒标志位。 消除闰秒标志位触发内核,程序BUG的潜在风险
闰秒发生前18个小时 二级时间源和一级时间源之间切段联系 二级时间源稳定守时
闰秒发生前12个小时 二级时间源之间聚合调整时间,使得时间以每秒调整 0.011574ms/s的速度开始整体调整时间 整体客户端开始跟随二级时间源缓慢调整
经过漫长的12个小时 整体集团时间和标准时间误差开始逐渐增大
闰秒时刻 此刻和标准时间误差达到最大值0.5s
经过漫长的12个小时 整体集团时间和标准时间误差开始逐渐减小
闰秒发生后12个小时 二级时间源上的缓慢调整停止,一级时间源和GPS建立连接 整体集团时间和标准时间误差几近为零
闰秒发生后13个小时 二级时间源和一级时间源建立连接 闰秒变更完成

对于阿里巴巴如此大体量的互联网公司,遇到的挑战总是更大的,在方案实施过程中我们也有发现了若干问题,在内部时间源时间聚合期间,个体时间服务器的时间变化收到本身硬件,以及网络,温度等,各种外部因素的影响。这些因素产生的影响也是要引起注意的。

7