路由选项

从应用向 Bigtable 发送请求时,您可以使用应用 配置文件来指示 Bigtable 如何 处理请求。应用配置文件指定了请求的 路由政策 。对于使用复制功能的实例,路由政策可控制哪些集群接收请求以及故障切换的处理方式。

本文档介绍了可用于标准应用配置文件的路由政策。

路由政策对于工作负载 隔离应用场景尤为重要,因为在这些场景中 您无法使用 Data Boost。您可以将其与请求 优先级结合使用。

路由政策不会影响复制,但在阅读本页面内容之前,您应该先熟悉 Bigtable 复制 的工作原理。您还应阅读 故障切换

单集群路由

单集群路由政策会将所有请求路由到您实例中的一个集群。如果该集群变得不可用,您必须手动故障切换到另一个集群。Data Boost 和内存中层 (预览版) 应用 配置文件使用单集群路由。

这是唯一可让您启用 单行 事务的路由政策。

复制的实例通常会提供最终 一致性。但是,如果您为工作负载配置应用配置文件,以使用单集群路由将读取和写入请求发送到同一集群,则可以在复制的实例中为该 工作负载实现读己所写 一致性。您可以根据工作负载要求,将复制的实例上其他工作负载的流量路由到该实例中的其他集群。

多集群路由

多集群路由政策会将您发送到实例的请求路由到该实例具有的集群所在的最近区域。如果该集群变得不可用,则流量将自动故障切换到最近的可用集群。

此配置可提供最终一致性。您无法启用使用多集群路由的单行 事务,因为在使用多集群路由时,单行事务可能会 导致 数据 冲突 。如需了解详情,请参阅单行 事务

如果您需要高可用性 (HA),请使用多集群路由。如需了解推荐的 实例配置和更多详细信息,请参阅创建高可用性 (HA)

使用多集群路由时,您可以将请求路由到实例中的 任何集群 或路由到您定义的 集群组 。如果您的工作负载主要由单行操作组成,并且您希望实现更高的读己所写一致性,则可以启用 行亲和性路由

如需详细了解与 SQL 相关的路由注意事项,请参阅本文档的 “使用 SQL 进行路由”部分。

任何集群路由

任何集群路由使实例中的每个集群都可接收请求并可用于故障切换。

集群组路由

如果您要从可能的故障切换中排除实例的一个或多个集群,则可以使用集群组路由。这种形式的多集群路由允许您指定应用配置文件可以向其发送流量的部分集群。如果您要为单独的工作负载预留集群,则该路由会非常有用。

行亲和性路由

行亲和性路由会根据请求的行键,自动将单行读写请求路由到特定集群。

您可以使用 gcloud CLI、 Google Cloud 控制台、适用于 Java 的 Bigtable 客户端库或 Terraform 启用行亲和性路由。如需了解详情,请参阅 创建应用配置文件

如果您希望多集群路由实现更高的读己所写一致性,并且大多数请求都是单行操作,则可以使用行亲和性路由(粘性路由)。Bigtable 使用请求的行键自动确定要将请求路由到的集群。您无法手动设置行键与集群之间的映射。

行亲和性路由只能用于单行读取或写入请求。 这包括使用一个键指定的 ReadRowsMutateRow、 和使用一个键指定的 MutateRows 以及使用一个键 指定的 BulkMutateRow 的请求。

在以下情况下,行亲和性路由无法完全实现读己所写一致性:

  • 向实例添加集群:行亲和性路由根据行键确定要路由到的 集群。如果在启用行亲和性路由时向实例添加或从实例中移除新集群,则行键分配可能会发生变化。为了确保集群故障切换顺序在实例的集群列表发生变化后保持不变,我们建议您通过设置 --restrict-to 标志来使用集群组。

    使用集群组时,您无法删除应用配置文件正在使用的实例中的集群。此外,除非明确添加到应用配置文件的集群组中,否则添加到实例的任何新集群都不会开始接收请求。

  • 故障切换:如果集群不可用或运行状况不佳,系统会根据故障切换 顺序将发送到 受影响集群的请求定向到下一个集群。这种重新路由可能会影响一致性。

如需详细了解故障转移,请参阅 故障转移。 如需了解如何完成故障切换,请参阅管理 故障切换

使用 SQL 进行路由

使用 SQL 查询 Bigtable 时,请求的路由方式有一些特殊注意事项。SQL 查询的路由行为与其他类型的 Bigtable 请求不同。 行亲和性路由会根据行键自动将单行读取和写入 定向到特定集群。Bigtable 不支持 SQL 查询的此路由政策。此限制意味着,即使查询旨在读取单行,您也不能将行亲和性路由与 ExecuteQuery 方法搭配使用。如果您使用启用了 --row-affinity 标志的应用配置文件发送 ExecuteQuery 请求,则请求会成功,但不会强制执行行亲和性。

单行事务

在 Bigtable 中,行级层变更(例如读取、写入和删除请求)始终属于原子操作。这包括对单行中的多个列进行的变更,前提是它们包含在同一变更操作中。Bigtable 不支持以原子方式更新多个行的事务。

但是,Bigtable 支持某些需要在其他数据库中执行事务的写入操作。实际上,Bigtable 使用单行事务来完成这些操作。这些操作包括读取和写入操作,且所有读取和写入均以原子方式执行,但仍然只是在行级的原子操作:

  • 读取-修改-写入操作,包括增量和附加。读取-修改-写入操作会读取现有值,对现有值进行增量或附加操作,并将更新后的值写入表中。
  • 检查并更改 (Check-and-mutate) 操作(也称为条件更改或条件写入)。在检查并更改 (check-and-mutate) 操作中,Bigtable 会对行进行检查以了解其是否符合指定条件。如果符合条件,Bigtable 则会将新值写入该行中。

单行事务之间的冲突

Bigtable 实例中的每个集群都是主集群,它既接受读取,也接受写入。因此,需要执行单行事务的操作可能会导致复制的实例出现问题。

如果您的使用场景允许,您可以使用聚合来避免这些冲突。 当您向聚合字段发送添加请求时,新值会与现有值合并。借助聚合,您可以保留运行总和或计数器。如需了解详情,请参阅写入时的聚合值

为了说明不使用聚合时可能出现的问题,假设您有一个用于存储票务系统数据的表。您使用整数计数器来存储已售出的门票数量。每次售出票时,您的应用都会发送 读取-修改-写入操作,将计数器递增 1。

如果您的实例有一个集群,则客户端应用可以同时出售门票,并且可增加计数器而不会丢失数据,因为请求以原子方式按照单个集群接收请求的顺序进行处理。

另一方面,如果您的实例有多个集群,并且您的应用配置文件是要允许多集群路由,则增加计数器的并发请求可能会发送到不同的集群,然后复制到该实例中的其他集群。如果您同时发送两个递增请求并路由到不同集群,则每个请求都会完成其事务,而不知道其他消息。每个集群上的计数器递增 1。当数据复制到另一个集群时,Bigtable 可能无法知道您打算递增 2。

为帮助您避免意外的结果,Bigtable 会执行以下操作:

  • 要求您必须在每个应用配置文件中指定是否允许单行事务。
  • 阻止您在使用多集群路由的应用配置文件中启用单行事务,因为没有可靠的方法可以同时启用这两项功能。
  • 如果您在使用单集群路由并且指向不同集群的两个或多个不同应用配置文件中启用了单行事务,则会向您发出警告。如果您选择创建此类配置,则必须确保不会将有冲突的读取-修改-写入请求或检查并变更请求发送到不同的集群。

后续步骤