路由选项
从应用向 Bigtable 发送请求时,您可以使用应用配置文件来指示 Bigtable 如何处理请求。应用配置文件指定了请求的路由政策。对于使用复制功能的实例,路由政策可控制哪些集群接收请求以及故障切换的处理方式。
本文档介绍了适用于标准应用配置文件的路由政策。
当您无法使用数据提升(预览版)时,路由政策对于工作负载隔离应用场景尤为重要。您可以将其与请求优先级结合配置。
路由政策不会影响复制,但在阅读本页面内容之前,您应该先熟悉 Bigtable 复制的工作原理。您还应阅读故障切换。
单集群路由
单集群路由政策会将所有请求路由到您实例中的单个集群。如果该集群变得不可用,您必须手动故障切换到另一个集群。
这是唯一可让您启用单行事务的路由政策。
复制的实例通常会提供最终一致性。但是,如果您为工作负载配置应用配置文件,以使用单集群路由将读取和写入请求发送到同一集群,则可以在复制的实例中为工作负载实现读己所写一致性。您可以根据工作负载要求,将复制的实例上其他工作负载的流量路由到该实例中的其他集群。
多集群路由
多集群路由政策会将您发送到实例的请求路由到该实例具有的集群所在的最近区域。如果该集群变得不可用,则流量将自动故障切换到最近的可用集群。
此配置可提供最终一致性。您无法启用使用多集群路由的单行事务,因为在使用多集群路由时,单行事务可能会导致数据冲突。如需了解详情,请参阅单行事务。
如果您希望实现高可用性 (HA),请使用多集群路由。如需了解建议的实例配置和更多详情,请参阅创建高可用性 (HA)。
这两种类型的多集群路由是任何集群路由和集群组路由。
任何集群路由
任何集群路由使实例中的每个集群都可接收请求并可用于故障切换。
集群组路由
如果您要从可能的故障切换中排除实例的一个或多个集群,则可以使用集群组路由。这种形式的多集群路由允许您指定应用配置文件可以向其发送流量的部分集群。如果您要为单独的工作负载预留集群,则该路由会非常有用。
行亲和性路由
行亲和性路由会根据请求的行键,自动将单行读写请求路由到特定集群。
如果您希望多集群路由实现更高的读己所写一致性速率,并且大多数请求都是单行操作,则可以使用行亲和性路由(粘性路由)。如需启用行亲和性路由,请使用启用了 --row-affinity
标志的自定义应用配置文件。Bigtable 使用请求的行键自动确定将请求路由到哪个集群。您无法手动设置行键与集群之间的映射。
行亲和性路由只能用于单行读取或写入请求。这包括调用 ReadRows
并指定一个键、调用 MutateRow
和 MutateRows
并指定一个键,以及调用 BulkMutateRow
并指定一个键的请求。
在以下情况下,行亲和性路由无法完全实现读己所写一致性:
向实例添加集群:行亲和性路由会根据行键确定要路由到哪个集群。如果在启用行亲和性路由时向实例添加或移除新集群,行键分配可能会发生变化。为确保集群故障切换顺序保持不变,即使实例的集群列表发生变化,我们也建议您通过设置
--restrict-to
标志来使用集群组。对于集群组,如果应用配置文件正在使用实例中的某个集群,您将无法删除该集群。此外,除非将添加到实例中的任何新集群明确添加到应用配置文件的集群组,否则该集群不会开始接收请求。
故障切换:如果某个集群不可用或运行状况不佳,系统会根据故障切换顺序将发送到受影响集群的请求转到下一个集群。这种重新路由可能会影响一致性。
如需详细了解故障转移,请参阅故障转移。 如需了解如何完成故障切换,请参阅管理故障切换。
单行事务
在 Bigtable 中,行级层变更(例如读取、写入和删除请求)始终属于原子操作。这包括对单行中的多个列进行的变更,前提是它们包含在同一变更操作中。Bigtable 不支持以原子方式更新多个行的事务。
但是,Bigtable 支持某些需要在其他数据库中执行事务的写入操作。实际上,Bigtable 使用单行事务来完成这些操作。这些操作包括读取和写入操作,且所有读取和写入均以原子方式执行,但仍然只是在行级的原子操作:
- 读取-修改-写入操作,包括增量和附加。读取-修改-写入操作会读取现有值,对现有值进行增量或附加操作,并将更新后的值写入表中。
- 检查并更改 (Check-and-mutate) 操作(也称为条件更改或条件写入)。在检查并更改 (check-and-mutate) 操作中,Bigtable 会对行进行检查以了解其是否符合指定条件。如果符合条件,Bigtable 则会将新值写入该行中。
单行事务之间的冲突
Bigtable 实例中的每个集群都是主集群,它既接受读取,也接受写入。因此,需要执行单行事务的操作可能会导致复制的实例出现问题。
如果您的用例允许,您可以使用汇总来避免这些冲突。向汇总字段发送添加请求时,新值会与现有值合并。借助汇总,您可以保留累计总和或计数器。如需了解详情,请参阅在写入时汇总值。
为了说明不使用汇总时可能会出现的问题,假设您有一个用于存储票务系统数据的表。可以使用整数计数器存储已售门票数。每次出售一张门票后,您的应用都会发送读取-修改-写入操作,以将计数器递增 1。
如果您的实例有一个集群,则客户端应用可以同时出售门票,并且可增加计数器而不会丢失数据,因为请求以原子方式按照单个集群接收请求的顺序进行处理。
另一方面,如果您的实例有多个集群,并且您的应用配置文件是要允许多集群路由,则增加计数器的并发请求可能会发送到不同的集群,然后复制到该实例中的其他集群。如果您同时发送两个递增请求并路由到不同集群,则每个请求都会完成其事务,而不知道其他消息。每个集群上的计数器递增 1。当数据复制到另一个集群时,Bigtable 可能无法知道您打算递增 2。
为帮助您避免意外的结果,Bigtable 会执行以下操作:
- 要求您必须在每个应用配置文件中指定是否允许单行事务。
- 阻止您在使用多集群路由的应用配置文件中启用单行事务,因为没有可靠的方法可以同时启用这两项功能。
- 如果您在使用单集群路由并且指向不同集群的两个或多个不同应用配置文件中启用了单行事务,则会向您发出警告。如果您选择创建此类配置,则必须确保不会将有冲突的读取-修改-写入请求或检查并变更请求发送到不同的集群。