TiKV為什麼用一個單點的授時服務而不是用一致性集群來授時呢?
不知道我有沒有理解錯,TiKV用了一個單點的授時服務給事務提供版本號,為什麼不用一個內置的一致性集群(比方Raft集群)來做呢?
申礫同學已經回答得不錯了,我補充一下當時做這個設計時候的想法。
如果用一個獨立的 raft group 實現授時服務的時鐘同步,代價太大,畢竟這個事務模型需要每個事務都去拿兩下,提升吞吐的方式只有做 batch,但是一旦 batch 了,延遲必然會很高,而且一般來說在跨機房部署的時候這個授時服務可能是需要跨數據中心的,這樣延遲就更大了,所以基本就否了。
學術界也不是沒有辦法,比如 HLC(Hybrid Logical Clock, https://www.cse.buffalo.edu/tech-reports/2014-04.pdf)其實在跨數據中心的場景下能顯著的降低延遲,畢竟可以直接採用本地時鐘,然後像 spanner 那樣通過事務的 commit wait 等過時鐘誤差,因為時鐘誤差大多數情況下可能是會比跨數據通信的延遲要小的。
但是!commit wait 的 gap 怎麼設?NTP 並沒有辦法像 Google 的 TrueTime 那樣能給你一個保證,時鐘誤差在比如 10ms 之內,那這個值是多少?很難確定的。比如 CockroachDB 的做法是把這個值交給用戶去制訂,我擦,我一個用戶怎麼知道我該設多少,設長了就慢,設短了可能出錯。對於需要強一致事務的業務,我選擇不出錯。
我們團隊做事情的原則一般是 make it right, before making it fast, 所以在性能和正確性之間我們選擇了一個折中,通過 raft 來選舉一個 time oracle leader,讓它來負責單調遞增的 timestamp 分配,定時通過 raft 持久化已分配的 timestamp 的最大值,即使它掛了,新選舉出來的 timestamp leader 只需要從持久化的這個值, 加上一個選舉的時間再加一個誤差的補償,就可以繼續提供服務。另外這個服務通過 pipeline 和 batch 等優化,可以做到上百萬的 timestamp 分配吞吐,我覺得一個集群百萬級別的事務並發,應該是可以滿足 99.9% 需求了,畢竟即便是雙十一,OceanBase 的最高並發寫吞吐也才十萬不是?
而且,我覺得吧,跨(長距離)數據中心的 ACID 事務實現,只有用硬體搞一種搞法,HLC 也不靠譜還複雜,其實自己搞 TrueTime 也不算太難,只不過現在還沒有有錢的大爺有這個需求,如果有錢的大爺有這個需求,錢給到位我也能搞出來。TiKV 使用 PD 進行授時,PD 是一個集群,不是單點,leader掛了會選舉出新的leader參考: https://github.com/pingcap/docs/blob/master/op-guide/overview.md#tidb-architecture
對不同的事務組也可以使用不同的時間伺服器,提高擴展能力,掛了影響也沒那麼大,所以raft性價比低。這個東西只要不重複就好,這個約束是很容易達到的。
推薦閱讀:
※三階段提交協議如何避免協調者狀態未知的情況?
※常用的分散式事務解決方案介紹有多少種?
※如何理解阿里大神程立的分散式事務文檔?
※阿里雲的分散式事務中間件是什麼實現的?