TiKV为什么用一个单点的授时服务而不是用一致性集群来授时呢?

不知道我有没有理解错,TiKV用了一个单点的授时服务给事务提供版本号,为什么不用一个内置的一致性集群(比方Raft集群)来做呢?
关注者
101
被浏览
4067

3 个回答

申砾同学已经回答得不错了,我补充一下当时做这个设计时候的想法。

如果用一个独立的 raft group 实现授时服务的时钟同步,代价太大,毕竟这个事务模型需要每个事务都去拿两下,提升吞吐的方式只有做 batch,但是一旦 batch 了,延迟必然会很高,而且一般来说在跨机房部署的时候这个授时服务可能是需要跨数据中心的,这样延迟就更大了,所以基本就否了。

学术界也不是没有办法,比如 HLC(Hybrid Logical Clock, cse.buffalo.edu/tech-re)其实在跨数据中心的场景下能显著的降低延迟,毕竟可以直接采用本地时钟,然后像 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
参考: github.com/pingcap/docs