复制

本页面介绍了 Spanner 中的数据复制方式、Spanner 副本的不同类型及其在读写中的角色,以及复制的优势。

概览

Spanner 会在字节级别自动进行复制。如 Spanner 读写的生命周期中所述,它在构建它的底层文件系统中利用了此功能。Spanner 将数据库变更写入此文件系统中的文件,而文件系统负责在机器或磁盘发生故障时复制和恢复文件。

尽管构建 Spanner 的底层分布式文件系统已经提供字节级复制,但 Spanner 也会复制数据以提供数据可用性和地理局部性的额外优势。概括来讲,Spanner 中的所有数据都会整理到行中。Spanner 会创建这些行的多个副本(即“副本”),然后将这些副本存储在不同的地理区域中。Spanner 使用基于 Paxos 的同步复制方案,在该方案中,投票副本在提交写入之前对每个写入请求进行投票。借助全局同步复制的这一属性,您可以从任何 Spanner 读写或只读副本中读取最新数据。

Spanner 会为每个数据库分块创建副本。分屏包含一系列连续的行,这些行按主键排序。分块中的所有数据以物理方式一起存储在副本中,Spanner 从独立故障区域传送每个副本。如需了解详情,请参阅架构简介

系统使用 Paxos 存储和复制分片集。在每个 Paxos 副本集中,会有一个副本被选定为主要副本。主要副本负责处理写入,而任何读写或只读副本都可以在不与主要副本通信的情况下处理读取请求(但如果请求强读取,系统通常会查询主要副本,以确保只读副本已收到所有最近的变更)。

Spanner 复制的优势

Spanner 复制的优势包括:

  • 数据可用性:对于希望读取数据的客户端而言,拥有更多数据副本可以使数据更具可用性。此外,即使某些副本不可用,Spanner 仍然可以处理写入操作,因为在提交写入时只需要大多数投票副本。

  • 地理局部性:能够使用 Spanner 将数据存放到不同的区域和大洲,这意味着数据可以在地理位置上更接近需要数据的用户和服务,因此访问速度也更快。

  • 单一数据库体验:Spanner 可以通过同步复制和全球强一致性来提供单一数据库体验。

  • 更轻松的应用开发:由于 Spanner 符合 ACID 并提供全局强一致性,因此使用 Spanner 的开发者无需在应用中添加额外的逻辑来处理最终一致性,因此应用开发和后续维护变得更加轻松快捷。

副本类型

Spanner 有三种类型的副本:读写副本只读副本见证者副本。构成基本实例配置的区域和复制拓扑是固定的。基本区域实例配置仅使用读写副本。基本双区域实例配置使用读写副本和见证者副本,而基本多区域实例配置使用所有三种副本类型的组合。您可以创建自定义实例配置,并为单区域和多区域实例配置添加其他只读副本

下表汇总了 Spanner 副本的类型及其属性:

副本类型 是否可以投票 是否可以成为主要副本 是否支持读取 可以手动配置副本
读写
只读 *
见证者

*如需了解详情,请参阅如何使用自定义实例配置创建实例

读写副本

读写副本支持读取和写入。此类副本具有以下特性:

  • 维护数据的完整副本。
  • 支持读取。
  • 可针对是否提交写入进行投票。
  • 可参与主要副本的选择。
  • 有资格成为主要副本。
  • 是单区域实例中唯一使用的类型。

只读副本

只读副本仅支持读取,不支持写入。这些副本不会为主要副本或提交写入投票,因此您可以通过它们来扩展读取容量,而无需增加写入所需的最小票数。只读副本:

  • 维护从读写副本复制的数据的完整副本。
  • 支持读取。
  • 不参与针对提交写入的投票。因此,只读副本的位置对写入延迟时间没有任何影响。
  • 如果只读副本是距离您的应用最近的副本,则只读副本通常可以处理过时读取,而无需往返默认主要区域(假设过时至少 15 秒)。在多区域实例配置中,您还可以使用定向读取将只读事务和单次读取路由到特定副本类型或区域。如需了解详情,请参阅定向读取

    强读可能需要往返于主副本。往返仅用于协商时间戳,而不是传送来自主要副本的实际数据。时间戳协商是在主要副本处的一项 CPU 效率操作,通常数据已经在传输中。此通信由系统自动处理。

    如需详细了解过时读取和强读取,请参阅读取中部分。

  • 没有资格成为主要副本。

您可以创建自定义单区域或多区域实例配置,并添加可选的只读副本以扩缩读取并支持低延迟过时读取。您可以将可选区域下列出的位置添加为可选的只读副本。如果您没有看到所选的只读副本位置,可以请求新的可选只读副本区域。请注意,您无法更改固定的基本实例配置的复制拓扑。

所有可选的只读副本均需支付计算容量和存储费用。此外,向自定义实例配置添加只读副本不会更改实例配置的 Spanner SLA。如果您选择将只读副本添加到与主要区域位于不同大洲的大洲,我们建议您至少添加两个只读副本。这有助于在其中一个只读副本不可用时保持低读取延迟。

添加只读副本时,主副本会经历更多的复制负载,这可能会影响性能。最佳做法是,先在自定义实例配置中的非生产实例中测试性能工作负载。如需了解区域间延迟时间中位数,请参阅区域间延迟时间和吞吐量基准信息中心。例如,如果您使用 eur6 多区域基本配置创建自定义实例配置并在 us-east1 中创建一个可选的只读副本,由于到 europe-west4 的主要区域的往返时间,us-east1 中客户端的预期强读取延迟时间约为 100 毫秒。具有充分过时的过时读取不会引发往返,因此速度要快得多。您还可以使用延迟时间(按事务类型)指标,查看读写和只读类型事务的延迟时间数据。

有关说明,请参阅创建自定义实例配置

见证者副本

见证者副本不支持读取,但参与针对提交写入的投票。见证者副本使您可以更轻松地达成最小写票数,而无需读写副本在存储数据的完整副本及处理读取时所需的存储空间和计算资源。见证者副本:

  • 仅用于多区域实例。
  • 不要保留数据的完整副本。
  • 不提供读取操作。
  • 针对是否提交写入进行投票。
  • 可参与主要副本的选择,但没有资格成为主要副本。

副本在写入和读取中的作用

本部分介绍副本在 Spanner 写入和读取中的作用,这有助于了解 Spanner 在多区域配置中使用见证者副本的原因。

在写入中

始终先在主副本处理客户端写入请求,即使存在更靠近客户端的非主副本,或者主副本在地理位置上距离客户端较远时也是如此。如果您使用多区域实例配置,并且您的客户端应用位于非主要区域,则 Spanner 会使用主要区域感知型路由来动态地路由读写事务,以缩短数据库的延迟时间。如需了解详情,请参阅领导者感知路由

主要副本记录传入的写入,并将其并行转发给有资格对该写入进行投票的其他副本。每个有资格投票的副本都会完成其写入,然后在响应该主要副本时对是否应该提交该写入进行投票。当大多数投票副本同意提交该写入(或达到“最小写票数”)时,写入会被提交。在后台,所有其余(非见证者)副本会记录该写入。如果读写副本或只读副本在记录写入时滞后了,可以从另一个副本请求丢失的数据,以获得完整的最新数据副本。

在读取中

客户端读取请求可能会在主要副本中执行,或需要与主要副本进行通信,具体取决于读取请求的并发模式。

  • 作为读写事务一部分的读取操作由主要副本处理,因为主要副本保有强制执行可序列化所需的锁。

  • 单次读取方法(即在事务上下文之外进行读取)和只读事务中的读取可能需要与主要副本进行通信,具体取决于读取的并发模式。(如需详细了解这些并发模式,请参阅读取类型。)

    • 强读取请求可以转到任何读写或只读副本。如果此类请求转到非主要副本,则该副本必须与主要副本进行通信才能执行读取操作。

    • 过时读取请求会转到最近的可用只读副本或读写副本,并赶上请求的时间戳。如果主要副本是距离发出读取请求的客户端最近的副本,则此副本可以是主副本。