互聯網上的設備要保持正常運行需要內置時鐘運行精準,像Facebook這種規(guī)模體量的互聯網公司對設備時鐘的精準度要求會更高。本文介紹了Facebook在搭建自己的精確時間服務方面的探索實踐,最終給我們提供了測量系統時間誤差的方法以及對chrony的應用實踐。
數十億連接到互聯網的設備幾乎都有內置時鐘,為了保證設備的正常運行,這些時鐘必須保持精確。因為許多時鐘的內部振蕩器并不精準,所以可能會導致每天數秒的誤差,這就需要定期校正。因為不準確的時間會導致一些問題,比如錯過重要的提醒時間,甚至導致宇宙飛船發(fā)射失敗。全世界的設備都依賴網絡時間協議(NTP),通過包交換、可變延遲的數據網絡來保持與更精確時鐘的同步。
隨著Facebook基礎設施的增長,系統中的時間精度變得越來越重要。我們需要知道數據中心中兩個隨機服務器之間的準確時間差,以便數據存儲寫入數據時不會打亂事務順序。我們需要以亞毫秒級的精度同步多個數據中心的所有服務器。為此,我們測試了chrony,這是一個功能豐富的現代NTP服務器實現。在測試期間,我們發(fā)現與以前使用的服務ntpd相比,chrony具有更高的精確性和可伸縮性,這就讓我們很安心的用chrony替換了基礎設施中的ntpd。Chrony也是Facebook公共NTP服務time.facebook.com的基礎。在這篇文章中,我們將分享將時間精度從10毫秒提高到100微秒所做的工作,以及我們如何在計時實驗室驗證這些結果的。
閏秒
在深入了解NTP服務細節(jié)之前,我們需要了解一種稱為閏秒的現象。由于地球不規(guī)律的自轉,我們有時需要增加或減少一秒,或一閏秒。對于人類來說,增加或減少一秒在看鐘表的時候幾乎察覺不到。然而,這種事情發(fā)生在服務器上,就可能導致大量事務或事件丟失,甚至發(fā)生嚴重的軟件故障。解決這一問題最通常的做法是“抹去”閏秒,也就是說每過幾個小時稍微修改一下時間。
規(guī)模建設NTP服務
Facebook的NTP服務分為四個層次:
·第0層是一層擁有極其精確原子鐘的衛(wèi)星,這些原子鐘來自全球導航衛(wèi)星系統(GNSS),如GPS、GLONASS和Galileo。
·第1層是Facebook的原子鐘,與GNSS同步。
·第2層是一個與層1設備同步的NTP服務器池。在這一層,閏秒開始出現。
·第3層是更大規(guī)模配置的服務器層。他們接收被處理過的時間,這一層就感知不到閏秒了。
在某些系統中,可能有多達16個層來分配工作,對層數的需求取決于系統規(guī)模和精度要求。
當我們開始構建NTP服務時,我們測試了以下后臺程序使用的時間:
1.Ntpd:一個通用的后臺程序,Ntpd過去常常應用在大多數類Unix操作系統中。多年來,它一直是穩(wěn)定的解決方案,現在的大多數計算機上依舊運行著Ntpd。
2.Chrony:一個比較新的后臺程序,它具有豐富的特性,并且可以為NTP提供精確的時間同步。Chrony還提供了可擴展控制協議,理論上可以將精度降低到納秒。從資源消耗的角度來看,我們發(fā)現ntpd和chrony非常相似,chrony消耗的內存甚至稍微少一些(大約有1 MiB的差異)。
評估后臺程序
無論系統是使用ntpd還是chrony,每個系統都提供了一些評估的度量方法。通過使用這些后臺程序的命令行工具可以進行評估。這些評估是基于一定的假設為前提的,例如:
·客戶機和服務器之間的網絡路徑要有對稱性。
·當時間戳被添加到NTP包并調用send()時,操作系統會立即發(fā)送它。
·振蕩器的溫度和輸入電壓是恒定的。
Ntpd包含ntpq命令行工具,可以顯示時間沒有同步的狀態(tài):
[user@client ~]# ntpq -p
remote refid st t when poll reach delay offset jitter
=========================================================================
+server1 .FB. 2 u 406 1024 377 0.029 0.149 0.035
+server2 .FB. 2 u 548 1024 377 0.078 0.035 0.083
*server3 .FB. 2 u 460 1024 377 0.049 -0.185 0.114
然而,這些數據可信么?如果ntpd報告時間差了0.185 ms,是否準確?答案是否定的。服務器根據包中的多個時間戳估計偏移量,而實際值應該在一個10倍大的窗口內。換句話說,差0.185毫秒的結果意味著偏差可能在+/-2毫秒內(總共4毫秒)。我們的測試表明,ntpd的準確性一般在10毫秒以內。
我們有更高精度的技術要求。例如,多主數據庫將微秒甚至納秒的精度直接轉換為理論吞吐量。另一個需要中等精度的示例是日志記錄,為了在分布式系統的節(jié)點之間匹配日志,通常需要毫秒級的精度。
下面讓我們看看如果用chrony替換ntpd,效果會怎樣:
[user@client ~]# chronyc sources -v
210 Number of sources = 19
.-- Source mode '^' = server, '=' = peer, '#' = local clock.
/ .- Source state '*' = current synced, '+' = combined , '-' = not combined,
| / '?' = unreachable, 'x' = time may be in error, '~' = time too variable.
|| .- xxxx [ yyyy ] +/- zzzz
|| Reachability register (octal) -. | xxxx = adjusted offset,
|| Log2(Polling interval) --. | | yyyy = measured offset,
|| \ | | zzzz = estimated error.
|| | | \
MS Name/IP address Stratum Poll Reach LastRx Last sample
===============================================================================
^+ server1 2 6 377 2 +10us[ +10us] +/- 481us
^- server2 2 6 377 0 -4804us[-4804us] +/- 77ms
^* server3 2 6 377 59 -42us[ -46us] +/- 312us
^+ server4 3 6 377 60 +11ns[-3913ns] +/- 193us
注意最后三個數字。在最后,從右向左看:
·最后一個數字是估計誤差。它的前綴是+/-。它表示chrony的最大誤差范圍。有時是10毫秒,有時是100微秒(100倍的差異)。這是因為當chrony與另一個chrony同步時,使用擴展的NTP協議,這極大地提高了精度。效果還不錯。
·下一個是方括號中的數字。它顯示了測量的偏移量。除了server4(我們稍后將討論這個),其它的我們看到也大約有100倍的差異。
·方括號左邊的數字顯示的是最初的測量值,經過調整后,允許自第一次測量以來的任何slews應用于本地時鐘。同樣,我們可以看到ntpd和chrony之間的差異也是100倍。
請看下圖:
藍色豎線表示ntpd被chrony替換的時間點。對于ntpd,其范圍是+/-1.5 ms。用了chrony后,變動范圍在微秒內。更重要的是,估計誤差(窗口)下降到了100微秒的范圍,這些是可以通過實驗室測量來確認的(下面會有更多的介紹)。但是,這些值是用后臺程序估算的。實際上,實際時間可能完全不同。我們如何驗證這些數字的準確性呢?
每秒脈沖數(1PPS)
我們可以從原子鐘中提取模擬信號(實際上是來自層1設備的內部計時電路)。這個信號叫做1PPS,意思是每秒1個脈沖;它在每一秒的開始都會在同軸電纜上產生一個脈沖。這是一種主流的、精確的同步方法。我們可以在NTP服務器上生成相同的脈沖,然后比較各個階段的差異。這里有個困難點就是,并非所有服務器都支持1PPS,因此需要專門的網絡擴展卡。
我們第一次測試是手動完成的,使用了一臺顯示相移的示波器。
通過10分鐘的測量,我們估算出ntpd的偏移約為3.5毫秒,有時會跳到10毫秒。
這個測試在Facebook大規(guī)模服務器上實現起來是極其困難并且也不切實際。更好的測試方法是將測試服務器的1PPS輸出連接到層1設備本身的1PPS輸入,并監(jiān)控其差異。
這種方法可以實現上一個測試方法中所有優(yōu)點,同時也不需要在數據中心使用示波器。如果使用該方法,我們能夠在任何時間點進行測量并驗證真實的NTP偏移量。
通過這兩個測量結果,我們對實際的NTP偏移有了很好的了解,使用1PPS誤差估計在納秒內,這主要是由電纜長度導致的。
這些方法的不足之處是:
·電纜鋪設:做這樣的測試需要同軸電纜。在不同的數據中心進行測試需要更改數據中心的布局設計,這是比較困難的。
·定制硬件:不是所有網卡都有1PPS輸出。這樣的測試需要特殊的網卡和服務器。
·層1設備需要1PPS輸入。
·服務器上需要安裝1PPS軟件:為了運行測試,我們必須在我們的測試服務器上安裝ntpd。這個后臺程序可能會導致意外錯誤,因為它在用戶空間中工作,并會被Linux調度。
專用測試設備
市場上有一些設備可以進行準確性測試。它們包含GNSS接收器,一個原子鐘,多個1PPS和網絡接口,還可以充當NTP客戶端。這就讓我們可以直接使用NTP協議執(zhí)行相同的測試。接收到的NTP包由原子鐘或GNSS接收器以非常精確的時間戳記錄。
以下就是常見的裝備:
上面的照片是我們最初臨時用的測試設備。使用該設備進行測量有以下幾個優(yōu)點:
·它不需要額外的1PPS電纜。我們雖然仍然需要約束原子鐘,但這可以通過使用GNSS或層1設備本身和一根短電纜來實現。
·它使用原子鐘的數據來標記傳輸和接收的網絡數據包。這使得操作系統的影響可以忽略不計,誤差率只有幾納秒。
·它同時支持NTP和PTP(精確時間協議)。
·該設備是便攜式的,我們可以在不同地點之間移動它來執(zhí)行測試。
·設備使用自己的數據點集格式,但它可以將數據導出到CSV,也就是說我們可以按我們的數據標準導出數據。
NTPD測量
結果與我們在后臺程序評估和1PPS測量中看到的非常相似。首先,我們發(fā)現有一個10毫秒的下降,然后慢慢地修正為+/-1毫秒。有趣的是,這個10毫秒的下降是相當穩(wěn)定的,并且在每次重啟后都會出現。
Chrony測量
這看起來與chrony后臺程序的估算非常相似,它比ntpd好10到100倍。
Chrony的硬件時間戳
Chrony極大地改善了偏移量,這可以從1PPS的估算結果和實驗室設備值中看出。不過Chrony還支持硬件時間戳。根據文檔,Chrony聲稱可以將精度提高到幾百納秒以內。
讓我們來看看網絡上NTP客戶機-服務器通信中的NTP包結構。初始客戶端的NTP包包含傳輸時間戳字段。
服務器填充其余的字段(例如,接收時間戳),將客戶機的傳輸時間戳保存為原始時間戳,并將其發(fā)送回客戶機。
可以使用tcpdump驗證此行為:
08:37:31.489921 IP6 (hlim 127, next-header UDP (17) payload length: 56) client.36915 > time1.facebook.com.ntp: [bad udp cksum 0xf5d2 -> 0x595e!] NTPv4, length 48
Client, Leap indicator: clock unsynchronized (192), Stratum 0 (unspecified), poll 3 (8s), precision -6
Root Delay: 1.000000, Root dispersion: 1.000000, Reference-ID: (unspec)
Reference Timestamp: 0.000000000
Originator Timestamp: 0.000000000
Receive Timestamp: 0.000000000
Transmit Timestamp: 3783170251.489887309 (2019/11/19 08:37:31)
Originator - Receive Timestamp: 0.000000000
Originator - Transmit Timestamp: 3783170251.489887309 (2019/11/19 08:37:31)
...
08:37:31.490923 IP6 (hlim 52, next-header UDP (17) payload length: 56) time1.facebook.com.ntp > server.36915: [udp sum ok] NTPv4, length 48
Server, Leap indicator: (0), Stratum 1 (primary reference), poll 3 (8s), precision -32
Root Delay: 0.000000, Root dispersion: 0.000152, Reference-ID: FB
Reference Timestamp: 3783169800.000000000 (2019/11/19 08:30:00)
Originator Timestamp: 3783170251.489887309 (2019/11/19 08:37:31)
Receive Timestamp: 3783170251.490613035 (2019/11/19 08:37:31)
Transmit Timestamp: 3783170251.490631213 (2019/11/19 08:37:31)
Originator - Receive Timestamp: +0.000725725
Originator - Transmit Timestamp: +0.000743903
...
客戶端會獲得數據包,附加另一個接收時間戳,并使用下面這個NTP RFC#958中的公式計算偏移量:
c=(t2-t1+t3-t4)/2
然而,Linux不是一個實時操作系統,它要運行的進程不止一個。因此,當傳輸時間戳被填滿并調用Write()時,并不能保證立即通過網絡發(fā)送數據:
另外,如果機器沒有足夠的流量,在發(fā)送NTP包之前可能需要一個ARP請求,ARP請求是不可靠的,這會導致估算錯誤。但chrony支持硬件時間戳,使用這些方法,另一端的chrony可以高精度地確定數據包何時被網絡接口處理。雖然從網卡戳記數據包到它實際離開數據包之間仍然有一個延遲,但小于10ns。
還記得之前這個chronyc sources的輸出形式嗎?
^+server4 2 6 377 60+11ns[-3913ns]+/-193us
Chrony報告偏移量為11 ns。這是因為啟用了硬件時間戳的結果。然而,估計誤差在幾百微秒的范圍內。雖然不是所有的網卡都支持硬件時間戳,但是隨著它越來越受歡迎,網卡會慢慢支持這個特性。要驗證對硬件時間戳的支持,只需運行ethtool檢查,然后就可以看到硬件傳輸和硬件接收功能。
ethtool-T eth0
Time stamping parameters for eth0:
Capabilities:
hardware-transmit(SOF_TIMESTAMPING_TX_HARDWARE)
hardware-receive(SOF_TIMESTAMPING_RX_HARDWARE)
hardware-raw-clock(SOF_TIMESTAMPING_RAW_HARDWARE)
通過使用實驗室設備測試相同的硬件,我們就可以得到不同的結果了,ntpd誤差顯示在-10毫秒和3毫秒之間(13毫秒的差異),chrony誤差顯示在-200微秒和200微秒之間,而且啟用硬件時間戳后,在大多數情況下chrony誤差都顯示在-100微秒和100微秒之間。這也證實了之前后臺程序的估算可能是不準確的。
公共服務
現在,所有測量都在我們內部控制的數據中心網絡中進行。下面,我們看看當我們在公共NTP服務或者其他一些著名的公共NTP服務提供商上測試時,情況是什么樣的:
測量的結果好壞在很大程度上取決于網絡路徑以及網絡連接的速度和質量。這些測量并沒有受到Facebook網絡的影響,針對的是來自不同地點、不同Wi-Fi和LAN網絡的服務進行的多次測試。我們可以看到,我們的公共NTP服務不僅與其他主流的供應相比有競爭優(yōu)勢,而且在某些情況下,它的性能也更優(yōu)。
公共NTP設計方案
在我們成功地將內部精度提升到亞毫秒級別之后,我們就啟動了一個公共NTP服務,它可以通過設置time.facebook.com作為NTP服務器來使用。我們在我們的網絡入網點(PoP)上運行這個公共NTP服務。為保障私隱,我們不會按IP地址為設備設定指紋。為了在即使請求網絡路徑失敗的情況下也能提供更好的服務,我們在五個不同的地理位置都設置了端點。我們的五個端點如下:
·time1.facebook.com
·time2.facebook.com
·time3.facebook.com
·time4.facebook.com
·time5.facebook.com
每個端點都在不同的地理位置上,這對可靠性和時間精度都有積極的影響。
time2.facebook.com的網絡路徑如下:
time3.facebook.com的網絡路徑如下:
抹掉閏秒
Ntpd一直使用一種預發(fā)布的閏秒列表文件。有了這個文件,Ntpd就可以提前進行時間修正,當閏秒實際發(fā)生時,也能保證時間是正確的。
Chrony依賴于GNSS提前幾小時發(fā)布的閏秒指示器。當閏秒事件在UTC 00:00實際發(fā)生時,在指定的時間段內它就會被抹去。有了Facebook公共NTP服務,我們決定采用更精確的方法,在事件結束后的大約18個小時內抹去閏秒。
因為涂抹操作要在層2的許多服務器上同時進行,所以保持操作盡可能的相似是很重要的。按照平滑的正弦曲線規(guī)則進行操作對應用程序來說是安全的選擇。
經驗總結
測量時間是非常具有挑戰(zhàn)性的。ntpd和chrony提供的估算方法在一定程度上都是正確的。一般來說,如果您想要監(jiān)控真實的偏移量,我們建議使用1PPS或帶有GNSS接收器和原子鐘的外部設備。
在比較ntpd和chrony時,我們的測量結果表明chrony要精確得多,這就是我們將基礎設施遷移到chrony并啟動公共NTP服務的原因。結果證明,將精度從幾十毫秒提高到幾百微秒是值得的。
使用硬件時間戳可以進一步將精度提高兩個數量級。盡管NTP已經有所改善,但它也有自己的局限性,因此對PTP的研究使用才有可能將您的精度提升到下一個級別。
英文原文:
https://engineering.fb.com/production-engineering/ntp-service/