EMC颜开分析Google全球级分布式数据库Spanner
完成 对Google Dremel原理的分析后,EMC中国研究院的研究员 颜开又在自己博客上 分析了Google的全球级分布式数据库Spanner,他重点分析了Spanner的背景、设计和并发控制。
在简介中,颜开指出:
Spanner的扩展性达到了令人咋舌的全球级,可以扩展到数百万的机器,数已百计的数据中心,上万亿的行。更给力的是,除了夸张的扩展性之外,他还能同时通过同步复制和多版本来满足外部一致性,可用性也是很好的。冲破CAP的枷锁,在三者之间完美平衡。
接下来,他提到:
Spanner能做到这些,离不开一个用GPS和原子钟实现的时间API。这个API能将数据中心之间的时间同步精确到10ms以内。因此有几个给力的功能:无锁读事务,原子schema修改,读历史数据无block。
在背景分析部分,颜开认为:Spanner在Google的定位,处于F1和GFS之间。
颜开这样介绍F1:
一个可容错可扩展的RDBMS——F1。和一般的分布式数据库不同,F1对应RDMS应有的功能,毫不妥协。起初F1是基于Mysql的,不过会逐渐迁移到Spannerr。
F1有如下特点:
- 7×24高可用。哪怕某一个数据中心停止运转,仍然可用。
- 可以同时提供强一致性和弱一致。
- 可扩展
- 支持SQL
- 事务提交延迟50-100ms,读延迟5-10ms,高吞吐
至于为什么Google不用BigTable,颜开的分析是:
因为BigTable提供的最终一致性,一些需要事务级别的应用无法使用。同时BigTable还是NoSql,而大量的应用场景需要有关系模型。就像现在大量的互联网企业都使用Mysql而不愿意使用HBase,因此Google才有这个可扩展数据库的F1。而Spanner就是F1的至关重要的底层存储技术。
颜开又介绍了第二代GFS——Colossus。
初代GFS是为批处理设计的。对于大文件很友好,吞吐量很大,但是延迟较高。所以使用他的系统不得不对GFS做各种优化,才能获得良好的性能。
Colossus是第二代GFS。Colossus是Google重要的基础设施,因为他可以满足主流应用对FS的要求。Colossus的重要改进有:
- 优雅Master容错处理 (不再有2s的停止服务时间)
- Chunk大小只有1MB (对小文件很友好)
- Master可以存储更多的Metadata(当Chunk从64MB变为1MB后,Metadata会扩大64倍,但是Google也解决了)
Colossus可以自动分区Metadata。使用Reed-Solomon算法来复制,可以将原先的3份减小到1.5份,提高写的性能,降低延迟。
至于Spanner相对于BigTable和Megastore的优势,颜开认为:
BigTable在Google得到了广泛的使用,但是它不能提供较为复杂的Schema,还有在跨数据中心环境下的强一致性。Megastore有类RDBMS的数据模型,同时也支持同步复制,但是它的吞吐量太差,不能适应应用要求。Spanner不再是类似BigTable的版本化 key-value存储,而是一个“临时多版本”的数据库。何为“临时多版本”,数据是存储在一个版本化的关系表里面,存储的时间数据会根据其提交的时间打上时间戳,应用可以访问到较老的版本,另外老的版本也会被垃圾回收掉。
Google官方认为 Spanner是下一代BigTable,也是Megastore的继任者。
颜开提到Spanner作为一个全球化分布式系统的有趣特性:
- 应用可以细粒度的指定数据分布的位置。精确的指定数据离用户有多远,可以有效的控制读延迟(读延迟取决于最近的拷贝)。指定数据拷贝之间有多远,可以控制写的延迟(写延迟取决于最远的拷贝)。还要数据的复制份数,可以控制数据的可靠性和读性能。(多写几份,可以抵御更大的事故)
- Spanner还有两个一般分布式数据库不具备的特性:读写的外部一致性,基于时间戳的全局的读一致。这两个特性可以让Spanner支持一致的备份,一致的MapReduce,还有原子的Schema修改。
这些特性都得益于Spanner的全球时间同步机制:
全球时间同步机制,可以在数据提交的时候给出一个时间戳。因为时间是系列化的,所以才有外部一致性。这个很容易理解,如果有两个提交,一个在T1,一个在T2。那有更晚的时间戳那个提交是正确的。
这个全球时间同步机制是用一个具有GPS和原子钟的TrueTime API提供了。这个TrueTime API能够将不同数据中心的时间偏差缩短在10ms内。这个API可以提供一个精确的时间,同时给出误差范围。
颜开认为:
这个TrueTime API 非常有意义,如果能单独开源这部分的话,很多数据库如MongoDB都可以从中受益。
颜开接下来分析了Spanner的体系结构:
Spanner由于是全球化的,所以有两个其他分布式数据库没有的概念。
- Universe。一个Spanner部署实例称之为一个Universe。目前全世界有3个。一个开发,一个测试,一个线上。因为一个Universe就能覆盖全球,不需要多个。
- Zones. 每个Zone相当于一个数据中心,一个Zone内部物理上必须在一起。而一个数据中心可能有多个Zone。可以在运行时添加移除Zone。一个Zone可以理解为一个BigTable部署实例
其中还包括如下组件:
- Universemaster: 监控这个universe里zone级别的状态信息
- Placement driver:提供跨区数据迁移时管理功能
- Zonemaster:相当于BigTable的Master。管理Spanserver上的数据。
- Location proxy:存储数据的Location信息。客户端要先访问他才知道数据在那个Spanserver上。
- Spanserver:相当于BigTable的ThunkServer。用于存储数据。
颜开分析了Spanner中的抽象概念directory,它让Spanner比Bigtable具备更强扩展性:
Directory是一些key-value的集合,一个directory里面的key有一样的前缀。更妥当的叫法是bucketing。Directory是应用控制数据位置的最小单元,可以通过谨慎的选择Key的前缀来控制。……Directory还是记录地理位置的最小单元。
对于Spanner的数据模型,颜开的分析是:
在设计之初,Spanner就决心有以下的特性:
- 支持类似关系数据库的schema
- Query语句
- 支持广义上的事务
……
据模型是建立在directory和key-value模型的抽象之上的。一个应用可以在一个universe中建立一个或多个database,在每个database中建立任意的table。Table看起来就像关系型数据库的表。有行,有列,还有版本。Query语句看起来是多了一些扩展的SQL语句。
Spanner的数据模型也不是纯正的关系模型,每一行都必须有一列或多列组件。看起来还是Key-value。主键组成Key,其他的列是Value。但这样的设计对应用也是很有裨益的,应用可以通过主键来定位到某一行。
对于Spanner的并发控制,颜开提到:
Spanner使用TrueTime来控制并发,实现外部一致性。支持以下几种事务。
- 读写事务
- 只读事务
- 快照读,客户端提供时间戳
- 快照读,客户端提供时间范围
那么何时能出现开源的Spanner和F1产品呢?颜开的分析是:
GFS出现于2001年,Hadoop出生是在2007年。如果Hadoop是世界领先水平的话,GFS比世界领先水平还领先了6年。同样的Spanner出生大概是2009年,现在我们看到了论文,估计Spanner在Google已经很完善,同时Google内部已经有更先进的替代技术在酝酿了。笔者预测,最早在2015年才会出现Spanner和F1的山寨开源产品。
颜开博客上的原文对Spanner有更多深入的细节分析,如果读者想了解更多,请移步 颜开的这篇博客。
郑柯 InfoQ中文站总编。做过开发,当过PM,干过销售,搞过市场,最终还是回到媒体。实用的理想主义者,相信:每天改变一点点,这个世界会更好。