4  Spanner

4.1背景

在google的BIGTABLE论文中,提到过Bigtable后续计划支持多Master的方向,由于BIGTABLE的架构中,只有一个Master服务器,因此一个Bigtable分布式数据库的扩展能力,始终是由一定的限制,数据量增加后,势必需要就会出现瓶颈,如何提升数据库的数据管理能力,解决数据规模不断增加后带来的问题。同时Bigtable丢失传统RDMS系统的一些特点,比如多数据表之间的事务一致性,这些都是数据库必须也是应该具背的特性。是否能够满足分布式数据库的数据分布、负载和吞吐量的同时,还具备关系数据库特性,这不就是分布式数据库的智高无上的理想吗?但分布式数据库CAP理论告诉我们,分布式数据库一致性,可用性、分区容忍性此特性必然只能取其二,是不可能同时具备,这个魔咒能够被打破吗?

阿迪有一句名言“Nothing is impossible”势必需要引入一种新的机制,聪明的Google人找到并解决方案,并在技术上得以实现,Spanner就是在这个场景下面诞生。

4.2 Spanner的数据模型

4.2.1 带独立时间戳映射结构

Spanner有一种负责专门管理数据的spanserver,spanserver也是基于bigtable的tablet结构,每个spanserver由上百个或者上千个tablet构成,Spanserver类似于Bigtable中tablet服务器,是管理数据的核心组件,spanserver的Tablet存在下面映射(key:string, timestamp:int64) –> string,这种映射与Bigtable采用的Key-Value结构第一眼看去貌似一样,但仔细看确有很大差别,时间字段不在是Key一个组成部分,而是把时间戳单独了出来作为一个独立项,构成了一个多版本的数据库,独立时间戳意味着时间在Spanner中会扮演重要角色。

4.2.2 spanserver的软件层次

一个tablet由数据和状态部分构成,存放在一种称作Colossus的文件系统中,该文件系统为GFS后继的文件系统,为了支持数据同步复制,在spanserver上部署有一个paxos状态机, paxos状态机用于实现一系列被一致性复制的映射。一个数据有多个数据副本,多个数据副本所在的paxos状态机组织成一个paxos 分组,用于控制副本一致性。对于主副本,spanserver会增加锁表来保证并发性控制,对于在一个跨越多个Paxos分组的事务,需要在Paxos更上层的确定出主副本机制,以保证跨Paxos分组的事务性。整个结构如图4-1所示,在图中可以看出,由于涉及同步的复制范围不同,需要参与协商Leader的范围就会发生变化,但不管如何变化,始终是可以根据上升的原则,通过协商机制,实现更大范围的事务控制。


GOOGLE分布式数据库技术演进研究--从Bigtable、Dremel到Spanner(三)_第1张图片

图4-1Spanserver 软件层次图

4.2.3 Spanner的目录结构

Spanner提供了一种最为基础键值映射集合的逻辑视图,这个逻辑视图实际上是一个桶的作用,用于把提供一系列键值映射集合放在一起存储,只是为了便于理解,在Spanner中,把这种桶叫做目录。由于键值存放的数据可能存在于不同的Paxos分组,各Paxos所对应物理存储可能在不同的Spanserver服务器上,这些数据也可能属于不同zone,因此虽然这些数据都可以被访问,但访问读取时需要通过长距离的网络传输,因此访问效率可能就不太高。

Spanner中提出了目录概念,就是要把目录作为数据放置的最小单位,目录可以在Spanner中进行移动,移动原则是相关数据尽量存放在一起,这样可以提升Spanner的访问效率,可以看出逻辑桶结构对于Spanner这种巨型的分布式数据库效率提升具有十分重要的意义,能够让系统在数据分布的同时,照顾到数据物理位置,尽量以访问效率的原则进行数据物理位置的调整,以解决效率问题。目前这种调整的依据还是只能根据访问频率的方式来进行调整,当一个目录所管理的键值映射集合太大时,会进行分割操作,分裂为多个目录。

4.2.4 Spanner的半关系模型

Spanner的模型属于半关系型模型,每个表都必须包含一个或者多个主键的排序集合,这一点类似于Key-Value的结构,这种结构的好处是可以方便的根据这种主键来进行数据存放位置控制,这种位置属性可以解决分布式数据的位置聚集要求,提升系统访问的性能,但是带来的一个问题,系统需要存放一些冗余信息,对于没有主键的行,也必须存储为NULL值。在图4-2对于这种半关系模型进行了说明,这个例子中有2个表,用户和相册,相册是依赖于用户这个表格,在相册定义是就增加了用户的信息,这种结构可以根据客户端分割为一个表或者多个表的层次结构,以用户为主键,可以按照用户来组织目录,这种方式就可以结合上面目录结构做到位置集聚,解决由于数据物理分布引起的效率问题。

GOOGLE分布式数据库技术演进研究--从Bigtable、Dremel到Spanner(三)_第2张图片

图4-2 Spanner半关系型数据表定义示例


4.3 Spanner的系统架构

Spanner设计为一个全球型,可扩展的巨型分布式数据库,可以把不同的应用放在一个Spanner中,而不像Bigtable需要建立不同的Bigtable集群。Spanner可以支持这些存放数据的同步和复制,在保证效率的基础上,进行数据复制,整个Spanner系统架构如图4-3所示,UniverseMaster为Spanner的总控制台,一个Spanner只有一个Universe Master,对于zone进行管理,包括创建、删除,同时也显示zone的各钟状态信息; Palacement driver为目录移动控制器,会周期性的与Spanserver进行通讯,确定需要转移目录、满足系统更新后的副本约束条件,系统负载调整所需目录中数据转移,优化数据物理存储,转移速度控制在分钟级别,一个Spanner只有一个Palacement driver;一个Spanner由许多个zone构成,zone类似于Bigtable数据库的角色。zone是管理部署的基本单元,Spanner中的zone中的数据都可以支持复制,可以在Zone之间进行数据复制,这种特性为新加入zone和删除或者替换zone时,提供了良好的扩展性。一个Zone有一个zone Master 和许多Spanserver构成,Zone Master把数据分配给Spanserver,由Spanserver提供给客户端数据库服务,客户端通过Zone上面的Locationproxy来确定为客户端提供服务的Spanserver。


GOOGLE分布式数据库技术演进研究--从Bigtable、Dremel到Spanner(三)_第3张图片

图4-3 Spanner架构图


4.4 Spanner查询

4.4.1 Spanner只读查询

Spanner收到一个数据读取操作后, 根据发起查询请求,计算出整个查询需要涉及到那些键值,涉及到的键值有多少Paxos分组,只涉及一个Paxos分组和涉及多个Paxos分组的处理逻辑有所不同。

涉及一个Paxos分组,按照下面步骤来获取数据:

步骤一客户端对Paxos组的领导者发起一个只读事务;

步骤二 Paxos组的领导者分配为这个读操作分配一个时间戳,这个分配过程Paxos组领导必须要考虑到现在已经申请处理的事务,确保这个时间戳可以让该读取看到最后一次写之后的数据;

步骤三按照分配的时间戳进行数据读取。


涉及多个Paxos分组时,步骤会有所不同,按照下面步骤获取数据:

步骤一客户端发起一个只读事务;

步骤二多个Paxos组领导者进行协商后,分配一个时间戳;

步骤三按照分配时间戳进行数据读取。


4.4.2 Spanner读写操作

Spanner对于读取和写入操作会进行拆分,发生在一个事务中写操作会在客户端进行缓存,先执行读操作,因此这种事务读取操作不会看到这个事务写操作结果。

读操作在自己数据相关的Paxos组中先获取到读锁,读锁作用是明确读先执行读操作,避免写操作申请到写锁,申请到读锁后,分配给客户端对应时间戳进行读操作,但所有读取操作完成后,释放掉读锁。

读锁释放完成后,客户端开始处理所有已经缓存的写操作,也是通过Paxos协商机制进行协商,获取到写锁,分配对应的预备时间戳后,然后根据预备时间戳中的最大时间,确定一个提交时间戳,在提交时间戳同时进行写操作的事务提交。


4.5 应用场景和关键技术


4.5.1 应用场景

Spanner的特点使其具备特定关系型数据库的特点,其应用的场景可以部分替换原有关系型数据库的使用场景,原有Bigtable丢失的关系型数据库的特性,在实际应用中也暴露出了存在缺陷,而Spanner着力于找回这些丢失的特性,提供表数据的外部一致性和读取的全局一致性、跨中心数据的一致性复制,从Google的应用实际看,GOOGLE可以使用F1+Spanner的方式来完全满足关系型数据的特性,而Spanner就是这里组合的基础,不满足部分由F1来实现。同时,由于Spanner数据库的管理能力非常巨大,可以设定多个区域,每个区域的管理能力都与Bigtable相当,因此是一个全球性的巨型数据库,理论上所有的应用都可以基于一个Spanner数据库来运行,这种管理能力是非常惊人的,同时采用这种多区域组成Spanner数据库的结构,多个区域网络连接速度一定是有限,Spanner由会通过一些目录调整的技术,来内聚相关数据,做到相关数据的位置聚集,解决了多区域数据库存在的效率问题,因此从部署上看,spanner可以部署多个数据中心,不仅仅是逻辑数据中心,还是包括物理上不同数据中心,组成一个全球分布式数据库。

4.5.2 关键技术

4.5.2.1 TrueTime

TrueTime是Spanner中核心技术,掌握TrueTime也就掌握Spanner技术精髓,TrueTime从物理上GPS和原子钟构成时间发生器,在每个数据中心部署了一组time Master,在每个节点都部署了timeslave daemo,大多数Master都配置为GPS时钟,部分Master配置为原子时钟,这些Master在物理上面相互隔离,逻辑上会彼此通讯,进行时间校对。Timeslavedaemo会从一组Master中获取可信时间区间,这种机制会对于Master进行修订,同时timeslave daemo可以获取到一个可信时间区间,具体实现细节这里不做详细描述。

而Spanner是利用TrueTime提供API方法, TT.now()、TT.after()和TT.before()方法,TT.now()方法可以给出一个可信时间区间,类似于时间的最早和最晚时间构成的可信时间区间,保证时间必然在这一区域内,TT.after()和TT.before()方法是TT.now()方法的扩展。 表示一个事件e的绝对时间,可以利用函数tabs(e)。如果用更加形式化的术语,TrueTime可以保证,对于一个调用tt=TT.now(),有tt.earliest≤tabs(enow)≤tt.latest,其中,是enow是调用事件。

这个可信时间区间太重要了,这里强调一下Truetime解决二个重要问题,第一,这个可信时间区间是Spanner全系统一直认同、并一致保证、可靠的时间区间值,第二,TrueTime机制使得这个区间值范围达到毫秒级,时间区间范围值越小越利于分布式事务处理,事务处理成功可能性就会越大。这种时间置信区间后,分布式数据库节点之间最大问题事务一致性控制,如何控制,如果有绝对准确时间,可以通过判断事务发生的时间顺序来进行事务一致性控制,因为从时间点角度看,任务一个事务发生时间点必然是唯一的,只是由于系统时间精度和准确时间获取成本和技术上可行性,导致时间点无法准确区分和排序,TrueTime就退而求其次,给出一个可信时间区间,然后根据各事务提交可信时间区间对事务成功还是失败进行控制,这种思路的确非常巧妙的解决这一难题。


4.5.2.2 只读事务和快照读事务无锁管理

只读事务时预先申明快照隔离的事务,这种事务提前申明不包含什么写操作,由Spanner系统为这种事务分配一个时间戳,在这个时间戳后面写事务都不会被阻塞,一个只读事务可以去任何足够新的副本上面去执行,实现无锁管理。

快照读事务是对历史数据的读取,由客户端在提交事务处理时给出一个时间戳或者给出一个时间范围,让Spanner根据这个时间范围选择一个时间戳给该快照读事务,这二种场景都可以保证快照读在任何足够新的副本上面执行,实现无锁管理。

4.5.2.3 Paxos领导者的续约

事务始终是与Paxos分组相关,由Paxos中的领导者进行事务控制,对于领导者能够对于事务时间进行控制,可以延长自己的时间,实现更长时间的领导者地位,当然这个时间有一个最大值,不能超出这个值的范围里面续约,续约有一套类似投票协商的机制,此处不做详细介绍,另外为了保证事务的隔离性,退出以时间区间中最晚时间点满足条件为止。

4.5.2.4 读写事务的锁管理

Spanner采用读和写采用二阶段锁事务协议。当所有锁都已经获得以后,在任何锁被释放之前,就可以给事务分配时间戳。事务根据分配时间戳,通过Paxos分组控制机制,把读或者写的动作进行时间戳排序拆分,确保该事务能够被正常的执行。

6 结语

GOOGLE从Bigtable数据库开始,提供出来一个解决大型数据管理的新视角,Bigtable侧重于数据分布性、扩展性和处理能力提升,丢弃了关系型数据库特性,是一种NOSQL的技术发展方向,不管是Bigtable在GOOGLE公司内部的成功应用,还是开源社区HBASE大红大紫,都说明这种技术方向确实有应用场景。但是随着Bigtable数据库深入使用,我们发现其丢失的关系型数据库特性,在有些场景下已经不能满足需求,对于巨型数据进行分析时Bigtable的速度也不能满足人们的要求。通过GOOGLE的不断研究,在实时数据分析上,引入了一种新模型Dremel,该模型使用列式嵌套式的存储结构和服务树的方式,提高数据读取的有效性,对于数据进行快速查询分解,对于查询结果进行快速汇集,满足大型数据的实时处理要求。作为Bigtable的后续演进上,GOOGLE推出Spanner来找回部分Bigtable丢失关系型数据库的特性,同时Spanner在管理容量上,比Bigtable有了巨大的提升,如果说Bigtable是一个区域和局部分布式数据库集群,那么Spanner就是一个全球范围的巨型数据库系统,在管理上无理论上限。在Spanner后续技术发展上会进一步的提供更接近与关系数据库的产品,对于数据库的效率继续提升,另外一个比较让人动心的技术是数据按照负载情况进行感知,自动进行位置搬迁,提升处理效率,同时spanner也在提升不同数据中心数据复制的成本,优化数据一致性带来的开销,对于Bigtable、Dremel、Spanner的关系可以如下图6-1所示。

GOOGLE分布式数据库技术演进研究--从Bigtable、Dremel到Spanner(三)_第4张图片



图6-1 Bigtable\Dremel\Spanner关系图

GOOGLE对于分布式数据库技术发展方向的共享非常大,可以说引领了整个分布式数据库发展的方向,如果说苹果公司重新定义了手机,那么也可以说GOOGLE重新定义了分布式数据库,差别在于苹果公司提供是手机这样的产品,而GOOGLE提供的是一种可以技术上进行实践的分布式数据库理念,期待不久的将来,GOOGLE能够持续对于分布式数据库进行持续改进,能够使得分布式数据满足必要关系型数据库特性,提供更好的产品理念和技术文档的同时,而且把代码级把产品能够公开出来,满足大型数据的处理要求,推出对外商用的分布式数据库产品。

作者力图从自身视角对于GOOGLE分布式数据库演进技术做为分析,侧重于作者自身的分析和判断,部分结论可能不一定准确,如有描述不准确的地方,敬请谅解,提出宝贵的改进意见。