聊聊Ntp導(dǎo)致的時鐘回撥
時鐘回撥
我們的服務(wù)器時間校準一般是通過ntp進程去校準的。但由于校準這個動作,會導(dǎo)致時鐘跳躍變化的現(xiàn)象。而這種情況里面,往往回撥最能引起我們的困擾,回撥如下所示:
會引起什么問題
準點調(diào)度任務(wù)的誤判
假設(shè)有一個任務(wù)每天0點時候獲取昨天所有的數(shù)據(jù)進行對賬,正常情況和時鐘回撥的情況如下圖所示:
針對這種情況,筆者讓業(yè)務(wù)調(diào)整了調(diào)度觸發(fā)時間,不要精確在準點,以避免此問題。
唯一序列號(雪花算法)
時鐘回撥的情況也會影響到采用雪花算法這種對時間戳要求單調(diào)的算法。很明顯的,時間戳回調(diào)后,極易形成重復(fù)的序列號。
對于這種情況我們采用預(yù)留序列號段,在檢測到這種情況后,將預(yù)留序列號分配出去,進而解決這一問題。
ntpd的時鐘回撥(跳變)條件
事實上,ntpd本身還有另一種方案,即通過調(diào)整滴答頻率來讓我們的本地時鐘慢慢的和精確時間match。但是,如果本機時間和精確時間(從ntpd服務(wù)器獲取的時間)相差過大(> stepout threshold 128ms),則ntpd會直接采用跳躍變化的方式修正時間。代碼如下所示:
- ntp_loopfilter.c
- double clock_max = CLOCK_MAX; // .128也就是128ms
- int local_lock(...) {
- // 差距>128ms之后,選擇跳變
- if (fabs(fp_offset) > clock_max && clock_max > 0) {
- ......
- // 修正simclock.local_time
- step_systime(fp_offset);
- ......
- }
- }
而在我們的線上,在/var/log/message中經(jīng)常能見到時鐘跳變的輸出。
-x選項
我們采用-x選項,可以將stepout threshold(128ms)提升到600s。這樣,不是太極端的情況,應(yīng)該都不會觸發(fā)到時鐘回撥。但這會導(dǎo)致長時間時間戳不準確的問題(畢竟,調(diào)整滴答頻率來慢慢match比較慢)。
stepback stepback
在高版本的ntpd中,還可以有stepback選項,如果設(shè)置為0的話,則不會回撥。
本文轉(zhuǎn)載自微信公眾號「解Bug之路」,作者解Bug之路。轉(zhuǎn)載本文請聯(lián)系解Bug之路公眾號。
































