Google Cloud Spanner:好,坏,邪恶

嗨哈布罗夫斯克 传统上,我们在预期推出新课程时会继续分享有趣的材料。今天,我们特别为您发布了一篇有关Google Cloud Spanner的文章,其发布时间恰好与AWS for Developers课程的启动相吻合




最初发布在Lightspeed HQ博客上


作为一家为世界各地的零售商,餐馆和在线零售商提供许多基于云的POS解决方案的公司,Lightspeed将几种不同类型的数据库平台用于各种交易,分析和搜索案例。每个数据库平台都有其优点和缺点,因此,当Google在市场上推出Cloud Spanner时,关系数据库世界中前所未有的有前途的功能,例如几乎无限的水平可扩展性和99.999%的服务水平协议(SLA), -我们不能错过获得它的机会!

为了全面概述我们在Cloud Spanner方面的经验以及我们使用的评估标准,我们将涵盖以下主题:

  1. 我们的评估标准
  2. 简而言之,云扳手
  3. 我们的评价
  4. 我们的发现



1.我们的评估标准


在深入研究Cloud Spanner的功能,其与市场上其他解决方案的异同之前,让我们先讨论一下在考虑将Cloud Spanner部署到基础架构中时要考虑的主要用户案例:

  • 替代(流行的)传统SQL数据库解决方案
  • 带有OLAP支持的OLTP解决方案如何

注意:为了简化并便于比较,本文将Cloud Spanner与MySQL GCP Cloud SQL和Amazon AWS RDS系列解决方案进行了比较。

使用Cloud Spanner替代传统的SQL数据库解决方案


传统的数据库环境中,当对数据库查询的响应时间接近甚至超过预定义的应用程序阈值时(主要是由于用户和/或查询数量的增加),有几种方法可以将响应时间减少到可接受的水平。但是,大多数这些解决方案都包括手动干预。

例如,您需要采取的第一步是查看与性能相关的各种数据库参数,并将其配置为与应用程序使用模式最匹配。如果这还不够,您可以选择垂直或水平缩放数据库。

扩展应用程序通常需要通过添加更多的处理器/内核,更多的RAM,更快的存储等来更新服务器实例。添加更多的硬件资源会导致数据库性能的提高,这主要是通过以下方式进行的:第二,OLTP系统的事务延迟。关系数据库系统(使用多线程方法),例如MySQL,可以很好地垂直扩展。

这种方法有几个缺点,但最明显的是市场上最大的服务器大小。一旦达到最大服务器实例的限制,就只有一种方法:水平扩展。

水平扩展是一种方法,其中将更多服务器添加到群集,以理想方式通过增加服务器数量线性地提高性能。大多数传统的数据库系统无法很好地横向扩展或根本无法扩展。例如,MySQL可以通过添加从属读取器来横向扩展读取操作,但是不能横向进行写入操作。

另一方面,由于其性质,Cloud Spanner可以轻松地水平扩展而干扰最小。

功能齐全的DBMS即服务必须从不同角度进行评估。作为基础,我们采用了云中最受欢迎的DBMS-Google,GCP Cloud SQL和Amazon,AWS RDS。在我们的评估中,我们重点关注以下类别:

  • 功能映射:SQL范围,DDL,DML;连接库/连接器,事务支持等。
  • 开发支持:易于开发和测试。
  • 管理支持:实例管理-例如,扩展/缩小和升级实例;SLA,备份和还原;安全/访问控制。

将Cloud Spanner用作具有OLAP支持的OLTP


尽管Google并未明确宣称Cloud Spanner用于分析处理,但它与其他机制(例如针对OLAP工作负载设计的Apache Impala&Kudu和YugaByte)具有一些共同点。

即使Cloud Spanner极少包含具有(或多或少)可用的OLAP功能集的一致的水平可扩展HTAP(混合事务/分析处理)引擎的机会,我们认为也应引起我们的注意。

考虑到这一点,我们检查了以下类别:

  • 数据加载,索引和分区支持
  • 查询性能和DML

2.简而言之,Cloud Spanner


Google Spanner是一个集群关系数据库管理系统(RDBMS),Google用于其自身的多项服务。Google于2017年初向Google Cloud Platform用户公开提供了此功能。

以下是Cloud Spanner的一些属性:

  • 高度一致的可伸缩RDBMS群集:使用硬件时间同步来确保数据一致性。
  • 跨表事务支持:事务可以跨多个表-不必限于一个表(与Apache HBase或Apache Kudu不同)。
  • : (), . , . , .
  • : . . , , , -.
  • : Cloud Spanner . . . . , , , . , .

«Cloud Spanner . , Cloud Spanner , - , ».


: Apache Tephra Apache HBase ( Apache Phoenix -).

3.


因此,我们都阅读了Google关于Cloud Spanner的好处的声明-几乎无限的水平扩展,同时保持了高一致性和很高的SLA。尽管无论如何都很难实现这些要求,但我们的目标不是反驳它们。相反,让我们关注大多数数据库用户关心的其他事情:奇偶校验和可用性。

我们将Cloud Spanner评定为可替代MySQL


Google Cloud SQL和Amazon AWS RDS是云市场上两个最流行的OLTP DBMS,具有非常大的功能集。但是,要将这些数据库扩展到单个节点之外,您需要执行应用程序分区。这种方法为应用程序和管理增加了额外的复杂性。我们研究了Spanner如何适合将多个段组合到一个实例中的情况,以及可能不得不牺牲哪些功能(如果有)。

是否支持SQL,DML和DDL以及连接器和库?


首先,从任何数据库开始时,必须创建一个数据模型。如果您认为可以将JDBC Spanner连接到您喜欢的SQL工具,则会发现可以使用它查询数据,但是您不能使用它来创建表或更改(DDL)或任何插入/更新/删除操作( DML)。Google的官方JDBC都不支持。
“驱动程序当前不支持DML或DDL。”
扳手文档

使用GCP控制台,情况再好不过-您只能发送SELECT查询。幸运的是,社区提供了一个具有DML和DDL支持的JDBC驱动程序,包括事务github.com/olavloite/spanner-jdbc。尽管此驱动程序非常有用,但是缺少Google自己的JDBC驱动程序令人惊讶。幸运的是,Google对客户端库(基于gRPC)提供了相当广泛的支持:C#,Go,Java,node.js,PHP,Python和Ruby。

几乎强制使用Cloud Spanner用户界面(由于JDBC中缺少DDL和DML)导致对代码相关领域的某些限制,例如连接池或数据库绑定框架(例如Spring MVC)。通常,在使用JDBC时,您可以自由选择自己喜欢的连接池(例如,HikariCP,DBCP,C3PO等),该连接池已经过测试并且运行良好。对于自定义Spanner API,我们必须依靠我们自己创建的框架/绑定池/会话。

通过PC进行主键(PC)设计时,Cloud Spanner的速度非常快,但也会导致一些查询问题。

  • ; . ( / .)
  • UPDATE DELETE WHERE, , DELETE all — , : UPDATE xxx WHERE id IN (SELECT id FROM table1)
  • - , . , .

?


Google Cloud Spanner内置了对二级索引的支持。这是一个非常好的功能,其他技术中并不总是存在。 Apache Kudu当前根本不支持二级索引,并且Apache HBase不直接支持二级索引,但是可以通过Apache Phoenix添加它们。

可以将Kudu和HBase中的索引建模为具有不同主键组成的单独表,但是在父表和相关索引表上执行的操作的原子性必须在应用程序级别执行,并且在正确的实现中并非无关紧要。

如Cloud Spanner评论中所述,其索引可能与MySQL索引不同。因此,在建立查询和分析时应格外小心,以确保在需要的地方使用正确的索引。

表示?


视图是数据库中非常流行且有用的对象。它们对于大量的用户案例很有用。我最喜欢的两个是逻辑抽象级别和安全级别。不幸的是,Cloud Spanner不支持提交。但是,这仅部分限制了我们,因为对于访问权限,在表示可能是可接受的解决方案的列级别没有粒度。

Cloud Spanner文档的一节详细介绍了配额和限制(扳手/配额),尤其是某些应用程序可能会遇到问题:开箱即用的Cloud Spanner每个实例最多限制100个数据库。显然,这对于设计为可扩展到100多个数据库的数据库可能是一个严重的障碍。幸运的是,在与我们的Google技术代表交谈后,我们发现可以通过Google支持将该限制提高到几乎任何价值。

开发支持?


Cloud Spanner对编程语言提供了相当不错的支持,以与其API一起使用。官方支持的库位于C#,Go,Java,node.js,PHP,Python和Ruby领域。该文档非常详细,但是与其他先进技术一样,与最流行的数据库技术相比,社区是很小的,这可能导致解决不常见用例或问题所花费的时间增加。

那么当地的发展支持呢?


我们找不到在本地环境中创建Cloud Spanner实例的方法。我们得到的最接近的是CockroachDB Docker映像,它在原理上是相似的,但实际上却大不相同。例如,CockroachDB可以使用PostgreSQL JDBC。由于开发环境应尽可能接近工作环境,因此Cloud Spanner并不理想,因为您需要依赖完整的Spanner实例。为了节省成本,您可以为一个区域选择一个实例。

行政支持?


创建Cloud Spanner实例很容易。您只需要在为一个区域创建多区域或实例之间进行选择,即可指定区域和节点数。在不到一分钟的时间内,实例将启动并运行。

在Google控制台的“扳手”页面上可以直接使用几个基本指标。可通过Stackdriver获得更详细的视图,您还可以在其中设置阈值指标和警报策略。

获得资源?


MySQL提供了广泛且非常详细的用户权限/角色设置。您可以轻松配置对特定表的访问,甚至可以仅配置其列的子集。Cloud Spanner使用Google身份和访问管理(IAM)工具,该工具仅允许您在很高的级别上设置策略和权限。最详细的选项是数据库级别的解决方案,不适用于大多数生产案例。此限制迫使您向代码和/或基础结构中添加其他安全措施,以防止未经授权使用Spanner资源。

备份?


简而言之,Cloud Spanner中没有备份。尽管Google SLA的高要求可以保证您不会因硬件或数据库故障,人为错误,应用程序缺陷等而丢失任何数据。我们都知道规则:高可用性不能替代合理的备份策略。目前,备份数据的唯一方法是以编程方式将其从数据库流式传输到单独的存储环境。

查询性能?


我们使用Yahoo!来下载数据和测试查询。云服务基准。下表显示了YCSB B工作负载,其读取率为95%,写入率为5%。



*负载测试是在n1-standard-32计算引擎(CE)(32 vCPU,120 GB内存)上执行的,并且测试实例绝不是测试的瓶颈。
**一个YCSB实例中的最大线程数为400。总计,必须运行六个并行的YCSB测试实例才能获得总共2400个线程。

查看测试结果,特别是处理器负载和TPS的组合,我们可以清楚地看到Cloud Spanner的扩展性很好。Cloud Spanner集群中的大量节点可以补偿由大量线程创建的大量负载。尽管延迟看起来很高,尤其是在使用2400个线程时,但可能需要使用6个较小的计算引擎实例进行重新测试才能获得更准确的数字。每个实例将运行一个YCSB测试,而不是一个具有6个并行测试的大型CE实例。因此,将更容易地区分Cloud Spanner请求延迟和Cloud Spanner与运行测试的CE实例之间的网络连接所增加的延迟。

Cloud Spanner如何处理OLAP?


分区?


将数据分为物理上和/或逻辑上独立的段(称为分区)是大多数OLAP机制固有的非常流行的概念。分区可以显着提高查询性能和数据库支持。关于分区的进一步深化将在另一篇文章中介绍,因此,让我们仅提及使用分区方案和子分区的重要性。将数据划分为多个分区,甚至进一步细分为子分区的能力,对于分析查询的性能至关重要。

Cloud Spanner本身不支持分区。它在内部将数据拆分为所谓的拆分基于主键范围。自动执行分离以平衡Cloud Spanner集群中的负载。Cloud Spanner的一个非常方便的功能是拆分父表(一个不与另一个表交替的表)的基本负载。Spanner自动确定拆分是否包含比其他拆分中数据读取频率更高的数据,并可以决定进一步的拆分。因此,请求中可以包含更多节点,这也有效地提高了吞吐量。

加载数据中?


批量数据的Cloud Spanner方法与常规下载相同。为了获得最佳性能,您需要遵循一些建议,包括:

  • 按主键对数据进行排序。
  • 将它们除以10 * 单个节的节点数
  • 创建一组并行加载数据的工作任务。

通过此数据下载,将使用所有Cloud Spanner节点。

我们使用A YCSB工作负载来生成1000万行的数据集。



*负载测试是在n1-standard-32计算引擎(32 vCPU,120 GB内存)上执行的,并且测试实例绝不是测试的瓶颈。
**不建议将1节点配置用于任何生产负载。


如上所述,Cloud Spanner会根据拆分的负载自动处理拆分,因此在多次连续重复测试之后,结果会有所改善。这里介绍的结果是我们收到的最佳结果。查看上面的数字,我们可以看到Cloud Spanner如何随着集群中节点数量的增加而扩展(很好)。如上所述,突出的数字是极低的平均延迟,与混合工作负载的结果形成对比(读取为95%,写入为5%)。

缩放?


一键式任务是增加和减少Cloud Spanner节点的数量。如果要快速加载数据,可以考虑将实例最大化(在我们的示例中,在US-EAST区域中为25个节点),然后在数据库中的所有数据之后减少适合常规加载的节点数注意2 TB /节点的限制。

即使数据库较小,我们也被提醒了这一限制。经过几次负载测试后,我们的数据库大小约为155 GB,当缩减为1个节点的实例时,出现以下错误:



我们设法将规模从25个实例减少到2个实例,但被困在两个节点上。

可以使用REST API自动增加和减少Cloud Spanner集群中的节点数量。这对于减少繁忙时间增加的系统负载特别有用。

OLAP查询性能?


最初,我们计划为此投入大量时间来评估Spanner。经过几次SELECT COUNT之后,我们立即意识到测试会很短,并且Spanner不会成为OLAP引擎。无论集群中有多少节点,简单选择10M行表中的行数都需要55至60秒。此外,任何需要更多内存来存储中间结果的请求都将失败,并出现OOM错误。

SELECT COUNT(DISTINCT(field0)) FROM usertable; — (10M distinct values)-> SpoolingHashAggregateIterator ran out of memory during new row.

可以在Todd Lipcon的文章Nosql-kudu-spanner-slides.html,幻灯片42和43中找到一些TPC-H请求的数字。这些数字与我们自己的结果一致(不幸的是)。



4.我们的发现


考虑到Cloud Spanner功能的当前状态,很难想象它是现有OLTP解决方案的简单替代,尤其是当您的需求超出需求时。构建考虑到Cloud Spanner缺陷的解决方案将需要花费大量时间。

当我们开始评估Cloud Spanner时,我们期望其Spanner的管理功能与其他Google SQL解决方案相同或至少相距不远。但是我们对完全没有备份以及对资源访问的控制非常有限感到惊讶。更不用说缺少视图,缺少本地开发环境,不支持的序列,没有DML和DDL支持的JDBC等。

那么,需要扩展事务数据库的人去哪儿了?似乎市场上没有适合所有用例的单一解决方案。有很多封闭式和开放源代码解决方案(本文中提到了其中的一些解决方案),每种解决方案都有其优点和缺点,但是没有一个提供SaaS的99.999%SLA和高度一致性。如果高SLA是您的主要目标,并且您不希望为多个云环境创建自己的解决方案,则Cloud Spanner可能是您正在寻找的解决方案。但是您必须意识到其所有局限性。

公平地说,应该指出的是Cloud Spanner并非仅在2017年春季才向公众发布,因此可以合理地预期它的某些缺点最终可能会消失(我希望),并且一旦发生,它就能改变游戏规则。毕竟,Cloud Spanner不仅仅是Google的第三方项目。 Google将其用作其他Google产品的基础。而且,当Google最近用Cloud Spanner取代了Google Cloud Storage中的Megastore时,它允许Google Cloud Storage与全球对象列表严格一致(这仍然不适用于Amazon的 S3)。

因此,仍然有希望……我们希望。

就这样。就像文章的作者一样,我们也继续希望,但是您对此有何看法?在评论中写下内容,

邀请每个人访问我们的免费网络研讨会,在该框架下,我们将详细讨论OTUS AWS for Developers课程。

All Articles