云计算下的新型数据库技术
摘要:在这个信息化的时代,我们的一举一动都离不开与数据打交道,特别是云计算和大数据时代的到来,使得传统数据库的性能已无法满足海量数据的实时交易查询需求。在性能和成本的双重压力之下。云计算下的数据库须要寻找突破之路。
1.简单介绍:
云计算通过整合。管理和调配分布在互联网中的全部计算资源,以统一的界面同一时候向用户提供服务。
互联网提供的各种计算形式的应用以及提供这些服务的数据中心和软硬件基础设施、提供的服务成为软件即服务(SaaS),数据中心的软硬件基础设施即为云,这样的虚拟化资源提供计算的方式使得服务通过互联网传播,而用户不须要知道云计算服务的提供者和提供方式。因此。云计算具有规模大,可靠性高,用户透明,可扩展性强,提供按需服务和便宜等特点。
而实现以上需求的前提条件就是云计算系统应该具备足够大的规模和处理能力。以满足大量的数据訪问,数据存储和来自不同网络等额请求。
传统的关系型数据库尽管在数据存储方面占领着不可动摇的地位,但因为其天生的限制,越来越不能满足云计算下的数据扩展、读写速度、支撑容量以及建设和运营成本的要求。鉴于此。国内外知名的一些互联网企业Google、Facebook、Twitter、阿里、腾讯、百度等纷纷展开探索,自主研发新型数据库,这些企业有拥有众多的优秀人才。以及丰富的产品经验,所以对于新型数据库的探索成果在一定程度上也代表了当下云计算下数据库的最新的进展。所以本文主要先对与传统型数据库的优劣进行一些分析。接着介绍了现现在新型数据库的研究进展,对各类型数据库进行一些对照分析,最后在对于还存在的不足进行总结并对数据库的发展提出自己一些的看法。
2.背景:
2.1 云计算和大数据:
大数据是一种大规模数据的管理和利用的商业模式和技术平台的泛指,它不同于传统的海量数据,除了数据规模呈现几何级数增长的特征以外。还包含全部数据类型的採集、分类、处理、分析和展现等多个方面,从而终于实现从大数据中挖掘潜在巨大价值的目的。因此,大数据具有这4方面的特征:规模性(Volume)、多样性(Variety)、快速性(Velocity)和真实性(Veracity)。
云计算是一种基于互联网的计算方式,通过这样的方式,共享的软硬件资源和信息可以按需提供给计算机和其它设备。可以像煤气、水电一样提供给信息时代的社会化服务。使用方便。费用低廉。云计算具有下面的特点:
(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)存储数据库
这一类数据库主要会使用到一个哈希表。这个表中有一个特定的键和一个指针指向特定的数据。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是对各种新的可扩展/高性能数据库的总称,这类数据库不仅具有NoSQL对海量数据的存储管理能力,还有传统数据库支持ACID和SQL等特性。
NewSQL系统尽管在的内部结构变化非常大,可是它们有两个显着的共同特点:
(1)它们都支持关系数据模型。
(2) 它们都使用SQL作为其基本的接口。
已知的第一个NewSQL系统叫做H-Store,它是一个分布式并行内存数据库系统。
眼下NewSQL系统大致分三类:
新架构
第一类型的NewSQL系统是全新的数据库平台,它们均採取了不同的设计方法。
它们大概分两类:
(1) 这类数据库工作在一个分布式集群的节点上,当中每一个节点拥有一个数据子集。 SQL查询被分成查询片段发送给自己所在的数据的节点上运行。这些数据库能够通过加入额外的节点来线性扩展。现有的这类数据库有: Google Spanner, VoltDB, Clustrix, NuoDB.
(2) 这些数据库系统通常有一个单一的主节点的数据源。它们有一组节点用来做事务处理,这些节点接到特定的SQL查询后,会把它所需的全部数据从主节点上取回来后运行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 旨在为全部应用程序提供高速稳定、规模弹性的性能。服务端平均延迟通常不超过十毫秒。
随着您的数据卷增多。应用程序性能要求添加,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。
一个Zone能够理解为一个BigTable部署实例。
如图所看到的。一个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快照读都能够读到写入的值。
上表是Spanner如今支持的事务。
单独的写操作都被实现为读写事务 ; 单独的非快照被实现为仅仅读事务。事务总有失败的时候,假设失败。对于这两种操作会自己重试。无需应用自己实现重试循环。
时间戳的设计大大提高了仅仅读事务的性能。事务開始的时候,要声明这个事务里没有写操作。仅仅读事务可不是一个简单的没有写操作的读写事务。
它会用一个 系统时间戳去读。所以对于同一时候的其它的写操作是没有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原理》