写入

本页面列出了可以发送到 Bigtable 的写入请求的类型,并介绍了何时应该使用以及何时不应使用这些请求。相关信息 有关在写入时聚合单元格中的数据,请参阅写入时聚合值 时间

借助 Bigtable Data API 和客户端库,您可以 以编程方式将数据写入表中Bigtable 会针对每次写入发回响应或确认。

每个客户端库都具备发送以下类型的写入请求的功能:

  • 简单写入
  • 增量和附加
  • 条件写入
  • 批量写入

Bigtable 客户端库具备适用于简单写入和批量写入的内置智能重试功能,这意味着其可以无缝处理暂时无法使用的情况。例如,如果您的应用尝试写入数据却遇到临时中断或网络问题,它会自动重试,直至提交写入或达到请求时限。这种弹性同时支持采用单集群路由或多集群路由的单集群和复制的实例。

对于批量写入和流式写入操作,您可以使用 Bigtable Beam 连接器。如需了解详情,请参阅批量写入

如需了解适用于写入请求的限制,请参阅配额和限制

如需查看本页所述写入请求的 Cloud Bigtable 客户端库示例,请参阅写入示例

写入的类型和适用情形

所有写入请求都包含以下基本组成部分:

  • 要写入的表的名称。
  • 向 Bigtable 说明如何进行流量路由的应用配置文件 ID。
  • 一项或多项变更。变更包含以下元素:
    • 列族名称
    • 列限定符
    • 时间戳
    • 要写入表的值

变更的时间戳以当前日期和时间作为默认值,时间是从 Unix 纪元(世界协调时间 [UTC] 1970 年 1 月 1 日 00:00:00)起经过的时间。

您发送到 Bigtable 的时间戳必须是微秒值,长度不超过 毫秒级精度。精确率为微秒的时间戳,例如 “3023483279876543”已被拒绝。在此示例中,可接受的时间戳值为 3023483279876000

单个写入请求中的所有变更都具有相同的时间戳,除非您将其覆盖。您可以将写入请求中所有变更的时间戳设置为彼此相同或不同。

简单写入

您可以通过 MutateRow 请求向 Bigtable 写入一行数据 包括表格名称、应该使用的应用配置文件的 ID、 行键以及该行最多 100,000 项变更。单行写入为原子化写入。在对单行进行多项变更时,请使用这种类型的写入。

如需查看演示如何发送简单写入请求的代码示例,请参阅执行简单写入

何时不应使用简单写入

在以下使用场景中,简单写入不是写入数据的最佳途径:

  • 写入一批具有连续行键的数据。在这种情况下,您应该使用批量写入而非连续的简单写入,因为前者只需单次后端调用即可应用连续批处理。

  • 您需要高吞吐量(每秒行数或每秒字节数),不需要低延迟。在这种情况下,批量写入速度更快。

增量和附加

如需增加或递增某个值,最好使用汇总,因为这样您可以在写入时更新值。汇总不支持 附加操作。如需了解详情,请参阅 写入时的汇总值

如果您想将数据附加到现有值,或者需要递增 而不能使用汇总方法,则可以发送 ReadModifyWriteRow 请求。该请求包括表名称、应该使用的应用配置文件的 ID、一个行键以及一组要在写入数据时使用的规则。每个规则都包含列族名称、列限定符 以及附加值或增量值。

规则按顺序应用。例如,如果您的请求包含将列的值增加 2 的请求,并且同一请求中的下一个规则将相同列增加 1,那么在这一单次原子化写入中该列增加 3。后面的规则不会覆盖前面的规则。

仅当值采用 64 位大端序有符号整数进行编码时,才可以对该值执行增量操作。如果对空值或不存在的值应用增量,Bigtable 会将该值视为零。ReadModifyWriteRow 请求是原子化请求。如果此类请求由于任何原因失败,将不会重试。

如需查看演示如何在单元中附加值的代码示例,请参阅递增现有值

不应使用 ReadModifyWriteRow 的情况

请勿在以下情况下发送 ReadModifyWriteRow 请求:

  • 您可以使用汇总来处理您的用例。

  • 使用具有多集群路由的应用配置文件。

  • 使用多个单集群应用配置文件并发送写入请求,该请求可能与写入实例中其他集群内的同一行和列的数据冲突。采用单集群路由时,写入请求会发送到单个集群,然后进行复制。

  • 您依赖客户端库提供的智能重试功能。 增量和附加操作无法重试。

  • 写入大量数据并需要快速完成写入操作。与简单写入请求相比,读取然后修改行的请求速度较慢。因此,这类写入往往不是规模较大时的最佳方法。

    例如,如果要计数的内容数以百万计(例如网页浏览量),则应使用汇总在写入时更新计数。您还可以将每次查看记录为简单写入(而非递增值),然后使用 Dataflow 作业汇总数据。

条件写入

如果要检查行是否符合某条件,然后根据检查结果向该行中写入数据,请提交 CheckAndMutateRow 请求。 这种类型的请求包括行键和行过滤条件。行过滤条件是一组用于检查现有数据值的规则。只有当过滤器检查的特定条件得到满足之后,系统才会将变更提交到行中的特定列。这个先检查后写入的过程作为单个原子化操作完成。

过滤请求必须包含以下一种或两种类型的变更:

  • 真变更,或过滤返回值时应用的变更。
  • 假变更,即过滤未产生任何结果时应用的变更。

在一次写入中,您最多可以提供 100,000 个每种类型的变更(真和假),并且必须至少发送一个。所有变更都完成后,Bigtable 会发送响应。

如需查看演示如何发送条件写入的代码示例,请参阅有条件地写入值

何时不应使用条件写入

以下使用场景下不能使用条件写入:

  • 使用具有多集群路由的应用配置文件。

  • 使用多个单集群应用配置文件并发送写入请求,该请求可能与写入实例中其他集群内的同一行和列的数据冲突。采用单集群路由时,写入请求会发送到单个集群,然后进行复制。

  • 写入大量数据并需要快速完成写入操作。与 ReadModifyWriteRow 类似,条件写入请求需要先读取行,然后才能修改它们,因此 CheckAndModifyRow 请求的速度比简单写入请求慢。因此,这种类型的写入通常不是最佳选择, 方法。

批量写入

您可以使用 MutateRows 请求,通过单个调用写入多个行。MutateRows 请求包含一组多达 10 万个的条目,其中的每个条目均以原子化方式应用。每个条目包含一个行键以及至少一个要应用于该行的变更。一个批量写入请求可包含多达 100,000 个变更,这些变更分布于所有条目之间。例如,批量写入可能包括以下任何排列:

  • 100,000 个条目,每个条目中包含 1 项变更。
  • 包含 100,000 项变更的 1 个条目。
  • 1000 个条目,每个条目中包含 100 项变更。

MutateRows 请求中的每个条目都是原子化条目,但整个请求不是。如有必要,Bigtable 会重试该批次中 则不成功,直到所有写入都成功完成或请求时限已到 。然后,它会返回一个标识批次中各写入操作以及写入操作是否成功的响应。

如需查看演示如何发送批量写入的代码示例,请参阅执行批量写入

何时不应使用批量写入

  • 将批量数据写入彼此不靠近的行。Bigtable 按行键的字典顺序存储数据,这是字母顺序的二进制版本。因此,当请求中的行键彼此不相似时,Bigtable 会按顺序对其进行处理,而不会采取并行处理方式。吞吐量高,但延迟也高。为了避免这种高延迟,当行键类似并且 Bigtable 要写入彼此靠近的行时,请使用 MutateRows。针对彼此不靠近的行,请使用 MutateRow 或简单写入。

  • 请求对同一行进行多项变更。在这种情况下,如果在单个简单写入请求中执行所有变更,则效果更佳。这是因为在简单写入中,所有更改都通过单个原子化操作提交,但系统会强制批量写入对同一行的变更进行序列化,从而导致延迟。

批量写入流控制

如果您使用以下任一方法发送批量写入,则可以在代码中启用批量写入流控制

为 Dataflow 作业启用批量写入流控制后,Bigtable 会自动执行以下操作:

  • 限制流量速率以避免 Bigtable 集群过载
  • 确保集群负载足以触发 Bigtable 自动扩缩(如果已启用),从而在需要时自动向集群添加更多节点

这些组合操作可防止集群过载和作业失败,并且您无需 需要在运行批量写入的情况下手动扩缩集群。 启用流控制后,集群扩缩会在 Dataflow 作业期间(而不是之前)发生,因此作业完成所需的时间可能比手动扩缩集群更长。

您必须使用针对单集群路由配置的应用配置文件。为目标集群启用 Bigtable 自动扩缩不是必需的,但自动扩缩可让您充分利用批量写入流控制。您可以像使用任何其他作业一样使用 Dataflow 自动扩缩功能。

如需详细了解 Bigtable 自动扩缩,请参阅自动扩缩。了解应用配置文件路由 政策,请参阅应用配置文件概览

如需查看演示如何使用 Bigtable HBase Beam 连接器启用批量写入流控制的代码示例,请参阅向 Bigtable 写入数据

将数据写入已获授权的视图

如需将数据写入已获授权的视图,您必须使用以下任一方法:

  • gcloud CLI
  • Java 版 Bigtable 客户端

其他 Bigtable 客户端库尚不支持 授予的查看权限。

向授权视图写入数据时,您需要提供授权视图 ID 以及表 ID。

对授权视图的所有写入都会直接应用于 表格。

获授权视图定义限制

在已获授权的视图中,您可以写入数据的行或列受授权视图定义的限制。也就是说,您只能 写入满足为 授权视图。

例如,如果已获授权的视图由行键前缀 examplepetstore1 定义,则您无法使用行键 examplepetstore2 写入数据;行键值的开头必须包含整个字符串 examplepetstore1

同样,如果授权视图由列限定符前缀 order-phone 定义,则您可以使用列限定符 order-phone123 写入数据,但不能使用列限定符 order-tablet

您的写入请求也不能引用授权视图之外的数据,例如在有条件写入请求中检查值时。

对于任何将数据写入或引用 已获授权的视图时,系统会返回 PERMISSION_DENIED 错误消息。

复制

当复制的实例的一个集群收到写入时,该写入会立即复制到该实例中的其他集群。

原子性

您发送到复制的实例的每个 MutateRows 请求都会在请求路由到的集群上作为单个原子操作提交。当写入被复制到实例中的其他集群时,每一个这些集群也会将写入作为原子操作接收。集群不会收到部分变更;变更要么成功,要么对于它修改的所有单元自动失败。

一致性

您写入的数据可供读取所需的时间取决于 包括实例中的集群数量和 应用配置文件使用的路由类型

使用单集群实例时,可以立即读取数据, 实例有多个集群,这意味着它使用了复制功能, Bigtable 具有最终一致性。通过将请求路由到同一集群,您可以实现读己所写一致性

发送写入请求后,您可以创建并使用一致性令牌,并在 StandardReadRemoteWrites 模式下调用 CheckConsistency。令牌 检查复制一致性。一般来说,创建一个一致性令牌 发送大量数据 一小时。然后,您可以将令牌交给其他进程使用,例如发出读取请求的模块,此模块使用该令牌进行检查,以确保所有数据在其尝试读取前都已被复制。

如果您在创建令牌后立即使用该令牌,首次使用时可能需要几分钟时间来检查一致性。此延迟是因为各集群会检查每个其他集群,以确保不再有数据传入。初次使用之后,或者如果您等待几分钟再首次使用令牌,则每次使用令牌时都会立即成功。

冲突解决

Bigtable 表中的每个单元格值都通过四元组(行键、列族、列限定符、时间戳)进行唯一标识。如需详细了解这些标识符,请参阅 Bigtable 存储模型。在极少数情况下,当将两个具有完全相同的四元组的写入发送到两个不同的集群时,Bigtable 会基于服务器端时间使用内部“最后写入内容生效”算法自动解决冲突。Bigtable“最后写入内容生效”实现具有确定性,当副本完成同步后,所有集群都具有四元组的相同值。

后续步骤