本章详细介绍Spanserver的设计实现。Spanserver的设计和BigTable非常的相似。参照下图

从下往上看。每个数据中心会运行一套Colossus (GFS II) 。每个机器有100-1000个tablet。Tablet概念上将相当于一张表里的一些行,物理上是数据文件。打个比方,一张1000行的表,有10个tablet,第1-100行是一个tablet,第101-200是一个tablet。但和BigTable不同的是BigTable里面的tablet存储的是Key-Value都是string,spanner存储的Key多了一个时间戳(时间标记):
(Key: string, timestamp: int64) ->string。
因此spanner天生就支持多版本,tablet在文件系统中是一个B-tree-like的文件和一个write-ahead日志。
每个Tablet上会有一个Paxos状态机。Paxos是一个分布式一致性协议。Table的元数据和log都存储在上面。Paxos会选出一个replica做leader,这个leader的寿命默认是10s,10s后重选。Leader就相当于复制数据的master,其他replica的数据都是从他那里复制的。读请求可以走任意的replica,但是写请求只有去leader。这些replica统称为一个paxos group。
每个leader replica的spanserver上会实现一个lock table来管理并发。Lock table记录了两阶段提交需要的锁信息。但是不论是在spanner还是在BigTable上,但遇到冲突的时候长时间事务会将性能很差。所以有一些操作,如事务读可以走lock table,其他的操作可以绕开lock table。
每个leader replica的spanserver上还有一个transaction manager。如果事务在一个paxos group里面,可以绕过transaction manager。但是一旦事务跨多个paxos group,就需要transaction manager来协调。其中一个Transaction manager被选为leader,其他都听其指挥。这样事务就得到了保证。
2. Directories and Placement
之所以Spanner比BigTable有更强的扩展性,在于Spanner还有一层抽象的概念directory, directory是一些key-value的集合,同个directory里的key有着一样的前缀。更妥当的叫法是bucketing。Directory是应用控制数据位置的最小单元,可以通过谨慎的选择Key的前缀来控制。不难猜出,在设计初期,spanner是作为F1的存储系统而设立的,甚至还设计有类似directory的层次结构,这样的层次有很多好处,但由于实现起来太复杂而被摒弃了。
Directory作为数据放置的最小单元,可以在paxos group里面移来移去。spanner移动一个directory一般出于以下几个原因:
Directory可以在不影响client的前提下,在后台移动。移动一个50MB的directory大约只需要的几秒钟。
那么directory和tablet又是什么关系呢。可以理解为Directory是一个抽象的概念,管理数据的单元;而tablet是物理的东西,数据文件。由于一个Paxos group可能会有多个directory,所以spanner的tablet实现和BigTable的tablet实现有些不同。BigTable的tablet是单个顺序文件。Google有个项目,名为Level DB,是BigTable的底层,可以看到其实现细节。而spanner的tablet可以理解成一些基于行的分区的容器。这样就可以将一些经常同时访问的directory放在一个tablet里面,而不用太在意顺序关系。
在paxos group之间移动directory是后台任务。这个操作还被用来移动replicas。移动操作设计的时候不是事务的,因为这样会造成大量的读写block。操作的时候是先将实际数据移动到指定位置,然后再用一个原子的操作更新元数据,完成整个移动过程。
Directory还是记录地理位置的最小单元。数据的地理位置是由应用决定的,配置的时候需要指定复制数目和类型,还有地理的位置。比如(上海,复制2份;南京复制1分) 。这样应用就可以根据用户指定终端用户实际情况决定的数据存储位置。比如中国队的数据在亚洲有3份拷贝,美国队的数据在全球都有拷贝。
前面对directory还是被简化的,还有很多无法详述。
3. 数据模型
Spanner的数据模型来自于Google的内部实践。在设计之初,spanner就决定了以下几个特性:
为何会这样决定呢?在Google内部还有一个Megastore,尽管要忍受性能不够的折磨,但是在Google有300多个应用在用它,因为Megastore支持一个类似关系的schema,而且支持同步复制 (BigTable只支持最终一致的复制) 。使用Megastore的应用有大名鼎鼎的Gmail, Picasa, Calendar, Android Market和AppEngine。 而必须对Query语句的支持,来自于广受欢迎的Dremel。 最后对事务的支持是必不可少的,BigTable在Google内部被抱怨的最多的就是其只能支持行事务,再大粒度的事务就无能为力了。spanner的开发者认为,过度使用事务是造成性能下降的恶果,应该由应用的开发者承担。应用开发者在使用事务的时候,必须考虑到性能问题。而必须提供事务机制,而不是因为性能问题,就干脆不提供事务支持。
本文来自电脑杂谈,转载请注明本文网址:
https://www.pc-fly.com/a/shenmilingyu/article-16958-2.html
明白