ntp導致的時鐘回撥

語言: CN / TW / HK

ntp導致的時鐘回撥

時鐘回撥

我們的服務器時間校準一般是通過ntp進程去校準的。但由於校準這個動作,會導致時鐘跳躍變化的現象。 而這種情況裏面,往往回撥最能引起我們的困擾,回撥如下所示:

會引起什麼問題

準點調度任務的誤判

假設有一個任務每天0點時候獲取昨天所有的數據進行對賬,正常情況和時鐘回撥的情況如下圖所示:
針對這種情況,筆者讓業務調整了調度觸發時間,不要精確在準點,以避免此問題。

唯一序列號(雪花算法)

時鐘回撥的情況也會影響到採用雪花算法這種對時間戳要求單調的算法。很明顯的,時間戳回調後,極易形成重複的序列號。
對於這種情況我們採用預留序列號段,在檢測到這種情況後,將預留序列號分配出去,進而解決這一問題。

ntpd的時鐘回撥(跳變)條件

事實上,ntpd本身還有另一種方案,即通過調整滴答頻率來讓我們的本地時鐘慢慢的和精確時間match。 但是,如果本機時間和精確時間(從ntpd服務器獲取的時間)相差過大(> 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中經常能見到時鐘跳變的輸出。

-x選項

我們採用-x選項,可以將stepout threshold(128ms)提升到600s。這樣,不是太極端的情況,應該都不會觸發到時鐘回撥。但這會導致長時間時間戳不準確的問題(畢竟,調整滴答頻率來慢慢match比較慢)。

stepback stepback

在高版本的ntpd中,還可以有stepback選項,如果設置為0的話,則不會回撥。