@zmycoco
2017-03-18T05:17:08.000000Z
字数 6234
阅读 554
距离Google开始开发Spanner已经10年,5年前Google发表了论文,在Google云平台上增加开放Spanner服务,意义不仅仅是服务于AdWords和Google Play,而是希望在云端更有所为。在这5年时间里,正是由于其他厂商无法复制Google的想法,即不能解决大规模集群下高可用性、水平扩展能力、数据强一致性等。本文从Spanner技术着手,逐渐引出最近的特大消息:Google开放Spanner云端能力(测试版)。
简介
Spanner是Google的可扩展、多版本支持、全球分布式的同步备份数据库,领军人物是Eric Brewer,他是CAP理论的创造者、超级大牛。Spanner是第一个支持全球规模的分布式数据库。当数据量或者服务器数量发生变化时,Spanner在机器之间自动共享数据,并且Spanner在机器之间自动迁移数据(甚至在数据中心之间),用于负载均衡和响应失败。Spanner被设计为可以在数百万台机器之上横向扩展,覆盖数百个数据中心、上亿条数据。五年前发表的论文《在Google云平台上增加开放Spanner服务》,描述了Spanner数据库的内部结构是怎么样的、包含哪些属性、各种设计决策的基本原理,也暴露了一种新的不确定性时钟时间API。这些API和他们的实现对于支持外部一致性和几个重量级的特征来说极其重要,这些特征包括非阻塞式多版本读(nonblocking reads in the past)、无锁只读交易(lock-free read-only transactions)、原子模型变化(atomic schema changes),这些特征贯穿Spanner内部设计。
Spanner是一个在遍布全球范围的数据中心内部穿过多套Paxos状态机器共享数据的数据库。复制被用于全局可用性和地理位置;客户在副本之间自动切换。当数据量或者服务器数量发生变化时,Spanner在机器之间自动共享数据,并且Spanner在机器之间自动迁移数据(甚至在数据中心之间),用以负载均衡和响应失败。Spanner被设计为在几百万台机器之上横向扩展,这些扩展穿过了数百个数据中心和万亿行数据。
应用程序可以使用Spanner实现高可用性,甚至面对大面积的自然灾害,通过地区内部、甚至跨洲的备份数据策略。Spanner最早的客户是F1,它是一个Google广告系统的后台程序。F1在美国境内一共有5个副本。大多数应用程序在选择分布式数据库的时候,首选要求是低延时,然后才是高可用性,只要能够挺过1-2次数据中心故障就可以了。
Spanner是从类似于Bigtable这样的键值对(Key-Value)存储演变过来的一种时态多版本数据库。数据被存储在半关系型数据模型里,数据通过版本管理,每一个版本自动创建提交时间作为时间戳,老版本的数据服从垃圾回收机制管理。
和NoSQL数据库不同,Spanner属于NewSQL数据库。
与其他数据库对比
我们针对Spanner、关系型数据库、NoSQL数据库所能提供的功能进行对比,如图所示。
Spanner Schema设计
Spanner不需要每张表必须有一个主键列。由于Bigtable持续被投诉,所以Google在设计Spanner时把分布式交易集中化,因为过多的交易容易造成性能瓶颈出现。
在Spanner的模式定义语言里,你可以在表之间使用INTERIAVE IN申明表之间的层次关系。在层次关系的最顶层表示一张Directory表,其他的下级表示按照字典形式命名排序的。ON DELETE CASCADE被用于当Directory表里的一行数据被删除时,相应地一并删除子表里的对应数据。创建Spanner数据表如图所示。
读/写方式
Spanner提供三种类型的操作:读/写交易、读交易和快照读操作。单一的写操作是通过一个读/写交易执行的,然而一个单一的读操作,不是一个快照读,是通过一个读交易执行的。
一个写操作执行了一个读/写交易,在提交交易之前都是缓存在客户端。一个交易里面的读操作,不会被写操作的结果所影响。读/写交易当中的读操作使用了Wound-Wait方式避免死锁。客户端从协调节点获取读锁,然后读取最新的数据。
全球分布式设计
Spanner最初的出现就是因为Google内部使用的Bigtable无法确保跨地区的数据中心强一致性。Spanner的整体集合被称为Universe。一个Universe又由几个Zone组成。一个Zone意味着一个单元,这个单元可以物理上独立运行。一个数据中心可能超过1个Zone。如果你想要在不同的服务组内存储数据,你需要在一个数据中心内部建立两个或者以上的Zone。
上面这张图显示了在一个Universe里面配置的服务器,一个Zone由一个Zonemaster和几千个Spanserver组成。Zonemaster为Spanserver分配数据。同时,Spanserver实际存储和处理数据。Location Proxy通过客户端调用,显示目标数据被存储在哪个Spanserver。Universemaster提供了所有Zone的状态或者调试信息,并且Placement Driver实际上执行Zone之间的数据传输,决定是否数据被移除了(由于备份策略改变或者通过与Spanserver之间的定期通信进行负载均衡)。
每一个spanner serve大约有10到1000个被叫做Tablet的数据结构。Tablet可以存储多个映射,字符串(key:string, timestamp:int64)形式。Spanner里的Tablet和BigTable里的Tablet的差别是,Spanner存储一个数据的同时带了时间戳。这意味着Spanner不仅仅是一个简单的键值对存储,而是带有多版本特性的数据库。
Table 的状态存储在Colossus Distributed File System,基于二叉树文件形式和write-ahead log(WAL)。
Spanner使用Paxos状态机支持spanservers之间的数据备份。
一个spanserver有交易管理者,用于支持分布式事务。交易管理者在单一Paxos组内不会参与交易执行,但是当多个Paxos组之间进行交易时它会参与进去,参与人之一会被选举为协调组长,基于phase-2 commit协议执行协调。
目录是一组连续的键,这些键使用相同的前缀(你可以想象成一个桶)。Directory是一个数据分配的基本单元。Directory里面的所有数据有定义好的备份设置,并且Paxos组之间的数据传输也是指定的。
一个应用程序可以在一个universe内部创建1个或多个数据库,一个数据库有多张表(没有上限)。一张表有行和列,比关系型数据库表多的是有版本信息。在Spanner的模式定义语言里,你可以在表之间使用INTERLEAVE IN申明层次(hierachical)关系。在层次关系的最顶层表示一张directory表。根据directory表里定义的键,字表命名是根据字典排序的。ON DELETE CASCADE被用于当directory表的一行数据被删除时,相应地一起删除子表里面的数据。
F1
Spanner的最早的客户是F1,它是一个Google广告系统的后台程序。F1在美国境内一共有5个副本。许多其他的应用程序最有可能的是在一个地理区间内在3到5个数据中心中间复制数据,但是它们具有相对独立的失效模式(failure mode)。也就是说,大多数应用程序会首选较低延迟,然后才是高可用性,只要能够挺过1到2次的数据中心故障。
Google F1 SQL数据库管理系统构建在Spanner之上,用于替换Google的MySQL定制版本。
Spanner使用Paxos算法作为操作的一部分,用于在数百个数据中心之间共享数据。
技术总结
Spanner提供了类似于关系型数据库的功能支持和操作方式,每张表都有主键、可以管理和删除级联表的数据。Spanner支持ACID和SQL语句。由于Spanner会把上亿条数据存放在全球很多数据中心里,所以当你读取数据时,Spanner把读取请求发到物理上最接近你的数据中心,当你写入数据时,你会存储到多个数据中心。如果数据中心整体停止服务,你也可以从副本数据中心环境读取数据。
Spanner并不开源,但是有开源实现CockroachDB,源码请访问这里。
2017年2月14日(情人节),Google宣布Cloud Spanner发布测试版本。这是一个基于云端的全球分布式关系数据库服务,支持包括ACID交易、SQL语义,支持水平扩展和高可用性。当我们构建一个基于云端的应用程序时,数据库管理员和开发人员都需要去选择使用关系型数据库或者NoSQL数据库,关系型数据确保交易持久性,NoSQL数据库提供了简单、水平扩展和数据分布式。Cloud Spanner打破了这种非此即彼的选择方案,提供了集两个关键能力与一体的,完全管理的服务。
Cloud Spanner与Google颇有渊源,早在2012年的一份文件中Google就记录了Cloud Spanner,并且已在内部使用多年。目前谷歌的云数据库服务阵营包括Google Bigtable(谷歌2015年发布的一个全面管理、高性能、可扩展的NoSQL数据库服务)、Google Container Engine(谷歌为解决企业管理大量容器技术编排的繁琐工作而推出的容器管理服务)等。
Google产品经理Deepti Srivastava曾在一篇博文中写道:
Cloud Spanner通过在熟悉的关系数据库环境中支持标准工具和语言,简化了应用程序开发。它是传统关系数据库支持运行的工作负载的理想选择,如库存管理,金融交易和控制系统以及其它系统。
Cloud Spanner 同 GCP、Cloud SQL、Cloud Datastore、Cloud Bigtable一起,丰富了我们数据库服务的能力。
作为一个可控的服务,Cloud Spanner给DBA提供了下列重要福利:
Cloud Spanner并没有违反CAP定理。这些年,我们已经让Spanner打赢了Google内部很多场战斗,数百个不同的应用程序,PB级别的数据在全球的数据中心间转移。在Google,Spanner支持每秒数以百万计次的查询,运行的应用程序包括AdWords和Google Play。
有了Cloud Spanner,你可以对数据库的规模按照需求来扩展和缩小,然后你只需要按照使用规模来付费即可。Spanner Cloud的特色之一就是提供了一个简洁的收费模式,可通过计算节点使用的小时数,实际存储消耗(而不是预估存储消耗)以及外部网络接入等指标来计算费用。
Cloud Spanner力图保持应用开发的简洁性,支持开发者们熟知的关系数据库环境、工具和语言。因此它对那些通过传统关系数据库来的驱动的应用作业(如装备管理,金融事务,控制系统,以及那些规模快速增长的系统)是非常理想的。Cloud Spanner同时还数据线了分布式事务,Scheme和DDL声明,SQL查询和JDBC驱动等功能,并且支持多种主流语言,如Java,Go,Python,Node.js等。
Google Cloud Platform也将继续完善Google Cloud SQL服务以及Google Cloud Datastore。与此同时,AWS和Microsoft也并未放慢在云领域的脚步。AWS提供与MySQL兼容的Aurora关系数据库以及关系数据库服务(RDS),而 Microsoft Azure在虚拟机(VM)上提供Azure SQL数据库以及SQL Server。
简而言之,距离Google开始开发Spanner已经10年,5年前Google发表了论文,在Google云平台上增加开放Spanner服务,意义不仅仅是服务于AdWords和Google Play,而是希望在云端更有所为。在这5年时间里,正是由于其他厂商无法复制Google的想法,即不能解决大规模集群下高可用性、水平扩展能力、数据强一致性等。Cloud Spanner在做到兼顾优势的同时,并没有违反CAP理论。这也就是为什么Spanner在云端开放服务的消息成为了一个冲击性的新闻,让我们拭目以待Google的极客精神。
NewSQL:这是一种完全不同的数据库架构。NoSQL的一个优点是横向扩展能力,缺点是没有提供强一致性,它们不可以被使用在强一致性环境下。NewSQL和NoSQL一样具有很强的扩展能力,同时也提供了和RDBMS一样的单个节点上的ACID。NewSQL术语最早在2011年由Matthew Aslett创造。HBase也提供了有限形式的事务(单行事务)。然而,这种有限交易不能完全吻合业务需求。HBase也是一种NewSQL。
wound-wait:Spanner论文中提到了使用“wound-wait”策略防范死锁。这是一种基于剥夺的方法,当进程Pi请求的资源正在被进程Pj占有时,只有当进程Pi的时间戳比进程Pj的时间戳大时,即Pi比Pj年轻时,Pi才能等待。否则Pj被Roll Back,即死亡。只要被Roll Back的进程重新启动,使用原有的时间戳,这两种方案就能避免死锁和饿死现象。由于时间戳总是增加的,被Roll Back的进程最终将具有最小的时间戳。
CAP定理:指的是在一个分布式系统中,一致性、可用性、分区容错性,三者不可得兼。CAP理论是在分布式存储系统中,最多只能实现上面的两点。而由于当前的网络硬件肯定会出现延迟丢包等问题,所以分区容忍性是必须实现的。
ACID:在可靠的数据库管理系统中,事务所应该具有的四个特性,即原子性、一致性、隔离性、持久性。原子性是指事务是一个不可再分割的工作单位,事务中的操作要么都发生,要么都不发生。一致性是指在事务开始之前和事务结束以后,数据库的完整性约束没有被破坏。这是说数据库事务不能破坏关系数据的完整性以及业务逻辑上的一致性。多个事务并发访问时,事务之间是隔离的,一个事务不应该影响其它事务运行效果。持久性,意味着在事务完成以后,该事务所对数据库所作的更改便持久的保存在数据库之中,并不会被回滚。
Google AdWords、Google Play:Google Play的前身是Android Market,是一个由Google为Android设备开发的在线应用程序商店。Google AdWords是一种通过使用Google关键字广告或者Google遍布全球的内容联盟网络,推广网站的付费网络推广方式。可以选择包括文字、图片及视频广告在内的多种广告形式。