7.3.4 TrueTime

为了实现并发控制,数据库需要给每个事务分配全局唯一的事务id。然而,在分布式系统中,很难生成全局唯一id。一种方式是采用Google Percolator(Google Caffeine的底层存储系统)中的做法,即专门部署一套Oracle数据库用于生成全局唯一id。虽然Oracle逻辑上是一个单点,但是实现的功能单一,因而能够做得很高效。Spanner选择了另外一种做法,即全球时钟同步机制TrueTime。

TrueTime是一个提供本地时间的接口,但与Linux上的gettimeofday接口不一样的是,它除了可以返回一个时间戳t,还会给出一个误差e。例如,返回的时间戳是20点23分30秒100毫秒,而误差是5毫秒,那么真实的时间在20点23分30秒95毫秒到105毫秒之间。真实的系统e平均下来只有4毫秒。

TrueTime API实现的基础是GPS和原子钟。之所以要用两种技术来处理,是因为导致这两种技术失效的原因是不同的。GPS会有一个天线,电波干扰会导致其失灵。原子钟很稳定。当GPS失灵的时候,原子钟仍然能保证在相当长的时间内,不会出现偏差。

每个数据中心需要部署一些主时钟服务器(Master),其他机器上部署一个从时钟进程(Slave)来从主时钟服务器同步时钟信息。有的主时钟服务器用GPS,有的主时钟服务器用原子钟。每个从时钟进程每隔30秒会从若干个主时钟服务器同步时钟信息。主时钟服务器自己还会将最新的时间信息和本地时钟比对,排除掉偏差比较大的结果。