接續 Day 10
昨天講的 單調遞增時鐘 (Monotonic Clock) 不需要同步,而 日曆鐘 (Time-of-Day Clock) 就需要與 NTP 伺服器或外部時間資源做同步,但依舊很不幸的,你希望它應該是正確的時鐘並不是這麼可靠,以下是可能會發生的鬼故事:
雖然大多數人的公司都不太在意時間問題啦!但如果你的系統是跟投資相關,就會有法規要求你的時間精度,像 MiFID II (歐洲金融市場工具指令)就要求有高頻交易的金融機構,他們的時鐘不得與 UTC 時間有超過 100 微秒以上的誤差。
強壯的軟體也是需要為了不準確的時鐘做準備!不準確的時鐘之影響是緩慢且巨大的,如果石英鐘有缺陷或 NTP 使用者端未設定好,應用系統大多數的工作依舊會正常運作,時鐘緩慢的漂移,慢慢的遠離真實時間,直到它發生了意想不到的故障。
因此,若你的應用系統會依靠同步化時鐘,必須要確保和檢測所有機器節點的時間偏移量,任一節點時間漂移過多要視為節點故障並從叢集中移除。
接下來就舉個依賴日曆鐘結果悲劇的例子吧!
這裡有個 multi-leadar 分散式資料庫,資料庫會依靠事件的時間戳記 (timestamp) 做事情;若有 2 個用戶端同時往資料庫寫資料,如下圖 8-3, Client A 寫 x = 1
到 node 1, 它複製資料到 node 2 和 3,Client B 往 node 3 對 x 累加 1(我們知道 x 應為 2)。
每個寫入都依據了日曆鐘標註了發生時的 timestamp,在這個例子中,node 1 和 node 3 的時間偏移小於 3 毫秒 (ms),現在 node 1 x = 1
的 timestamp 為 42.004 秒,但 node 3 x 累加 1
的 timestamp 卻是 42.003 秒,node 2 同時接收到這 2 筆 replica,這就代表了若是使用 最後寫的是贏家 (last write wins) 策略,node 3 的寫入會被丟棄。
就算你使用了 NTP 同步日曆鐘,這種情況還是有可能會發生(如本篇文前半部份講的鬼故事),那這樣怎麼辦呢?我們可以使用一個累加的 counter 來取代日曆鐘解決事件的排序問題,也稱為 邏輯時鐘 (logical clocks),它只關心事件的相關順序,也就是 happns-before 關係。
先這樣啦 XDDDD