BigQuery 使用流式插入 API 保证最终一致性

Posted

技术标签:

【中文标题】BigQuery 使用流式插入 API 保证最终一致性【英文标题】:BigQuery eventual consistency guarantees using streaming insert API 【发布时间】:2018-12-14 13:39:43 【问题描述】:

我想使用 BigQuery streaming insert API 将行插入 BigQuery 表。在我的用例中,这是唯一会执行的“写”操作;我永远不会通过任何其他方式插入行,也永远不会更新或删除行。

读过Life of a BigQuery streaming insert,我的理解是,即使insertAll 请求被确认后,后续的读操作也可能无法“看到”它成功插入的所有行,直到它们被传输从流缓冲区到托管存储。

假设我的理解是正确的(如果不是,请告诉我!):

    有什么方法可以判断给定insertAll 请求插入的所有行现在何时已提交到托管存储? 即使在一行被提交到托管存储之后,后续的读取操作是否保证要么看到它们,要么失败?

我为什么要问这些问题?我的表模式将包含一个“键”列,这是一个严格单调递增的标识符。所有读取操作都将被限制在其键不超过某个指定值的行上。我需要保证这种形式的读取操作将始终返回相同的结果,假设指定的键对应于已经插入的行。显然,这样的查询不可能返回随后插入的行(因为它们的键会大于指定的键)。但是,如果有任何行已经被插入但仍在流缓冲区中,则查询可能不会返回它们,但稍后会执行完全相同的查询(在提交行之后)会返回它们。在我的用例中,这将是一场灾难。

【问题讨论】:

【参考方案1】:

有两种状态。

在流缓冲区中并提交。 您可以读取流缓冲区中的行,这种语法在非分区表和分区表之间有所不同,您可以找到如何获取这些行的示例。

如果 insertId 被多于一行使用,则仅保留一行。

提交状态保证您可以阅读。

【讨论】:

谢谢!我想你已经回答了我问题的第二部分——即一旦提交了一行,后续(成功的)读取操作确实可以保证看到它。但是,除非有某种方法让我能够检测到已提交的行,否则这对我没有多大帮助(如果实际上无法使用 BigQuery 执行此操作,那么这当然是一个完全有效的答案)。 (我在问题中添加了更多上下文,希望能说明为什么我需要能够判断行何时提交。) 您想要的很容易实现,找到并保留流缓冲区中最旧的密钥作为参考。这意味着所有先前的密钥都已提交并发出一个将其用作阈值的查询 这是有道理的,但我不清楚如何判断哪些行仍在流缓冲区中?有没有办法使用 API 调用来确定这一点? Eiter 你通过 API 检查streamingBuffer.oldestEntryTime 字段可以用来识别流缓冲区中记录的年龄。或者写查询,非分区和分区列有不同的语法:***.com/questions/41864257/…

以上是关于BigQuery 使用流式插入 API 保证最终一致性的主要内容,如果未能解决你的问题,请参考以下文章

流式 BigQuery API

BigQuery,Python 批量插入 bigquery 以进行流式传输服务(“告诉”错误)

在 Golang 中使用 BigQuery Write API

BigQuery 流式插入使用模板表数据可用性问题

Bigquery 流式处理 API 超时错误

使用 AVRO 格式的 BigQuery 流式插入