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