复制

本页面介绍了 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 会使用领导者感知型路由动态路由读写事务,以缩短数据库的延迟时间。如需了解详情,请参阅领导者感知型路由

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

在读取中

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

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

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

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

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