谷歌分布式三宝

BigTable、GFS、MapReduce这传说中的谷歌分布式三驾马车,虽然谷歌没有公开具体实现代码,但却公布了相应论文,对分布式文件系统、大数据挖掘和NoSQL流行起了重大促进作用,开源界相对应产品是Hbase、HDFS、Hadoop;距谷歌这三篇论文发表已近10年,谷歌内部这三驾马车也在更新换代:

BigTable--MegaStore--Spanner、F1
GFS--Colossus
MapReduce--MapReduce、Percolator、Dremel

MegaStore构建在BigTable之上,是个支持同步复制的半关系型数据库,试图融合NoSQL和SQL,但写吞吐量比较差,所以后续又有了Spanner、F1;Colossus就是GFS2代了;而MapReduce却没有被替代,只是多了Percolator和Dremel这样的提供批处理和实时处理的额外补充方案。

我粗糙解读下谷歌Spanner、F1两篇论文,希望能窥一窥NewSQL的大概原理,当然Spanner、F1只是NewSQL一种实现方式,另一种实现方式是in-memory方式(如H-Store),这里不作讨论;对分布式文件系统Colossus和数据挖掘框架MapReduce等本文也不做讨论。

** Spanner和F1是什么?**

Spanner:高可扩展、多版本、全球分布式外加同步复制特性的谷歌内部数据库,支持外部一致性的分布式事务;设计目标是横跨全球上百个数据中心,覆盖百万台服务器,包含万亿条行记录!(Google就是这么霸气-)

F1: 构建于Spanner之上,在利用Spanner的丰富特性基础之上,还提供分布式SQL、事务一致性的二级索引等功能,在AdWords广告业务上成功代替了之前老旧的手工MySQL Shard方案。

** Spanner特性概览**

1.跨数据中心级的高可用

2.临时多版本的数据库,每个数据的版本由commit时间戳来区分

3.支持常见事务

4.支持基于SQL的查询语言

5.数据中心级的资源透明分配,譬如:a.某个数据中心放什么数据,这样可以将用户数据放在离得近的数据中心(有助降低读延迟);b.各个复制集之间相距距离,这样话可以将各个数据集尽量靠在一起(有助于降低写延迟);c.数据中心间可以动态传输分配资源,以达负载均衡目的

6.外部一致性的读写和全局一致性的读;这样可以避免跨数据中心的备份和MapReduce操作出现数据的不一致性

7.原子级全局schema变更(即使当前变更的schema正有事务在执行)

** Spanner的总体架构**

简单点:Universe > Zone > Spanserver

Universe:Spanner最大的划分单位,目前全球三个:一个用作测试、一个生产环境、一个开发/生产混合型。它包含很多zone,这些zone由univer master来显示各自运行状态,当这些zone之间数据传输交流时,是由叫placement driver的东东来负责控制的。

Zone:Zone是Spanner数据复制的最小区间单位,一个数据中心一般包含一个或多个zone;当一个数据需要复制时,可不是说把这个数据复制到第M数据中心的第N台server,而是发出类似复制到zone X这样的指令;所以zone具有物理隔离性。一般一个zone含有几百台spanserver,有一个zone master来分配哪些数据到哪个

spanserver;同时还有location proxies--一个代理中间件,负责分配哪个spanserver处理对应客户端请求。

spanserver: 就是一台物理服务器,没什么可说的.

spanserver的物理结构

Tablet:最小物理存储单位。每个spanserver有100~1000个tablet,tablet存储的是一些映射,如这种表示:

(key:字符串, timestamp:64位的整数)--对应的字符串

你一定说这不就是KV存储嘛,但请看多了timestamp这个时间戳,因此谷歌说它更像多版本数据库而不是KV数据库(个人感觉强词夺理,哈哈)。Tablet的底层文件存储方式是B-Tree结构的,此外还有预写日志文件。

Paxos Group:spanserver之间是通过Paxos协议来复制的,在每个tablet上有个Paxos状态机,记录相关tablet的meta信息。Paxos里的leader能一直当下去,只要一直lease下去,每次lease时间默认10s。Paxos里的写操作要记录到日志里,而且要记录两次,一次写在tablet里,一次记录在Paxos本身日志里。写操作必须要Paxos leader先初始化下,而读操作可以从其他有数据的replica直接读,一些这样的读写replica组成了一个Paxos Group。

Directory

前面说了一些tablet+Paxos状态机可以结合成一个Paxos Group,group之间也有数据交互传输,谷歌定义了最小传输复制单元directory--是一些有共同前缀的key记录,这些key也有相同的replica配置属性。这样就能很方便的以directory为单位从一个Paxos group移到另一个group里了,速度嘛--一个50M的directory移动需要几秒。此外当一个Directory过大时Spanner会对它进行分片。

Spanner的数据模型

对开发人员来说,他可不管数据库的体系结构或物理格式,他需要的就是一个SQL接口抽象,所以数据模型很重要。

Spanner的数据模型由三部分组成:具备同步复制功能的半关系型表、类SQL语言支持、跨行事务支持。有了这层抽象,开发人员就能很容易在schema里建传统关系型表、使用类SQL查询,使用事务了。

但严格说Spanner的表不是关系型的,倒像KV存储,因为每张表都需要一个主键。1列或几列组成的主键当做key,其他列当做value。你可能会说InnoDB每张表不也需要主键,但InnoDB就不是kV存储呀;不同于InnoDB,InnoDB是非聚簇索引参考聚簇索引(主键)形成表内的层次关系,Spanner里是各个表之间都有层次关系,一个表主键需引用另个表主键组成父子关系.譬如下面例子,虽然语句创建了了user和album两个表,但实际存储不是两个表,而是album参考user主键一个KV大表:

Spanner的大杀器--TrueTime API

其实分布式关系型数据库学术界都提了好多年了,但一直鲜有听说 ,也是直到近几年才有MySQL Cluster、NuoDB、VoltDB、OceanBase等产品问世,why?原因在于关系型分布式数据库实现ACID、分布式事务和分布式join确实有工程上的极大困难,那谷歌又是如何克服的呢其实? 其实Spanner运用的大部分理论也就是常见的2PL、2PC、Paxos等,独到的地方是就是TrueTime API--我认为本篇论文最有价值的部分。

TrueTime API是什么?是基于GPS和原子钟的实现,能将各节点的时间不一致缩小控制在10ms以内!因为分布式数据库对时间要求很高,假如不同地区的数据库节点出现时间不一致,对一致性复制、恢复都是大麻烦;传统NTP时间同步由于不太可靠一般不在分布式环境中使用,逻辑时钟(如lamport时钟、向量时钟)又有因果顺序、通信开销等问题,所以谷歌采用了基于GPS和原子钟的True Time(意味着准确真实的时间!),解决了跨地区分布式节点时间同步问题。

虽然可能实现较复杂,但True Time调用起来却很简单,它包含三个方法:

TT.now():当前时间,返回值是一个时间间隔--[起始时间,结束时间];因为误差总是客观存在,谷歌没表达成通常的T+误差这种形式,而是给了个时间范围间隔;
TT.after(t):返回True,如果t已经发生过了
TT.before(t):返回True,如果t尚未发生

每个数据中心都有一系列True Time masters,这些master代表着绝对正确的时间,然后每台机器上的Time slave来从Time master同步。因为单独GPS或原子钟都有可能失效(引起失效原因各自不同),为以防万一所以有这两种时间确定方式;大部分Time master使用GPS天线接受信号确定时间,另一部Time Master分参考原子钟的时间。GPS和原子钟这两种方式哪个准确率高或者说更值得参考呢?答案是GPS方式,因为随着时间推移,总归会有不准确情况,当出现不准确就需要及时从正确源同步以调整,原子钟广播的时间时会有一小段1~7ms的不确定的时间漂移误差,而GPS却几乎没这种情况。

事务并发控制

Spanner支持两种事务和一种操作:

1.读写事务(只写事务也算此类)

对于最典型的读写事务,Spanner使用常见的两步锁策略(2PL)来控制并发,并实现了一个所谓的外部一致性:假如事务2在事务1提交后才开始,则事务2提交时间需大于事务1提交时间。

对于写操作,写操作都先缓存在客户端这边,所以不到此次事务提交,其他读操作是看不到写结果的;对于读操作,Spanner会加读锁,并使用wound-wait算法避免死锁;当读写都完毕后,使用两步提交协议(2PC)进行组提交到其他节点.但2PC协议最怕的就是协调者或参与者宕机导致其他节点漫长的等,Spanner很巧妙的利用Paxos复制协调者和参与者生成的日志到其他副本集,这样就算协调者或参与者挂掉也有副本上日志可代替读取.

读写事务中比较特别的是更改schema了,在关系型数据库中这种DDL操作一般会加锁阻塞读写,Spanner能神奇的做到不加锁无阻塞,其独到之处是预分配:1.分配一个未来的时间戳t,这样每个节点都知道在t时刻schema会变,正在访问这个schema的读写操作就会自动同步改变;但如果读写操作过了时间戳t,则仍然会阻塞。

2.只读事务

类似于Innodb的MVCC,Spanner基于True Time实现了多版本的快照隔离级别,可以无锁读,也即一个只读事务不影响其他事务的写。只要这事务的time确定,哪怕当前正在读的spanserver坏了,也可以基于True Time从其他replica继续读。但也不是任何replica都能提供某个事务的读的,必须这个replica的"本机时间"大于事务开始的时间,这个“本机时间”是由Paxos状态机和事务管理器一起决定的。

3.快照读

只要提供一个已经过去的时间戳,就能在任何replica上读取这个时间点(段)的数据。

Spanner的性能

spanserver配置:        AMD Barcelona 4核CPU(2200MHz)+4G内存
客户端与测试机网络延迟: <1ms(因为在同一个数据中心里)
测试数据集: 是由50个Paxos Group、2500个directories组成的
测试方法: 4K读写

结果:

1.单台机器事务commit等待时间5ms,Paxos复制延迟大概9ms;而随着replica的增多,这两项数值变化却不大,当复制规模达到一定程度时,延迟也趋于一稳定值.

2.而对于分布式事务2PC的延迟,则相对较大,谷歌给出了如下测试结果表:

总结:

由于论文的晦涩和本人阅读的不详细,很多细节都没描述出来,但可看出Spanner是一个提供半关系型结构、常见事务支持、类SQL接口且具有高可扩展性、自动分片、同步复制、外部一致性的全球分布式系统;但我感觉这样还不能算彻底的NewSQL,得再加上基于Spanner的F1才能算作NewSQL,下一篇Google NewSQL之F1会介绍F1的相关内容。

参考资料

[Spanner: Google’s Globally-Distributed Database](http:// research.google.com/archive/spanner-osdi2012.pdf )

Google Spanner原理- 全球级的分布式数据库

从Google Spanner漫谈分布式存储与数据库技术

MIT DB Course

      </div>

Google NewSQL之Spanner的更多相关文章

  1. Google三驾马车

    Google旧三驾马车: GFS,mapreduce,Bigtable http://blog.sina.com.cn/s/blog_4ed630e801000bi3.html Google新三驾马车 ...

  2. 分布式数据库Google Spanner原理分析

    Spanner 是Google的全球级的分布式数据库 (Globally-Distributed Database) .Spanner的扩展性达到了令人咋舌的全球级,可以扩展到数百万的机器,数已百计的 ...

  3. Spanner: Google’s Globally-Distributed Database

    https://research.google.com/archive/spanner.html Spanner is Google’s scalable, multi-version, global ...

  4. 全球级的分布式数据库 Google Spanner原理

    开发四年只会写业务代码,分布式高并发都不会还做程序员?->>>    Google Spanner简介 Spanner 是Google的全球级的分布式数据库 (Globally-Di ...

  5. 分布式 NewSQL 对比

    1.TiDB: 说明: PingCAP 公司基于 Google Spanner / F1 论文实现的开源分布式 NewSQL 数据库. 开源分布式 NewSQL 关系型数据库 TiDB 是新一代开源分 ...

  6. 转- 阿里云、Amazon、Google云数据库方案架构与技术分析

    「一切都会运行在云端」. 云时代早已来临,本文着眼于顶级云服务商云服务商的云数据库方案背后的架构,以及笔者最近观察到的一些对于云数据库有意义的工业界的相关技术的进展,希望读者能有所收获. 现在越来越多 ...

  7. google cloud storage products

    https://cloud.google.com/products/storage/ BigTable Cloud Bigtable 是 Google 面向大数据领域的 NoSQL 数据库服务.它也是 ...

  8. 分布式系统(Distributed System)资料

    这个资料关于分布式系统资料,作者写的太好了.拿过来以备用 网址:https://github.com/ty4z2008/Qix/blob/master/ds.md 希望转载的朋友,你可以不用联系我.但 ...

  9. 一篇文看懂Hadoop:风雨十年,未来何去何从

    本文分为技术篇.产业篇.应用篇.展望篇四部分 技术篇 2006年项目成立的一开始,“Hadoop”这个单词只代表了两个组件——HDFS和MapReduce.到现在的10个年头,这个单词代表的是“核心” ...

随机推荐

  1. 拒绝switch,程序加速之函数指针数组

    先看一个使用switch语句的程序: #include <stdio.h> #include <time.h> //加法 int add(int a,int b) { retu ...

  2. Android进程回收机制LMK(Low Memory Killer)【转】

    本文转载自:http://www.cnblogs.com/wytiger/p/5744752.html 熟悉Android系统的童鞋都知道,系统出于体验和性能上的考虑,app在退到后台时系统并不会真正 ...

  3. 函数和指针 C++

    一.用函数指针变量调用函数. 指针变量也可以指向一个函数,一个函数在编译时被分配给一个入口地址.这个函数入口地址就称为函数的指针.可以用一个指针变量指向函数,然后通过该指针变量调用此函数. 定义指向函 ...

  4. H3C交换机DHCP&nbsp;Server配置的六个方面

    H3C交换机DHCP Server配置的六个方面 在交换机上面配置DHCP内容是司空见惯的了.那么这里我们就讲解一下H3C交换机DHCP Server配置内容.之后的文章中,我们还对针对其他方面的配置 ...

  5. 一个php+jquery+json+ajax实例

    json.php <!DOCTYPE html Public "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://ww ...

  6. linux系统下块设备驱动程序

    顾名思义,块设备驱动程序就是支持以块的方式进行读写的设备.块设备和字符设备最大的区别在于读写数据的基本单元不同.块设备读写数据的基本单元为块,例 如磁盘通常为一个sector,而字符设备的基本单元为字 ...

  7. A - Vile Grasshoppers

    Problem description The weather is fine today and hence it's high time to climb the nearby pine and ...

  8. Super超级ERP系统---(1)总体设计

       1.概述 随着互联网的发展,尤其是电子商务的发展,信息化系统越来显得越重要.在互联网飞速发展的今天,各种网站,软件系统应用而生,特别是随着近几年电子商务的发展,很多企业慢慢开始做大,管理方面暴露 ...

  9. 使用Micrisoft.net设计方案 第一章 企业解决方案中构建设计模式

    第一章企业解决方案中构建设计模式 我们知道的系统总是由简单到复杂,而不是直接去设计一个复杂系统.如果直接去设计一个复杂系统,结果最终会导致失败.在设计系统的时候,先设计一个能够正常工作的系统,然后在此 ...

  10. OpenCV中GPU模块使用

    CUDA IT168的文章系列: Cuda的初始化:http://tech.it168.com/a2011/0715/1218/000001218458.shtml OpenCV: OpenCV中GP ...