分布式数据库之Spanner数据库简述

本文是分布式数据库课程的阅读报告,为了凑字数可能有些罗嗦,但也算是对Spanner数据库的一个简述,参考文献包括:

1.《Spanner: Google’s Globally Distributed Database》
2.《Google-Spanner论文的思考》
3.《百万节点数据库扩展之道(3): Google Bigtable》

       BigTable,作为Google分布式三架马车之一,问世以来已经有十多年(相对于选择的论文的时间还不到十年),随着计算机相关技术的发展,也有相应的更新。这次我选择谷歌发表于2012年的论文《Spanner: Google’s Globally Distributed Database》作为阅读的论文,学习Spanner数据库的基本原理,以及其包含的分布式数据库设计思路。

       论文中明确表示,Spanner数据库的数据结构和DML受限于谷歌公司以往存储的数据形式和使用方式,处于兼容性和过去的使用经验,Spanner数据库使用结构化的半关系型表来存储数据,支持查询语言和支持通用事务。这些并不是Spanner数据库与众不同之处,Spanner数据库的特点,在于其使用True Time以及基于True Time的数据管理方式。

       True Time使用GPS和原子钟保证了每一个Spanner的数据管理单元,能在任何时刻,获得全局范围上的准确时间,True Time的实现细节十分复杂,,但其使用却十分简单。True Time所使用的APIGoogle的集群管理软件实现并提供,主要包含TT.now()TT.after()TT.before()三个方法。其中TT.now()返回一个时间区间TTinterval:[earliest,latest]TTinterval是一个具有有限时间不确定性的时间区间,在这里认为获得的时间戳TTstamp是一个不确定的时间,但是可以保证时间戳TTstamp一定存在于TTinterval这个时间区间内,这个不确定时钟的时间窗口的宽度足够小(通常小于10ms)。而TT.after()TT.before()方法是基于TT.now()方法的二次封装,提供了用于判断是否已经超过了指定时间和是否还没有到达指定时间的便捷方法。

       基于True Time的时间戳,区别于一般的键值存储,Spanner中数据存储的形式为(key:string, timestamp:int64)string。由于时间戳的存在,Spanner数据库根据设定的销毁时间的不同,可以存在不同数量的多个版本的数据。通过对事务发起时间和分布式数据库不同站点的局部时间戳的比较,确定操作的执行位置和时间。在了解Spanner的具体实现前,先明确Spanner分布式数据库的总体结构和其基于BigTable的现实,如下图1和图2

                        

       总体上,一个Spanner分布式数据库由univermasterplacement driver和一系列Zone组成。ZoneSpanner部署管理的基本单元,univermaster将根据任务的实际情况,将其分发给对应的zonemasterzonemaster再将其发布到不同的spanseverspansever直接为客户端提供数据服务。Location proxy提供给zonemaster定位可能达数千个spanserver的服务。Placement driver则是负责不同zone之间的数据移动,用以满足最新的数据副本约束条件或者实现负载均衡。

                     

       每个SpanServer管理1001000TabletSpanner中的TabletBigTable中的Tablet类似,Tablet的状态存储在一系列以B-Tree组织的文件集合和WALWrite-Ahead-Log)文件中,而所有的这些文件都存储在名为Colossus的分布式文件系统中。为了支持复制,每个Spanserver在每个Tablet的上层都实现了一个单独的Paxos状态机(这里请看参考文献3)。每个状态机中将状态机的状态和日志信息记录到其对应的Tablet中。SpannerPaxos实现支持了长寿leader(数据的不同时间的状态机副本replica,根据实现的机制获得执行权),长寿leader是通过基于时间的leader租约(默认租约长度是10秒)实现的。当前Spanner的实现中会对每次Paxos的写入操作记录两次:一次记录在tabletlog中,一次记录在Paxoslog中。

       在任意一个leader副本上,每个Spanserver通过一张lock table来控制并发。这张lock table中包含了二阶段锁的状态:它将某个范围的key映射到相应的锁状态。用于后面所介绍的事务管理。

  

而图2中所涉及的组(group)的概念,是因为在所有的Key-Value映射的上层,Spanner实现了一层被称为directorybucketing 抽象,如图3所示,一个directory是一批连续的具有相同前缀的key的集合。Directory又被组织成组,通过二级结构实现更加方便的数据管理和访问。GroupZonedirectory的关系如图所示。

有上述的系统组织和基于True Time时间戳的多副本存储,Spanner数据库的事务实现方式十分巧妙而又高效:

       基于时间戳的非事务只读操作:每个数据副本都会记录一个名为安全时间的变量:T_safeT_safe=min(T_paxos_safe,T_tm_safe),在没有事务有待提交时,T_safe为数据副本最后一次更新的时间T_paxos_safe,当有事务待提交时,根据leader事务管理器的安全时间计算出安全事件T_tm_safe。若一个读操作的时间戳是T,当满足T<=T_safe的时候,这个数据副本才可以被当前的这个读操作进行读取。在进行只读操作的时候无须对数据进行加锁,因为时间戳已经保证读操作可以得到正确的数据。

       事务性读和写使用两阶段锁,在读写事务获得锁之后,释放锁之前,可以为之指定任意的时间戳,但需要保证顺序一致性原则:若事务T2的开始时间在事务T1的提交时间之后,那么事务T2的提交时间一定比事务T1的提交时间要晚。

       基于这样的数据管理方式,Spanner数据库实现了在全球范围,这样大的区域下的高并发数据读,和一致性的读写事务操作,并且提供多版本的数据库访问。

       其实在我的印象中,使用时间戳的数据管理方式在通信和编程领域早已出现过。如在通信系统中,使用一致的时钟频率对数据进行一致性采样和校准。又或者是在单机程序上使用时间戳的方式通过管道模型,对实现多进程以及多线程之间的通信。前者是通过短距离情况下通信设备的电气特性实现,而后者是借助计算机系统的时间接口实现,均只能在小范围情况下做到时间准确同步。而Spanner数据库则在全范围内实现了时间的同步(尽管10ms的误差在很多场景下并不适用,但还是有重大影响),想来这项技术也将被应用到其他相关领域。或许这种时间戳的数据管理方式不再适用于数据库需要等到人类建立地外基地,并且需要同步各基地的数据吧。

      

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值