从分布式到云端服务:Google Spanner 成长之路

为促进社区发展,运维派寻求战略合作、赞助、投资,请联系微信:helloywp

Google Spanner

摘要:距离 Google 开始开发 Spanner 已经 10 年,5 年前 Google 发表了论文,在 Google 云平台上增加开放 Spanner 服务,意义不仅仅是服务于 AdWords 和 Google Play,而是希望在云端更有所为。在这 5 年时间里,正是由于其他厂商无法复制 Google 的想法,即不能解决大规模集群下高可用性、水平扩展能力、数据强一致性等。本文从 Spanner 技术着手,逐渐引出最近的特大消息:Google 开放 Spanner 云端能力(测试版)。

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 数据库。

 NoSQL

与其他数据库对比

我们针对 Spanner、关系型数据库、NoSQL 数据库所能提供的功能进行对比,如图所示。

 数据库

 Spanner Schema 设计

Spanner 不需要每张表必须有一个主键列。由于 Bigtable 持续被投诉,所以 Google 在设计 Spanner 时把分布式交易集中化,因为过多的交易容易造成性能瓶颈出现。

在 Spanner 的模式定义语言里,你可以在表之间使用 INTERIAVE IN 申明表之间的层次关系。在层次关系的最顶层表示一张 Directory 表,其他的下级表示按照字典形式命名排序的。ON DELETE CASCADE 被用于当 Directory 表里的一行数据被删除时,相应地一并删除子表里的对应数据。创建 Spanner 数据表如图所示。

Spanner

读 / 写方式

Spanner 提供三种类型的操作:读 / 写交易、读交易和快照读操作。

单一的写操作是通过一个读 / 写交易执行的,然而一个单一的读操作,不是一个快照读,是通过一个读交易执行的。

一个写操作执行了一个读 / 写交易,在提交交易之前都是缓存在客户端。一个交易里面的读操作,不会被写操作的结果所影响。读 / 写交易当中的读操作使用了 Wound-Wait 方式避免死锁。客户端从协调节点获取读锁,然后读取最新的数据。

 全球分布式设计

Spanner 最初的出现就是因为 Google 内部使用的 Bigtable 无法确保跨地区的数据中心强一致性。Spanner 的整体集合被称为 Universe。一个 Universe 又由几个 Zone 组成。一个 Zone 意味着一个单元,这个单元可以物理上独立运行。一个数据中心可能超过 1 个 Zone。如果你想要在不同的服务组内存储数据,你需要在一个数据中心内部建立两个或者以上的 Zone。

Zone

上面这张图显示了在一个 Universe 里面配置的服务器,一个 Zone 由一个 Zonemaster 和几千个 Spanserver 组成。Zonemaster 为 Spanserver 分配数据。同时,Spanserver 实际存储和处理数据。Location Proxy 通过客户端调用,显示目标数据被存储在哪个 Spanserver。Universemaster 提供了所有 Zone 的状态或者调试信息,并且 Placement Driver 实际上执行 Zone 之间的数据传输,决定是否数据被移除了(由于备份策略改变或者通过与 Spanserver 之间的定期通信进行负载均衡)。

每一个 spanserver 大约有 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,源码请访问 https://github.com/cockroachdb/cockroach。

发布 Cloud Spanner 测试版本

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 提供了下列重要福利:

  1. 让 DBA 把宝贵的精力专注于业务逻辑上,而不是用于处理各种软件或硬件问题;
  2. 使得 DBA 不用执行复杂的分片或者集群操作,就可以实现对 RDBMS 解决方案的扩展;
  3. DBA 不用把关系数据库迁移到 NoSQL 数据中,也能获得数据的水平扩展能力;
  4. DBA 无需复杂的数据备份或失效援备机制,即可维护数据的高可用性,以及具备对数据的灾备恢复能力;
  5. 将安全性与数据层加密,身份验证,接入管理,日志审核等功能进行整合。

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 等。

Cloud Spanner

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:在可靠的数据库管理系统中,事务所应该具有的四个特性,即原子性、一致性、隔离性、持久性。原子性是指事务是一个不可再分割的工作单位,事务中的操作要么都发生,要么都不发生。一致性是指在事务开始之前和事务结束以后,数据库的完整性约束没有被破坏。这是说数据库事务不能破坏关系数据的完整性以及业务逻辑上的一致性。多个事务并发访问时,事务之间是隔离的,一个事务不应该影响其它事务运行效果。持久性,意味着在事务完成以后,该事务所对数据库所作的更改便持久的保存在数据库之中,并不会被回滚。

文章来自微信公众号:高效开发运维

网友评论comments

发表评论

电子邮件地址不会被公开。 必填项已用*标注

暂无评论

Copyright © 2012-2019 YUNWEIPAI.COM - 运维派 - 粤ICP备14090526号-3
扫二维码
扫二维码
返回顶部