云计算下的新型数据库技术 php
摘要:在这个信息化的时代,咱们的一举一动都离不开与数据打交道,特别是云计算和大数据时代的到来,使得传统数据库的性能已没法知足海量数据的实时交易查询需求。在性能和成本的双重压力之下。云计算下的数据库需要寻找突破之路。html
1.简单介绍:mysql
云计算经过整合。管理和调配分布在互联网中的所有计算资源,以统一的界面同一时候向用户提供服务。web
互联网提供的各类计算形式的应用以及提供这些服务的数据中心和软硬件基础设施、提供的服务成为软件即服务(SaaS),数据中心的软硬件基础设施即为云,这样的虚拟化资源提供计算的方式使得服务经过互联网传播,而用户不需要知道云计算服务的提供者和提供方式。所以。云计算具备规模大,可靠性高,用户透明,可扩展性强,提供按需服务和便宜等特色。算法
而实现以上需求的前提条件就是云计算系统应该具有足够大的规模和处理能力。以知足大量的数据訪问,数据存储和来自不一样网络等额请求。sql
传统的关系型数据库尽管在数据存储方面占领着不可动摇的地位,但由于其天生的限制,愈来愈不能知足云计算下的数据扩展、读写速度、支撑容量以及建设和运营成本的要求。鉴于此。国内外知名的一些互联网企业Google、Facebook、Twitter、阿里、腾讯、百度等纷纷展开探索,自主研发新型数据库,这些企业有拥有众多的优秀人才。以及丰富的产品经验,因此对于新型数据库的探索成果在必定程度上也表明了当下云计算下数据库的最新的进展。因此本文主要先对与传统型数据库的优劣进行一些分析。接着介绍了现如今新型数据库的研究进展,对各种型数据库进行一些对照分析,最后在对于还存在的不足进行总结并对数据库的发展提出本身一些的见解。mongodb
2.背景:数据库
2.1 云计算和大数据:编程
大数据是一种大规模数据的管理和利用的商业模式和技术平台的泛指,它不一样于传统的海量数据,除了数据规模呈现几何级数增加的特征之外。还包含所有数据类型的採集、分类、处理、分析和展示等多个方面,从而终于实现从大数据中挖掘潜在巨大价值的目的。所以,大数据具备这4方面的特征:规模性(Volume)、多样性(Variety)、快速性(Velocity)和真实性(Veracity)。json
云计算是一种基于互联网的计算方式,经过这样的方式,共享的软硬件资源和信息能够按需提供给计算机和其它设备。能够像煤气、水电同样提供给信息时代的社会化服务。使用方便。费用低廉。云计算具备下面的特色:
(1) 超大规模。“云”具备超大的规模,Google云计算拥有100多万台server,Amazon、IBM、微软等的云均拥有几十万台server,正是这样拥有超大规模的“云”能够赋予用户史无前例的计算能力。
(2) 虚拟化。云计算支持用户在任何位置,使用各类终端获取应用服务。所请求的资源来自“云”,而不是固定的有形的实体。应用在“云”中某处执行。但实际用户无需了解、也不用操心应用执行的详细位置。仅仅需要一台笔记本或者一部手机,就可以经过网络服务来实现咱们需要的一切,甚至包含超级计算的任务。
(3) 高可靠性。“云”使用了数据多副本容错、计算节点同构可互换等措施来保障服务的高可靠性,使用云计算比使用本地计算可靠。
(4) 通用性。云计算不针对特定的应用。在云的支撑下可以构造出变幻无穷的应用。同一个云可以同一时候支撑不一样的应用执行
(5) 高可扩展性。
云的规模可以动态伸缩。知足应用和用户规模增加的需要。
(6) 按需服务。云是一个庞大的资源池,可按需购买,象自来水。电,煤气同样计费使用。
(7) 极其便宜。
用于“云”的特殊容错措施可以採用极其便宜的节点来构成云。“云”的本身主动化集中式管理使得大量企业无需负担日益高昂的数据中心管理成本,“云”的通用性使资源的利用率较之传统系统大幅提高,所以用户可以充分享受“云”的低成本优点。
大数据着眼于“数据”,关注实际业务。提供数据採集分析挖掘。看重信息积淀即数据存储能力。
云计算着眼于“计算”。关注IT解决方式,提供IT基础架构,看重计算能力,即数据处理能力,数据是二者之间最重要的联系,也是二者存在的意义,因此对于云计算和大数据时代。数据库技术的重要性也就不言而喻了。
2.2 云计算下的传统型数据库
随着web2.0的发展,传统的关系型数据库在应对超大规模和高并发的数据量和訪问量时存在难以克服的问题:
(1)高并发读写速度慢
在数据量达到必定规模时,由于关系型数据库的系统逻辑很复杂,使得其easy发生死锁等并发问题。致使其读写速度降低很严重。
(2)支撑容量有限
对于数据量巨大的一些站点好比社交站点,天天海量的用户动态,累计下每个月就能产生几亿条数据记录,对于关系型数据库。在这样一个具备数亿条记录的表中进行SQL查询,效率会是极其低下乃至不可忍受的。
(3)可扩展性差
在基于web的架构中,数据库是最难进行横向扩展的,当一个应用系统的用户量和訪问量与日俱增的时候,传统的关系型数据库却不能像web service 那样简单的经过加入不少其它的硬件和服务节点来扩展性能和负载能力。
对于很是多需要提供不间断服务的站点来讲,对数据库系统进行升级和扩展是很是痛苦的事情,每每需要停机维护和数据迁移,所以迫切需要关系数据库也能够经过不断加入server节点来实现扩展。
(4)建设和运维成本高
企业级数据库的价格很是高,并且随着系统的规模增大而不断上升。高昂的建设和运维成本没法知足云计算应用对数据库的需求。
(5)对于分布式系统的制约
为了支撑更大的訪问量和数据量,咱们一定需要分布式数据库系统,然而因为传统关系型数据库的强一致性,就会使得分布式系统的延迟提升,因为网络通讯自己比单机内通讯代价高很是多,这样的通讯的代价就会直接添加系统单次提交的延迟。延迟提升会致使数据库所持有时间变长,使得高冲突条件下分布式事物的性能不升反降,甚至性能距离单机数据库都还有明显的差距。
面对这个难题,传统的关系数据库选择了放弃分布式的方案,因为在20世纪70-80年代,数据库主要被用来处理企业内的各种数据,面对的用户只是几千人,而数据量最多也就是TB级别。
用单台机器处理事务。用个磁盘阵列处理一下磁盘容量不够的问题,基本就能解决一切问题。
然而,在大数据时代,云计算的数据量已然从TB级别变为了PB级别甚至不少其它。存在单点的单击系统无论怎样努力,都会面对系统处理能力的天花板,原来的这条路就不能再接着走下去了。
2.3 几种云计算下的新型数据库及事实上现原理
(1)NoSQL非关系型数据库
面对传统数据库出现的种种挑战,NoSQL是在新形势下出现的一种给关系型数据库的总称。它用全新的存储方式。下降了数据交互,下降了编写、调试的代码,对海量数据实现高效存储和高效訪问。同一时候它的开源免费也下降了企业的运营成本。
NoSQL的主要特征为:
1)不需要提早定义模式:不需要提早定义数据模式,提早定义表结构。
数据中的每条记录可能有不一样的属性和格式。当插入数据时,并不需要预先定义它们的模式。
2)无共享架构:相对于将所有数据存储的存储区域网络中的全共享架构。
NoSQL每每将数据划分后存储在各个本地server上。因为从本地磁盘读取数据的性能每每好于经过网络传输读取数据的性能。从而提升了系统的性能。
3)弹性可扩展:可以在系统执行的时候。动态添加或者删除结点。不需要停机维护,数据可以本身主动迁移。
4)分区:相对于将数据存放于同一个节点,NoSQL数据库需要将数据进行分区,将记录分散在多个节点上面。
并且一般分区的同一时候还要作复制。这样既提升了并行性能。又能保证没有单点失效的问题。
5)异步复制:和RAID存储系统不一样的是,NoSQL中的复制。每每是基于日志的异步复制。
这样,数据就可以尽快地写入一个节点。而不会被网络传输引发拖延。
缺点是并不老是能保证一致性,这种方式在出现问题的时候。可能会丢失少许的数据。
6)BASE:相对于事务严格的ACID特性,NoSQL数据库保证的是BASE特性。BASE是终于一致性和软事务。
NoSQL数据库并无一个统一的架构,两种NoSQL数据库之间的不一样,甚至远远超过两种关系型数据库的不一样。可以说,NoSQL各有所长。成功的NoSQL一定特别适用于某些场合或者某些应用。在这些场合中会远远赛过关系型数据库和其它的NoSQL。
详细优点表现有:
1)数据库的开发效率高,在设计上NoSQL数据库和传统的数据库有很是大的不一样,传统应用程序的开发中。需要在内存数据结构和福安息数据库的映射上花费大量的精力和时间。
NoSQL数据库更符合应用程序的需求,部分NoSQL数据库可以在硬盘上直接操做。简化了数据的交互,下降了编写、调试程序的工做量。
2)数据库的扩展能力强。现在企业一般使用更小,更廉价的计算机组成集群来构建数据库。NoSQL数据库的设计正是针对server集群。因此更适合大规模数据的处理。
3)数据库的开发成本低廉。因为NoSQL数据库主要都是开源软件,因此没有昂贵的开发成本。在项目开发中很是多企业为了节省开发成本而选择NoSQL数据库。
4)数据模型灵活。
在关系数据库中。数据有固定结构。经过各类操做互相关联。对大型的表格增删字段很麻烦。NoSQL的存储仅仅有一对键值或者数组。无需事先创建字段,不论何时都可以存储本身定义的数据格式。
NoSQL数据库的分类:
这一类数据库主要会使用到一个哈希表。这个表中有一个特定的键和一个指针指向特定的数据。Key/value模型对于IT系统来讲的优点在于简单、易部署。但是假设DBA仅仅对部分值进行查询或更新的时候,Key/value就显得效率低下了。
[3] 举好比:Tokyo Cabinet/Tyrant, Redis, Voldemort, Oracle BDB.
列存储数据库。
这部分数据库通常是用来应对分布式存储的海量数据。
键仍然存在。但是它们的特色是指向了多个列。这些列是由列家族来安排的。如:Cassandra, HBase, Riak.
文档型数据库
文档型数据库的灵感是来自于Lotus Notes办公软件的,而且它同第一种键值存储相相似。
该类型的数据模型是版本号化的文档,半结构化的文档以特定的格式存储,比方JSON。文档型数据库可 以看做是键值数据库的升级版,赞成之间嵌套键值。
而且文档型数据库比键值数据库的查询效率更高。
如:CouchDB, MongoDb. 国内也有文档型数据库SequoiaDB,已经开源。
图形(Graph)数据库
图形结构的数据库同其它行列以及刚性结构的SQL数据库不一样,它是使用灵活的图形模型,并且能够扩展到多个server上。NoSQL数据库没有标准的查询语言(SQL),所以进行数据库查询需要制定数据模型。
不少NoSQL数据库都有REST式的数据接口或者查询API。如:Neo4J, InfoGrid, Infinite Grap
(2)NewSQL
已知的第一个NewSQL系统叫作H-Store,它是一个分布式并行内存数据库系统。
新架构
第一类型的NewSQL系统是全新的数据库平台,它们均採取了不一样的设计方法。
它们大概分两类:
(1) 这类数据库工做在一个分布式集群的节点上,当中每个节点拥有一个数据子集。 SQL查询被分红查询片断发送给本身所在的数据的节点上运行。这些数据库可以经过加入额外的节点来线性扩展。现有的这类数据库有: Google Spanner, VoltDB, Clustrix, NuoDB.
(2) 这些数据库系统一般有一个单一的主节点的数据源。它们有一组节点用来作事务处理,这些节点接到特定的SQL查询后,会把它所需的所有数据从主节点上取回来后运行SQL查询,再返回结果。
第二类是高度优化的SQL存储引擎。这些系统提供了MySQL一样的编程接口。但扩展性比内置的引擎InnoDB更好。这类数据库系统有:TokuDB, MemSQL。
这类系统提供了分片的中间件层。数据库本身主动切割在多个节点执行。
这类数据库包扩:ScaleBase。dbShards, Scalearc。
2.4 当今几家主流互联网公司的数据库技术
(1)阿里分布式数据库服务DRDS
DRDS也是一个NewSQL的系统,它与ScaleBase、VoltDB等系统相似,都但愿能够找到一条既能保持系统的高扩展性和高性能,又能尽量保持传统数据库的ACID事务和SQL特性的分布式数据库系统。
三层架构,Matrix相应数据库切分场景,对SQL有必定限制,Group相应读写分离和高可用场景。对SQL差点儿没有限制。
DRDS主要功能介绍
分布式SQL运行引擎
分布式SQL引擎基本的目的,就是实现与单机数据库SQL引擎的全然兼容。眼下咱们的SQL引擎能够作到与MySQL的SQL引擎全兼容,包括各种join和各种复杂函数等。他主要包括SQL解析、优化、运行和合并四个流程,如图3中绿色部分。
尽管SQL是兼容的。但是分布式SQL运行算法与单机SQL的运行算法却全然不一样。缘由也很是easy,网络通讯的延迟比单机内通讯的延迟大得多。举个 样例说明一下。咱们有份文件要从一张纸A上誊写到另一张纸B上,单机系统就比如两张纸都在同一个办公室里,而分布式数据库则就像是一张纸在北京。一张纸 在杭州。
天然地,假设两张纸在同一个办公室,因为传输距离近,逐行誊写的效率是可以接受的。而假设距离是北京到杭州,用逐行誊写的方式。就立马显得代价太 高了,咱们总不能看一行。就打个“飞的”去杭州写下来吧。
在这样的状况下。仍是把纸A上的信息拍个照片。【一整批的】带到杭州去处理,明显更简单一些。这就 是分布式数据库特别强调吞吐调优的缘由,仅仅要是涉及到跨机的所有查询。都必须尽量的积攒一批后一块儿发送,以下降系统延迟提升带来的不良影响。
按需数据库集群平滑扩缩
DRDS赞成应用按需将新的单机存储增长或移出集群,DRDS则能够保证应用在迁移流程中实现不停机扩容缩容。
在内部的数据库使用实践中,这个功能的一个最重要应用场景就是双11了。在双11以前。会将大批的机器增长到咱们的数据库集群中,抗过了双11,这批机器就会下线。
因为全然没法预測在什么时间点系统会有爆发性的增加,而假设在这时候系统因为技术缘由不能使用。就会给整个业务带来毁灭性的影响,风口一旦错过,就追悔莫及了。我想这就是云计算特别强调可扩展能力的缘由吧。
小表广播
小表广播也是咱们在分布式数据库领域内最常用的工具之中的一个。他的核心目的事实上都是一个——尽量让查询仅仅发生在单机。
让咱们用一个样例来讲明。小表广播的通常使用场景。
图中,假设我想知道买家id等于0的用户在商城里面买了哪些商品,咱们一般会先将这两个表join起来。而后再用where平台名=”商城” and buyerID = 0找到符合要求的数据。然而这样的join的方式。会致使大量的针对左表的网络I/O。
假设要取出的数据量比較大。系统延迟会明显上升。
这时候,为了提高性能,咱们就必须要下降跨机join的网络代价。咱们比較推荐应用作例如如下处理,将左表拷贝到右表的每一个库上。这样,join操做就由分布式join一下变回到本地join。系统的性能就有很是大的提高了,如图所看到的。
分布式事务套件
在阿里巴巴的业务体系中存在许多需要事务类的场景。下单减库存,帐务,都是事务场景最集中的部分。
而咱们处理事务的方法却和传统应用处理事务的方案不大同样。咱们很强调事务的终于一致性和异步化。利用这样的方式,能够极大地减小分布式系统中锁持有的时间,从而极大地提高系统性能。
这样的处理机制,是咱们分布式事务能够以极低成本大量执行的最核心法门。
在DRDS平台内,咱们将这些方案产品化,为了DRDS的分布式事务解决套件。
利用他们,可让你以比較低的成本。实现低延迟。高吞吐的分布式事务场景。
(2)MongoDB
MongoDB[1] 是一个基于分布式文件存储的数据库。由C++语言编写。
旨在为WEB应用提供可扩展的高性能数据存储解决方式。
MongoDB[2] 是一个介于关系数据库和非关系数据库之间的产品。是非关系数据库其中功能最丰富,最像关系数据库的。他支持的数据结构很松散,是相似json的bson格式。所以可以存储比較复杂的数据类型。
Mongo最大的特色是他支持的查询语言很强大,其语法有点相似于面向对象的查询语言,差点儿可以实现相似关系数据库单表查询的绝大部分功能,而且还支持对数据创建索引。
它的特色是高性能、易部署、易使用,存储数据很方便。主要功能特性有:
*面向集合存储,易存储对象类型的数据。
*模式自由。
*支持动态查询。
*支持全然索引。包括内部对象。
*支持查询。
*支持复制和故障恢复。
*使用高效的二进制数据存储,包含大型对象(如视频等)。
*本身主动处理碎片。以支持云计算层次的扩展性。
*支持RUBY。PYTHON。JAVA。C++,PHP,C#等多种语言。
*文件存储格式为BSON(一种JSON的扩展)。
*可经过网络訪问。
所谓“面向集合”(Collection-Oriented),意思是数据被分组存储在数据集中,被称为一个集合(Collection)。
每个集合在数据库中都有一个惟一的标识名,并且能够包括无限数目的文档。
集合的概念相似关系型数据库(RDBMS)里的表(table),不一样的是它不需要定义不论什么模式(schema)。Nytro MegaRAID技术中的闪存快速缓存算法。能够快速识别数据库内大数据集中的热数据,提供一致的性能改进。
模式自由(schema-free),意味着对于存储在mongodb数据库中的文件,咱们不需要知道它的不论什么结构定义。
假设需要的话,你全然可以把不一样结构的文件存储在同一个数据库里。
存储在集合中的文档,被存储为键-值对的形式。键用于惟一标识一个文档,为字符串类型。而值则可以是各类复杂的文件类型。
咱们称这样的存储形式为BSON(Binary Serialized Document Format)。[3]
[4] MongoDB已经在多个网站部署,其主要场景例如如下:
1)站点实时数据处理。它很适合实时的插入、更新与查询。并具有站点实时数据存储所需的复制及高度伸缩性。
2)缓存。由于性能很是高,它适合做为信息基础设施的缓存层。在系统从新启动以后,由它搭建的持久化缓存层可以避免下层的数据源过载。
3)高伸缩性的场景。很适合由数十或数百台server组成的数据库。它的路线图中已经包括对MapReduce引擎的内置支持。
不适用的场景例如如下:1)要求高度事务性的系统。
2)传统的商业智能应用。
3)复杂的跨文档(表)级联查询。
MongoDB 的设计目标是高性能、可扩展、易部署、易使用。存储数据很方便。其主要功能特性例如如下。
(1)面向集合存储,easy存储对象类型的数据。在MongoDB 中数据被分组存储在集合中,集合相似RDBMS 中的表,一个集合中可以存储无限多的文档。
(2)模式自由,採用无模式结构存储。在MongoDB 中集合中存储的数据是无模式的文档,採用无模式存储数据是集合差异于RDBMS 中的表的一个重要特征。
(3)支持全然索引,可以在随意属性上创建索引,包括内部对象。
MongoDB的索引和RDBMS 的索引基本同样。可以在指定属性、内部对象上建立索引以提升查询的速度。
除此以外,MongoDB 还提供建立基于地理空间的索引的能力。
(4)支持查询。MongoDB 支持丰富的查询操做,MongoDB 差点儿支持SQL中的大部分查询。
(5)强大的聚合工具。
MongoDB 除了提供丰富的查询功能外。还提供强大的聚合工具,如count、group 等,支持使用MapReduce 完毕复杂的聚合任务。
(6)支持复制和数据恢复。
MongoDB 支持主从复制机制,可以实现数据备份、故障恢复、读扩展等功能。而基于副本集的复制机制提供了本身主动故障恢复的功能。确保了集群数据不会丢失。
(7)使用高效的二进制数据存储,包含大型对象(如视频)。使用二进制格式存储,可以保存不论什么类型的数据对象。
(8)本身主动处理分片,以支持云计算层次的扩展。MongoDB 支持集群本身主动切分数据。对数据进行分片可以使集群存储不少其它的数据,实现更大的负载。也能保证存储的负载均衡。
(9)支持Perl、PHP、Java、C#、JavaScript、Ruby、C 和C++语言的驱动程序。MongoDB 提供了当前所有主流开发语言的数据库驱动包,开发者使用不论什么一种主流开发语言都可以轻松编程。实现訪问MongoDB 数据库。
(10)文件存储格式为BSON(JSON 的一种扩展)。
BSON 是对二进制格式的JSON 的简称,BSON 支持文档和数组的嵌套。
(11)可以经过网络訪问。
可以经过网络远程訪问MongoDB 数据库。
(3)亚马逊自主研发的数据库:DynamoDB
DynamoDB是亚马逊自主研发的NoSQL型数据库,Amazon DynamoDB 是一项高速灵活的 NoSQL 数据库服务,适合所有需要一致性且延迟低于 10 毫秒的随意规模的应用程序。它是全然托管的云数据库,支持文档和键值存储模型。
其灵活的数据模型和可靠的性能令其成为移动、Web、游戏、广告技术、物联网和众多其它应用的不二之选。
Amazon DynamoDB 旨在为所有应用程序提供高速稳定、规模弹性的性能。服务端平均延迟一般不超过十毫秒。
随着您的数据卷增多。应用程序性能要求添加,Amazon DynamoDB 使用本身主动分区和 SSD 技术来知足您的吞吐量需求。以随意规模提供低延迟。
建立表时,仅仅需指定所需的请求容量就能够。假设您的应用吞吐量需求发生变化,仅仅需使用 AWS 管理控制台或 Amazon DynamoDB API 调用更新表的请求容量就能够。虽然 Amazon DynamoDB 在后台管理所有的扩展工做,您仍然可以在扩展进行过程当中达成您的优先吞吐量等级。
Amazon DynamoDB 支持文档和键值数据结构,您可以灵活地设计最适合您的应用程序的最佳架构。
Amazon DynamoDB 与 AWS Identity and Access Management (IAM) 集成,对组织内的用户实现精细的訪问控制。
您可以为每名用户分配惟一的安全证书,控制每名用户对服务和资源的訪问。
全然托管
Amazon DynamoDB 是全然托管的云 NoSQL 数据库服务。您仅仅需建立数据库表并设置吞吐量,其他事情都交由该服务来代劳。您无需再操心数据库管理任务。好比硬件或软件配置、建立设置和配置、软件更新、操做可靠的分布式数据库集群,或者随着扩展需要在多个实例间对数据进行分区等问题,您仅仅需尽享 Amazon DynamoDB 服务之大成。
(4)FaceBook图形数据库TAO
在Facebook上,人们已经造成了一个复杂的社会关系网络,怎样去存储、扩展和展现这个网络是Facebookproject师的一大难题。
早在几年前。Facebook的project师就意识到:关系型数据库的老方法。正在逐步减小基础设施和代码的效率。2009年。他们開始设计一种新的数据库体系结构,也就是分布式数据库TAO(The Associations and Objects)。6月25日,Facebook在官方博客上发布了支持其基础设施细节。
Facebook的软件project师Mark Marchukov在博客中表示他们之因此建立TAO的缘由之中的一个在于同一时候使用MySQL和Memcached读取数据太复杂了。产品project师要工做在两种全然不一样的数据模型之间:大规模的MySQLserver用关系表存储持久数据,相似数量的缓存数据server用来存储SQL查询到的键值对。即使是封装在数据訪问库中最多见的操做,也需要产品project师对系统内部有充分的了解,才干高效地使用memcache-MySQL组合。
TAO的图型架构在信息组织方面相似于Facebook的图搜索工具。它将世界看做由节点(对象,即人、地点和事物)和边(关联,即他们之间的关系)组成的图。
随着数据量的增大,保持数据的关系模式变得再也不重要,TAO及其相应的API应运而生。
Marchukov以为TAO最大的突破在于实现了图解模型,Facebook的主要工做负载在于读取数据。TAO证实了图数据模型很是适合这类查询操做较多的站点。实际上。相似Neo4j的图形数据库一直备受关注,因为它能有效表示人际关系。
Marchukov 在博客中提到,TAO不只大规模实现了图数据结构,也使用MySQL实现硬盘上的持久存储,同一时候要保证数据在各个数据中心的终于一致性。用户才干获取“新奇事”。
TAO服务执行在大量的server集群上,这些分布在不一样地理位置的集群构成一个树形网络。有另外的集群用来持久存储对象和对象关联,RAM和闪存实现缓存。这样的分层结构在单独进行不一样类型的集群扩展时更方便,也能有效利用server硬件。
(5)Google Spanner简单介绍
Spanner 是Google的全球级的分布式数据库 (Globally-Distributed Database) 。
Spanner的扩展性达到了使人咋舌的全球级。可以扩展到数百万的机器,数已百计的数据中心,上万亿的行。
更给力的是,除了夸张的扩展性以外。他还能 同一时候经过同步复制和多版本号来知足外部一致性,可用性也是很是好的。冲破CAP的枷锁,在三者之间完美平衡。
Spanner是个可扩展,多版本号。全球分布式还支持同步复制的数据库。
他是Google的第一个可以全球扩展并且支持外部一致的事务。Spanner能 作到这些,离不开一个用GPS和原子钟实现的时间API。这个API能将数据中心之间的时间同步精确到10ms之内。所以有几个给力的功能:无锁读事务, 原子schema改动,读历史数据无block。
如下主要是Spanner的背景,设计和并发控制。
Spanner背景
要搞清楚Spanner原理,先得了解Spanner在Google的定位。
从上图可以看到。Spanner位于F1和GFS之间。承上启下。因此先提一提F1和GFS。
F1
和众多互联网公司同样。在早期Google大量使用了Mysql。
Mysql是单机的,可以用Master-Slave来容错。分区来扩展。
但是需 要大量的手工运维工做。有很是多的限制。所以Google开发了一个可容错可扩展的RDBMS——F1。和通常的分布式数据库不一样。F1相应RDMS应有的 功能,绝不妥协。起初F1是基于Mysql的,只是会逐渐迁移到Spanner。
F1有例如如下特色:
· 7×24高可用。
哪怕某一个数据中心中止运转,仍然可用。
· 可以同一时候提供强一致性和弱一致。
· 可扩展
· 支持SQL
· 事务提交延迟50-100ms。读延迟5-10ms,高吞吐
众所周知Google BigTable是重要的NoSql产品,提供很是好的扩展性,开源世界有HBase与之相应。为何Google还需要F1。而不是都使用 BigTable呢?因为BigTable提供的终于一致性。一些需要事务级别的应用没法使用。同一时候BigTable仍是NoSql,而大量的应用场景需 要有关系模型。就像现在大量的互联网企业都使用Mysql而不肯意使用HBase,所以Google才有这个可扩展数据库的F1。
而Spanner就是 F1的相当重要的底层存储技术。
Colossus(GFS II)
Colossus也是一个不得不提起的技术。他是第二代GFS。相应开源世界的新HDFS。
GFS是著名的分布式文件系统。
初代GFS是为批处理设计的。对于大文件很是友好。吞吐量很是大,但是延迟较高。因此使用他的系统不得不正确GFS作各类优化。才干得到良好的性能。那为何 Google没有考虑到这些问题,设计出更完美的GFS ?因为那个时候是2001年。Hadoop出生是在2007年。假设Hadoop是世界率先水平的话。GFS比世界率先水平还率先了6年。
相同的 Spanner出生大概是2009年。现在咱们看到了论文,预计Spanner在Google已经很是无缺,同一时候Google内部已经有更先进的替代技术在 酝酿了。
笔者预測,最先在2015年才会出现Spanner和F1的山寨开源产品。
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份,提升写的性能,减小延迟。client来复制数据。详细细节笔者也猜不出。
与BigTable, Megastore对照
Spanner主要致力于跨数据中心的数据复制上,同一时候也能提供数据库功能。在Google相似的系统有BigTable和Megastore。和这二者相比,Spanner又有什么优点呢。
BigTable在Google获得了普遍的使用,但是他不能提供较为复杂的Schema,还有在跨数据中心环境下的强一致性。
Megastore 有类RDBMS的数据模型。同一时候也支持同步复制。但是他的吞吐量太差,不能适应应用要求。Spanner再也不是相似BigTable的版本号化 key-value存储,而是一个“暂时多版本号”的数据库。
何为“暂时多版本号”,数据是存储在一个版本号化的关系表里面,存储的时间数据会依据其提交的时间 打上时间戳,应用可以訪问到较老的版本号,另外老的版本号也会被垃圾回收掉。
Google官方以为 Spanner是下一代BigTable。也是Megastore的继任者。
Google Spanner设计
功能
从高层看Spanner是经过Paxos状态机将分区好的数据分布在全球的。数据复制全球化的。用户可以指定数据复制的份数和存储的地点。 Spanner可以在集群或者数据发生变化的时候将数据迁移到合适的地点,作负载均衡。用户可以指定将数据分布在多个数据中心,只是不少其它的数据中心将形成 不少其它的延迟。
用户需要在可靠性和延迟之间作权衡,通常来讲复制1。2个数据中心足以保证可靠性。
做为一个全球化分布式系统,Spanner提供一些有趣的特性。
· 应用可以细粒度的指定数据分布的位置。精确的指定数据离用户有多远,可以有效的控制读延迟(读延迟取决于近期的拷贝)。指定数据拷贝之间有多远,可以控制 写的延迟(写延迟取决于最远的拷贝)。还要数据的复制份数,可以控制数据的可靠性和读性能。(多写几份,可以抵御更大的事故)
· Spanner还有两个通常分布式数据库不具有的特性:读写的外部一致性。基于时间戳的全局的读一致。这两个特性可以让Spanner支持一致的备份,一致的MapReduce,还有原子的Schema改动。
这写特性都得益有Spanner有一个全球时间同步机制。可以在数据提交的时候给出一个时间戳。因为时间是系列化的,因此才有外部一致性。
这个很是easy理解,假设有两个提交,一个在T1,一个在T2。那有更晚的时间戳那个提交是正确的。
这个全球时间同步机制是用一个具备GPS和原子钟的TrueTime API提供了。这个TrueTime API可以将不一样数据中心的时间误差缩短在10ms内。这个API可以提供一个精确的时间。同一时候给出偏差范围。
Google已经有了一个TrueTime API的实现。笔者认为这个TrueTimeAPI 很是有意义。假设能单独开源这部分的话,很是多数据库如MongoDB都可以从中受益。
体系结构
Spanner由于是全球化的,因此有两个其它分布式数据库没有的概念。
· Universe。一个Spanner部署实例称之为一个Universe。
眼下全世界有3个。一个开发,一个測试。一个线上。因为一个Universe就能覆盖全球,不需要多个。
· Zones. 每个Zone至关于一个数据中心,一个Zone内部物理上必须在一块儿。而一个数据中心可能有多个Zone。
可以在执行时加入移除Zone。
如图所看到的。一个Spanner有上面一些组件。
实际的组件确定不止这些。比方TrueTime API Server。
假设只知道这些知识。来构建Spanner是远远不够的。
但Google都略去了。那笔者就简要介绍一下。
· Universemaster: 监控这个universe里zone级别的状态信息
· Placement driver:提供跨区数据迁移时管理功能
· Zonemaster:至关于BigTable的Master。管理Spanserver上的数据。
· Location proxy:存储数据的Location信息。client要先訪问他才知道数据在那个Spanserver上。
· Spanserver:至关于BigTable的ThunkServer。用于存储数据。
可以看出来这里每个组件都很是有料。但是Google的论文里仅仅具体介绍了Spanserver的设计,笔者也仅仅能介绍到这里。如下具体阐述Spanserver的设计。
Spanserver
本章具体介绍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来协调。当中一个Transactionmanager被选为leader,其它的是slave听他指挥。这样可以保证事务。
Directories and Placement
之因此Spanner比BigTable有更强的扩展性。在于Spanner另外一层抽象的概念directory, directory是一些key-value的集合。一个directory里面的key有同样的前缀。更稳当的叫法是bucketing。 Directory是应用控制数据位置的最小单元。可以经过慎重的选择Key的前缀来控制。据此笔者可以猜出,在设计初期,Spanner是做为F1的存 储系统而设立,甚至还设计有相似directory的层次结构。这种层次有很是多优势,但是实现太复杂被摒弃了。
Directory做为数据放置的最小单元。可以在paxos group里面移来移去。
Spanner移动一个directory通常出于例如如下几个缘由:
· 一个paxos group的负载太大,需要切分
· 将数据移动到access更近的地方
· 将经常同一时候訪问的directory放到一个paxos group里面
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仍是被简化过的。还有很是多没法详述。
数据模型
Spanner的数据模型来自于Google内部的实践。在设计之初。Spanner就决心有下面的特性:
· 支持相似关系数据库的schema
· Query语句
· 支持广义上的事务
为什么会这样决定呢?在Google内部另外一个Megastore,虽然要忍受性能不够的折磨,但是在Google有300多个应用在用它,因为 Megastore支持一个相似关系数据库的schema,而且支持同步复制 (BigTable仅仅支持终于一致的复制) 。使用Megastore的应用有大名鼎鼎的Gmail, Picasa, Calendar, Android Market和AppEngine。 而必须对Query语句的支持,来自于广受欢迎的Dremel,笔者不久前写了篇文章来介绍他。 最后对事务的支持是比不可少了,BigTable在Google内部被抱怨的最多的就是其仅仅能支持行事务。再大粒度的事务就无能为力了。Spanner的 开发人员以为,过分使用事务形成的性能降低的恶果。应该由应用的开发人员承担。
应用开发人员在使用事务的时候,必须考虑到性能问题。而数据库必须提供事务机制。 而不是因为性能问题,就干脆不提供事务支持。
数据模型是创建在directory和key-value模型的抽象之上的。一个应用可以在一个universe中创建一个或多个 database。在每个database中创建随意的table。Table看起来就像关系型数据库的表。
有行,有列。还有版本号。Query语句看起来 是多了一些扩展的SQL语句。
Spanner的数据模型也不是纯正的关系模型,每一行都必须有一列或多列组件。
看起来仍是Key-value。
主键组成Key,其它的列是Value。但这种设计相应用也是很是有裨益的。应用可以经过主键来定位到某一行。
上图是一个样例。对于一个典型的相冊应用,需要存储其用户和相冊。可以用上面的两个SQL来建立表。Spanner的表是层次化的,最顶层的表是 directory table。
其它的表建立的时候。可以用interleave in parent来什么层次关系。这种结构,在实现的时候,Spanner可以将嵌套的数据放在一块儿,这样在分区的时候性能会提高很是多。不然Spanner 没法获知最重要的表之间的关系。
TrueTime
TrueTime API 是一个颇有创意的东西,可以同步全球的时间。上表就是TrueTime API。
TT.now()可以得到一个绝对时间TTinterval。这个值和UnixTime是一样的。同一时候还可以获得一个偏差e。 TT.after(t)和TT.before(t)是基于TT.now()实现的。
那这个TrueTime API实现靠的是GFS和原子钟。之因此要用两种技术来处理,是因为致使这两个技术的失败的缘由是不一样的。GPS会有一个天线。电波干扰会致使其失灵。原子钟很是稳定。当GPS失灵的时候。原子钟仍然能保证在至关长的时间内,不会出现误差。
实际部署的时候。每个数据中心需要部署一些Master机器,其它机器上需要有一个slave进程来从Master同步。有的Master用 GPS,有的Master用原子钟。这些Master物理上分布的比較远,怕出现物理上的干扰。比方假设放在一个机架上,机架被人碰倒了。就全宕了。另外 原子钟不是并非常贵。Master本身还会不断比对,新的时间信息还会和Master自身时钟的比对,会排除掉误差比較大的,并得到一个保守的结果。
终于 GPS master提供时间准确度很是高,偏差接近于0。
每个Slave后台进程会每个30秒从若干个Master更新本身的时钟。为了减小偏差,使用Marzullo算法。
每个slave还会计算出本身的偏差。这里的偏差包含的通讯的延迟,机器的负载。
假设不能訪问Master,偏差就会越走越大。知道又一次可以訪问。
Google Spanner并发控制
Spanner使用TrueTime来控制并发。实现外部一致性。
支持下面几种事务。
· 读写事务
· 仅仅读事务
· 快照读,client提供时间戳
· 快照读。client提供时间范围
好比一个读写事务发生在时间t,那么在全世界不论什么一个地方,指定t快照读都可以读到写入的值。
单独的写操做都被实现为读写事务 ; 单独的非快照被实现为仅仅读事务。事务总有失败的时候,假设失败。对于这两种操做会本身重试。无需应用本身实现重试循环。
时间戳的设计大大提升了仅仅读事务的性能。事务開始的时候,要声明这个事务里没有写操做。仅仅读事务可不是一个简单的没有写操做的读写事务。
它会用一个 系统时间戳去读。因此对于同一时候的其它的写操做是没有Block的。而且仅仅读事务可以在随意一台已经更新过的replica上面读。
对于快照读操做,可以读取曾经的数据。需要client指定一个时间戳或者一个时间范围。
Spanner会找到一个已经充分更新好的replica上读取。
另外一个有趣的特性的是,对于仅仅读事务,假设运行到一半,该replica出现了错误。
client没有必要在本地缓存刚刚读过的时间,因为是依据时间戳读取的。
仅仅要再用刚刚的时间戳读取,就可以得到同样的结果。
读写事务
正如BigTable同样,Spanner的事务是会将所有的写操做先缓存起来。在Commit的时候一次提交。这种话,就读不出在同一个事务中写的数据了。只是这没有关系。因为Spanner的数据都是有版本号的。
在读写事务中使用wound-wait算法来避免死锁。当client发起一个读写事务的时候,首先是读操做,他先找到相关数据的leader replica。而后加上读锁。读取近期的数据。在client事务存活的时候会不断的向leader发心跳,防止超时。当client完毕了所有的读操做。并且缓存 了所有的写操做,就開始了两阶段提交。client闲置一个coordinator group,并给每一个leader发送coordinator的id和缓存的写数据。
leader首先会上一个写锁。他要找一个比现有事务晚的时间戳。
经过Paxos记录。每一个相关的都要给coordinator发送他本身准备的那个时间戳。
Coordinatorleader一開始也会上个写锁。当你们发送时间戳给他以后,他就选择一个提交时间戳。这个提交的时间戳,必须比刚刚的所有时间戳晚,而且还要比TT.now()+偏差时间 还有晚。这个Coordinator将这个信息记录到Paxos。
在让replica写入数据生效以前,coordinator还有再等一会。需要等两倍时间偏差。这段时间也恰好让Paxos来同步。因为等待之 后。在随意机器上发起的下一个事务的開始时间,都比方不会比这个事务的结束时间早了。
而后coordinator将提交时间戳发送给client还有其它的 replica。他们记录日志,写入生效,释放锁。
仅仅读事务
对于仅仅读事务,Spanner首先要指定一个读事务时间戳。还需要了解在这个读操做中,需要訪问的所有的读的Key。Spanner可以本身主动肯定Key的范围。
假设Key的范围在一个Paxos group内。client可以发起一个仅仅读请求给group leader。leader选一个时间戳,这个时间戳要比上一个事务的结束时间要大。
而后读取对应的数据。这个事务可以知足外部一致性。读出的结果是最后 一次写的结果,并且不会有不一致的数据。
假设Key的范围在多个Paxos group内。就相对复杂一些。当中一个比較复杂的样例是。可以遍历所有的group leaders,寻找近期的事务发生的时间。并读取。client仅仅要时间戳在TT.now().latest以后就可以知足要求了。
參考文献:
1、《挑战传统关系型数据库:FaceBook图形数据库TAO揭秘》 Jordan Novet
2、《云时代的分布式数据库:阿里分布式数据库服务DRDS》 沈询
3、《大数据与云计算》李永红
4、《基于云计算的数据库分析》 谢红
5、《全球级的分布式数据库Google Spanner原理》