背景
BIGO的服务器分布在全球各地,各种服务如分布式追踪等都对全球机器存在时钟对齐的需求。而客观上,受限于服务器本身的时间源设备精度以及内核时钟系统的软件设计实现等多种复杂因素制约,常见的服务器秒级别的设备时钟误差大约在万分之二左右,而累积误差会出现正反向补偿,根据经验观测值,一年存在至少分钟级别的时钟误差。
此类问题最常见的解决手段就是接入网络授时服务如NTP,但是作为一个全球分布几万+服务器的公司,简单接入NTP服务,并不能彻底解决全球时钟对齐的问题。
BIGO的服务器很早期就接入了time.nist.gov的NTP网络时间同步服务,但是观测到公司内部的机器普遍存在百毫秒级别的时钟误差,单机视图存在时间跳变等问题,而且误差分布几乎是随机的,同机房内部都可能出现极大误差。
基于以上现状,结合BIGO的业务需求,我们的全球时钟true time服务开启调研和建设。在业界相关领域,google的spanner论文有提到true time服务的建设,facebook也有公开过chrony时钟对齐服务解决方案。前者核心是依赖全球多机房部署原子钟+GPS构建了一个双层的架构,配合Marzullo变种算法来提供7ms时间区间服务。而后者本质上也是基于原子钟+GPS构建了一个最高可以达到16层的架构来提供true time服务。
业界的现有技术方案,一方面存在硬件设备依赖,另一方面直接作为开箱即用的时间源在BIGO实际场景会制约我们的服务部署情况。于是我们基于外部NTP网络时间源+内部UTC时间源集群+多PTP集群的方案来构建了BIGO自己的全球true time时钟对齐服务,目标是在不依赖内部原子钟的前提下,把BIGO全球机器99.99%场景时钟误差控制在亚毫秒。
该基础能力的建设,可以应用于BIGO内部不少场景:
1) 解决分布式追踪场景的时间误差问题;
2) 可以赋能BIGO的音视频优化直播帧时间戳跳变引起的卡顿问题,以及音视频和文件传输在重传准确率,拥塞控制等方向的提升;
3) 解决时间跳变问题,提升BIGO基础框架等服务的稳定性,避免跳变引起的服务卡顿和挂死。
NTP
在了解时钟对齐相关原理时,NTP协议(Network Time Protocal)和相应的ntpd和ntpdate服务是必须要了解的。这里我们简单回顾一下相关原理。
NTP协议的提出是为了解决这样一个问题:已知有一个基准服务器A,A的时间是准确的,怎么通过网络让B本地时钟跟A对齐?
聪明的读者可能已经很快想到答案,B发包询问A,A把本地时间回给B就搞定了。但是问题没有这么简单,B->A的网络包延时d1,A->B的网络包延时d2,甚至A收到请求再回包过程的耗时d3都会导致B拿到的时间存在误差。
针对此问题David L. Mills提出了NTP协议,最早出现在rfc958。
图1是单次NTP授时过程,首先B向A发送一个NTP包,包里包含了离开B的本地时间戳T1。A收到NTP请求包之后,依次记录包到达的本地时间戳T2,回包离开的时间戳T3,然后立即把包返回给B。B收到回包后,记录本地时间戳T4。
其中我们把d1=T2-T1定义为上行延时,d2=T4-T3定义为下行延时。假设A-B的时钟绝对误差为diff,则有如下公式:
d=d1+d2
T2=T1+diff+d1
T4=T3-diff+d2
如上推算,A-B的时钟误差公式求解如下:
假设网络的上下行延时对等无波动,即d1=d2,则A-B的时钟误差近似值diff_appro跟diff相等,diff_appro的表达公式如下:
在单次的ntp对齐过程中,工程上往往基于diff_appro公式去计算A-B的时钟差,此时并未剔除上下行网络波动的影响,我们把diff称为A,B机对齐前时钟误差(简称前误差),把diff_appro-diff称为A,B机对齐后的时钟误差(简称后误差)。
后误差的公式表达为diff_appro-diff=(d1-d2)/2,当d1或者d2等于d时,后误差最大为±d/2。
NTP算法简单来说,就是基于diff_appro公式计算diff值,并对B机的时钟做出加diff_appro的调整,从而让B机的时钟向A机尽量对齐。对齐过程还会存在后误差(diff_appro-diff),后误差最大可以到±d/2。
看到这里,可能聪明的读者要发出灵魂拷问了,A直接回时间给B,B完全不考虑任何误差直接使用A返回的时间设置为本机时间,这个过程存在的误差也就是d2而已,最大误差可以换算为d。这NTP绕了这么一圈,仅仅是把后误差缩小到到d/2而已,反正是不准,优化一半的精度似乎没什么价值。
其实本质不是这样的,仅仅关注最大误差确实只优化了一半的精度。但是直接使用A返回的时间,A和B的时钟误差是恒等于d2的,而NTP的时钟误差本质上是跟上行延时和下行延时的差值成正比,网络延时是永恒存在的,而上下行延时差值(简述为网络波动)却不一定是永恒存在的,只要配合一些多次采样平滑调整,是可以基于NTP把时钟对齐的精度控制在比较理想的范围的。
ntpd和ntpdate就是2种基于ntp协议封装的时钟对齐服务方式,前者利用了多时钟源以及一些平滑算法来规避对齐过程中的时钟跳变问题。而后者仅仅是对ntp协议过程的定期应用,容易存在误差和跳变。
架构权衡与设计
前面提到BIGO一开始全球机器都基于ntpdate接入了time.nist.gov,但是效果显而易见是不好的,普遍存在百毫秒误差,时钟跳变,误差无视机房,每个问题都很致命。
那么简单换成ntpd会不会变好,我们的实践表明ntpd本机房同步误差可以控制在毫秒级别,但是跨大区同步存在10毫秒级别的误差,虽然对比ntpdate会有改善,但是这个效果还不够满足业务需求。或者我们的服务器可以物理距离跟ntp源保持靠近部署,但这不是一个好扩展的服务架构,也不符合我们全球多机房的运维现状。
我们后续还尝试引入facebook的chrony(facebook提供的一种NTP时间源)作为时间源,其对比ntpd有更优秀的同步算法,但是我们验证跨大区同步的误差依然在6毫秒级别,主要原因在于公网跨大区上下行delay差异导致。此外chrony对第三方使用者的调优成本较高,其提供了如mindelay等十几种同步模式,缺乏最佳实践指引。
简单总结一些权衡,如果要开箱即用一些ntp源服务,则BIGO的服务器部署会受到限制,如部署地点,同步频率等。因此我们在这一期放弃了全网直接使用相关ntp服务,而是开始在BIGO内部分层构建true time服务。
架构上,我们要在没有内部原子钟设备的前提下,解决2个问题。
1. BIGO的机器时间要和UTC时间保持较高精度的同步;
2. BIGO各个内部机器之间的时间要尽量保持较高精度同步,且ping延时越小的机器之间精度要求越高。
问题1即时间源的问题,google spanner里的true time的处理方式是依赖硬件设备,引入原子钟+GPS组成分布全球的master群,利用原子钟和GPS故障概率和故障原因存在差异这个特性做双保险保障master可用性。同时master和daemon(即slave)都会通过一些算法识别明显异常的时钟,从而在内部建设了一套全球高可用的高精度时间源。
而BIGO在面对这个问题时,尚没有大规模的原子钟设备,为了低成本的解决时间源问题,最终我们选择了建设一个单机房的时间源,我们称为super master。super master为了保证可用性,应该是集群。Super master的时间并不是来自自身的时钟,而是基于ntpd跟一个物理距离上最接近的NTP源做时钟对齐。
至此,我们在没有原子钟的情况下,得到了一个可用性对比google spanner里的 true time稍差一点的时间源。
问题2,我们希望按机房分层建设架构。最终确定在每个机房建设一些master节点,本机房的其他节点(我们称为slave)只会跟这些master做时钟同步,基于PTP协议来进行。看到这里可能读者会疑惑,PTP是个什么协议,这里不急,后面会有篇幅对该协议做一个回顾,你可以先简单理解PTP是在NTP上做的一种工程优化,其比较适合子网内的高精度时钟同步(在毫秒内精度进一步提升),支持广播,单播等工作模式。
最终,我们得到BIGO true time服务一期架构图如下:
架构里的相关名词解释如下:
NTP源——基于ntpd或者ntpdate形式提供时钟对齐服务的标准机构(例如time.nist.gov是由美国国家标准技术研究所提供),NTP源的时间同步报文里包含的时间是UTC时间(等效于GMT格林威治时间)。
Super Master——角色定位为BIGO内部的可靠UTC时间源,前面说了,super master是没有原子钟的,基于ntpd跟物理最近的NTP源做UTC时钟同步。Super master一期暂时是单机房的,后面为了更高的可用性,会规划多机房的分布式UTC源架构。
Name Service——BIGO内部的分布式名字服务,具体架构不细讲了,可以对标Etcd等架构,这里该模块主要用于给master发现super master做ptp单播时钟同步用。
Master——某个机房内的时钟源,仅仅服务本机房的节点。一个机房内可以有多个master存在。Master会定期基于PTP单播配合我们的平滑算法去super master做时钟同步,同时,也会秒级对子网内做ptp的sync广播达成master和slave的时钟同步。
关于master的选举决策,这里涉及到PTP里的BMC算法,原则上一个机房不需要唯一的master,该算法不同于其他分布式强一致算法如paxos,不需要达成全局唯一共识。关于BMC选举master机制我们后面会展开讲解。
Slave——机房里的普通服务器,会周期秒级收到同机房master的PTP sync同步广播,达成时钟同步,当前由于只会在同机房做时钟同步,该过程暂未做平滑处理。
机房内Master选举
提起Master选举,可能很多读者会想到Raft,Paxos等相关技术方案。而在我们这个具体的问题领域,关于在一堆机器里选出合适的主机作为master来成为时钟源,比较经典的是IEEE1588里的BMC(Best Master Clock)算法。
该算法比较适合子网内部Master选举的特点,只负责选出确定的Master群,并动态保障slave一定可以较快找到可用的Master,但是不考虑slave使用的master是否是最优解,BIGO内部为该算法设计了保底策略,用于规避极端情况长期使用较差的master。
BMC算法本身为每台机器设置了几个属性:
1)机器优先级:根据机器属性赋予机器的一个优先级,值越小优先级越高;
2)分组优先级:对机器进行分组,每个组有一个优先级值越小优先级越高;
3)唯一标识:进程的唯一标识,一般使用MAC地址。
BIGO这边由于子网天然是同机房的,所以1和2默认都是不配置的,基于保底策略来动态解决机器网络状况波动问题。
原始的BMC算法选主流程如下:
1) 进程接收子网内的master的广播信息,并加入自身的foreignMaster列表;
2)进程根据foreignMaster列表信息(可能为空)和本进程信息通过BMC算法按机器属性选择出最优的master;
3)如果进程成为master的话,则开始广播信息。
图3是选主过程的状态迁移图,子网内任何一台机器都会周期的check自身的foreignMaster列表,选出当前的自己的master(可以是自己),然后相应把自身角色设置为master(slave)。
该算法集群多机状态收敛过程还是比较清晰简单的。
1) 初始的时候,不考虑引入任何随机退让算法,子网内所有机器都没有收到任何master的announce请求,则会将自己提升为master,并开始广播自己的信息。此时,子网内全部机器都是master;
2) 子网内的机器开始陆续收到子网内master的信息,在这过程中,不断执行bmc算法,进而将更优的进程设置为master,最后一般在几个广播周期内,整个集群的master,slvae状态达到稳定。
下面的图4简要的展示了BMC算法从初始化到收敛过程:
总结来看,BMC算法优点就是快速,简洁,而由于选主条件是静态的(如MAC地址大小),无法保证选出的master是网络情况最优的,这种算法在子网内比较合适。
为了保证该算法在网络变化后可以剔除掉明显异常的Master点,BIGO尝试引入网络波动保底策略。即在保持BMC算法主流程情况下,引入master->slave的网络波动情况来优化master选择策略。
为什么基于网络波动来做选主决策,而不考虑网络延时大小,根据我们前面描述的NTP原理,读者应该清楚,时钟同步的误差受上下行网络差值影响较大,而延时的绝对大小是没有影响的。
BIGO这边会基于PTP的delay过程(后面一节PTP协议会详细讲解),在本机维护slave跟他foreignMaster列表的机器的历史delay值集合——foreignMaster’s delay_list。然后基于标准方差公式计算每台master的delay方差S(关于方差的概念,本文不再赘述)。我们认为方差S可以较好的表达foreignMaster的网络波动。
在原BMC选主过程,BIGO会额外判断目标master的方差S是否超出了阈值,如果是则会把该Master机器从slave的foreignMaster列表里暂时踢掉,当S恢复小于阈值后,会再加回foreignMaster列表,全过程对BMC选主机制没有任何收敛性相关的破坏。
最后说一下,为什么BIGO不尝试改变BMC选主顺序条件,比如按照master的S大小来优先选主。主要基于2点考虑:
1. 子网内机器间的网络状况一般都是平等,我们没有强烈的需求需要选出最优的master,我们需要做的是规避毛刺和异常节点;
2. 改变BMC选主顺序,引入动态变量S来调整Master优先级,意味着每台slave机的Master优先级视图可以不一样,BMC简洁的Master收敛过程被破坏,我们需要很小心的去review整个算法的全过程,避免出现极端的Bug,而如1所述,这项工作的收益并不大。
PTP
单机房内部,master和slave之间通过PTP协议来完成时钟同步。这里简单回顾一下PTP协议,以及BIGO内部使用情况。
首先,NTP的原理读者应该已经清楚了,那么我们可以认为PTP是尝试对NTP做工程落地的一种优化实现方式。PTP全称为Precision Timing Protocol,也是在IEEE1588里提出的。PTP主要解决了2个工程上的问题:
1.解决NTP里面精准获取d1,d2的问题;
2.怎么高效的在一个子网内对多个slave同步时钟的问题。
先讲下问题1,精准获取d1,d2是什么意思呢?
首先,PTP是基于UDP协议来通信的,我们把d1,d2定义为网络延时,但是在工程实现上,假如B给A发包,A给B回包,A发回包前获取本机时间T3‘的话,那么T3’=T3-UC。其中T3是网络包从内核发出去的时间,UC是A获取本机时间到回包从内核发出去的时间差,为什么会有UC存在,因为linux并不是一个实时操作系统。UC的耗时组成会很复杂,cpu调度的繁忙程度,缓冲到发送的耗时都会影响UC,且会动态变化。而真正的延时d2=T4-T3,如果仅仅把T3’打到包里回给B,那么B在计算d2的时候就会存在误差。
关于问题2,PTP这边利用广播机制来主动对多个slave进行时钟同步,工程上具备容易配置,快速收敛(参考前面的机房内master选举算法过程),以及网络带宽和资源占用少等优点
PTP具体同步过程分为delay机制和sync机制:
图5为PTP时钟delay机制的同步过程,该过程重点解决一个问题:工程上精准算A到B的网络时延delay值。
为什么要算这个值呢?基于PTP子网同步的场景特点,PTP假设短时间内,一个子网的网络波动较小,即D1=D2,且D1值短时间内不会变化。基于这个假设,PTP后面可以以较低开销完成sync机制的时间同步。
简单来说,PTP在一个子网内,slave会长周期的进行delay广播机制,该过程开销偏大。而master侧会短周期的进行sync机制,来达成对子网内全部slave的时钟同步,该过程开销相对小。
回到delay机制过程本身,是怎么做到精准测算A到B的delay值呢。图中T1’,T2’,T3’,T4’都是PTP程序用户态可以拿到的时间,这些时间都含有误差。要精准测算delay,B就需要获取T1,T2,T3,T4,即req和resp从网卡发出,以及达到收包方内核协议栈的时间。
先说T2和T4值,这2个值在udp包达到内核协议栈之后会记录下来,用户态可以拿到该时间。从B的视角,T4本身就可以拿到,T2可以让A的程序在回包的包体里带上。
再来说T3,这个值的获取原理,是ptp delay机制需要广播发起的主要原因。PDelayResp包回包是广播到子网,由于是广播包,A自己也可以收到PDelayResp,基于回环广播特性此时A收到的PDelayResp包的到达时间就是该包的网卡发出时间,即T3。此时A只需要再发一个PDelayRespFollowUp包,包体里带上T3时间,则B就可以正确获取T3时间了。
最后说T1,只要明白T3的获取原理,则类似T3,B本身获取T1也是基于PDelayReq包的回环达到时间判定。
至此,基于公式delay = (T2-T1+T4-T3)/2即可在工程上完成精准测算A到B的网络时延delay值。
图6为PTP时钟同步的sync过程,该过程运行时,B已经成功获取到A到B的网络时延dealy。此时A作为master主动广播sync请求帮助B精准测算出A,B本地时钟差值offset。
本次过程依然A,B只能拿到T1’,T2’,但是基于前面delay过程的描述,读者应该可以比较直接的知道如何获取到T1和T2。过程不再赘述,B可以直接拿到T2,而followup包会把T1带给B。
于是我们知道T1+offset+dealy=T2,故A,B机器时钟误差满足offset=T2-T1-delay。B得到offset之后,修改本地时钟即完成了一次PTP的子网时钟对齐的过程。
最后提一下,PTP本身的工程源码也存在一些乱序和时钟同步错误的bug,BIGO内部基于一个版本做了一些改造优化。
跨机房同步
Master机器周期跨机房与super master做时钟同步,是本架构里主要误差来源。BIGO内部跨机房,跨大洲以走公网为主,网络延时大,网络波动比较明显。即使内部建设很好的光纤内网,双向链路的延时对称性也不一定可以保证,在实际运行中受很多因素影响。
在这一层实现上,BIGO基于ptp单播协议(这个不细讲了,就是ntp协议的工程实现)来做同步,但是该协议显而易见在网络波动下存在误差和跳变。
针对这个问题,BIGO参考了Ntpd的平滑实现并加入自研的异常波动剔除算法,来优化ptp单播跨机房同步过程存在的误差和跳变,主要有2个策略:
1. 当计算出offset(即ntp里的diff)在128ms以内时,对master本地时钟往super master时钟方向调整最多0.5ms。当计算出offset(即ntp里的diff)大于128ms时,默认忽略该offset,除非该offset持续了一个较大阈值周期(300s),才会基于此offset调整master时钟;
2. 基于波动阈值x剔除无效同步。当本次ptp单播的delay比最近30次delay值误差大于阈值x,则本次ptp单播的结果不被应用,同时x相应增加。只有当前ptp结果被采纳,且offset值小于2ms,才会把x重置为初始值。
策略1可以保证时钟对齐过程的平滑,同时时钟对齐导致的时钟回退问题也解决了。这里的0.5ms/s不是人为设置一个绝对值,而是调用linux内核封装的Phase-locked loop机制来对本机时钟进行调整。从而保证时间调整不会在应用上层体现为时间回退。该机制原理,本文不做展开。
策略2可以剔除网络波动对同步结果的影响,有点类似chrony的mindelay机制。
BIGO在上线该策略后,对比之前无平滑策略的ntpdate效果明显,在跨机房同步场景,比nptd和facebook的chrony效果也要更好,相关效果检验下面会完整阐述。
效果评测与仿真
关于精度和效果评测这个话题,业界如facebook的chrony内部声称做到0.1ms以内的的误差精度,而google的spanner里的true time是100%确信在7ms的区间内。BIGO在开展此项工作的一期目标是在没有内部原子钟的前提下,把99.99%场景误差精度控制在亚毫秒。
关于精度的测算,本身就是一个跟全球时钟对齐同等难度的命题。
为什么这么说呢,因为如果我们可以在上帝视角完美0误差识别任意2台机器的时间误差,那么也就代表着我们可以把任意2台机器的时间误差调整为0。
已知比较好的评测手段,有facebook提到的基于1PPS(每秒脉冲数)来检测任意2台机器的时钟误差,该评测可以做到纳秒级的误差,但是对硬件有很多依赖,如需要在机器间铺设专用同轴电缆,需要定制的网卡硬件。
这个话题,我们主要从2个方向来展开:评价指标和评价手段。
首先关于用什么指标来评价集群内机器之间的时钟误差情况,比较直观的就是机器间误差的时间轴坐标图,基于坐标图我们抽象了2个主要指标:
1)可用性——基于我们对误差精度的要求是是亚毫秒,则每秒进行一次机器间时钟误差判断,大于1ms则认为这1秒时钟服务不可用,最后可用时间占比即为可用性;
2)最大误差值——机器间误差值波动过大,我们认为需要重点关注。
评价手段这块,我们没有相关硬件来支撑我们做1PPS的效果评测,所以我们这里基于仿真的思路来做评测。
我们仅仅观察同机房的2台机器A和B的时间误差,由于同机房机器ping 延时可以稳定在0.1ms以下,此时我们近似具备了较高精度观测误差的能力。然后我们仅仅先评测以下3个场景:
1)A和B各自基于某种同步算法,跟本机房(或者同城)的时间源做时间同步,观测A和B的误差时间轴坐标图;
2)A和B各自基于某种同步算法,跟远端跨大区的时间源做时间同步,观测A和B的误差时间轴坐标图;
3)A基于某种同步算法,跟远端跨大区的时间源做时间同步,B基于相同同步算法,跟本机房(或者同城)的时间源做时间同步,观测A和B的误差时间轴坐标图。
图7简单描述了前面所说的3种评测场景。需要注意一点,待评测的UTC时间源可能是跟我们的机器在一个机房,也可能仅仅是同城,取决于待评测服务本身实际部署情况。
我们再来关注怎么评测一个时钟同步算法在跨大区机器间的误差,比如图中A1和B2之间的时钟误差?
软件层面这个问题看起来是无法评测的,但是我们先假设UTC时间源(外部原子钟设备)之间是没有毫秒级误差,那么A3和B3的时钟误差我们暂时可以基于0.1ms的精度进行评测,我们定义A3和B3的时钟误差为diff(A3,B3),则diff(A1,B2)近似等于 diff(A3,B3)。
一句话总结,我们可用观测diff(A3,B3)的结果认为其实仿真表达了diff(A1,B2),等价于我们成功评测了一个时钟同步算法在跨大区机器间的误差(本质上还是有2套本机房外部原子钟UTC源加持,但是仅仅是做评测时依赖而已,我们的系统的机器部署实质不依赖外部UTC时间源的具体部署情况)。
至此,我们已经具备不依赖内部硬件设备,在BIGO全球机房仿真评测同机房,跨大区机器的毫秒级时钟误差的能力。
图8到图13分别为跨大洲和同机房情况下BIGO,NTP和facebook的chrony时钟同步误差测量表。
图8~图13为我们观测BIGO同机房机器,基于不同算法和不同区域源时钟同步之后,取得的误差表。全部场景都观测了3个小时,每秒观测一次,每张图都是1万个横轴坐标点。需要注意的是,ntpdate本身明显过于粗糙,我们认为不值得浪费时间进行对比,所以这里只对比了ntpd和facebook的chrony。
此外,这里的对比结果不一定就代表facebook的chrony内部精度情况,仅仅表达了BIGO作为一个第三方,去依赖这些服务,我们能获得的精度能力。而且chrony本身提供了数十种参数来调优精度和波动,因为精力有限,我们对比时使用默认配置。
图14为我们对6张评测效果做的总结。
前面3行是跨大洲场景的表现,以前面定义的可用性而言,ntpd和chrony直接使用都无法满足我们的可用性需求,而最大误差这块,BIGO自研架构下的机器时钟误差控制在0.5ms内,而直接接入ntpd有近10ms最大误差,接入chrony的误差接近6ms。
后3行是同机房或者同大区的表现,此时BIGO自研架构下的机器时钟误差的可用性和最大误差依然是好过直接接入ntpd或者chrony的。其表达的含义为,即使BIGO选择限制自身的机房部署情况,做架构设计去适配ntpd和chrony源来复用他们提供的时钟对齐服务,效果依然不如当前版本的BIGO自研架构。
总结
总结一下BIGO在全球时钟同步服务的工作,在没有内部原子钟的前提下,基于双层架构设计,建设了稳定的内部UTC时间源。同时基于ptp单播配合平滑+异常剔除算法保证了第一层跨机房时钟同步精度控制在亚毫秒。然后在第二层机房子网内,基于ptp算法实现,优化了网卡发包到用户代码层的时间误差问题,进而把机房内的时钟精度在毫秒内进一步提升。
最终我们收获了一个99.99%场景下,集群时钟误差都在亚毫秒精度的时钟服务,且随着ping值减少,同机房的精度有进一步的提升。该服务架构具备良好的内部可扩展性,不依赖外部NTP时钟源的部署和服务能力。同时我们提供了有效的评测手段来验证我们的毫秒级误差情况。
该系统在内部UTC时间源的精度以及集群可用性,还有对抗上下行延时差值,高精度时钟评测等方向还有诸多工作待进一步展开优化,这些将规划到我们的后期工作中。
该系统当前作为基础设施,为BIGO的全链路trace系统等多项服务提供时钟对齐保证,成功解决了负调用耗时等业务问题。