如果我在流式传输之前先删除表并创建表,Google BigQuery Streaming 有时会失败

sea*_*ain 9 streaming google-bigquery

我正在将数据流式传输到 BigQuery 表中。

  • 删除旧表
  • 创建一个具有相同名称和相同架构的新表
  • 将数据流式传输到新表中

我以前做过很多次,它工作得很好。但最近我开始发现上述方法不起作用。

流式传输完成后(未报告错误),我查询表,有时它会起作用。有时,我的桌子是空的。(相同的脚本,相同的数据,多次运行,结果不同。有时有效,有时无效。)

更神秘的是,当我流式传输大量数据时,它似乎在大多数情况下都有效。但是当我流式传输少量数据时,它大部分时间都失败了。

但如果我只是这样做

  • 创建一个新表
  • 将数据流式传输到新表中

它总是有效。

我在 Google Apps Scrip 和 PHP Google Cloud Client Library for BigQuery 中都尝试了这个。我有同样的问题。

所以我在 Google Apps Script 中尝试了这个

  • 删除旧表
  • 休眠 10 秒,因此应该完成删除工作
  • 创建一个具有相同名称和相同架构的新表
  • 睡眠 10 秒,所以创建工作应该完成
  • 将数据流式传输到新表中

它仍然给我同样的问题。

但是没有报告或记录错误。

附加信息:

我又试了一次。

如果我等到流缓冲区为空,然后运行脚本。结果总是正确的。新数据成功流入新表。

但是,如果我在上次运行之后立即运行该脚本,则结果为空。数据不会流入新表。

因此,当流缓冲区不为空时,当我“删除旧表并创建新表”时,似乎会发生错误。

但是根据this thread的回答,BigQuery Stream and Delete while streaming buffer is not empty?,

旧表和新表(即使它们具有相同的名称和相同的架构),它们具有两个不同的“对象ID”。它们实际上是两个不同的表。删除旧表后,流缓冲区中的旧记录也会被删除。流缓冲区是否为空,它应该不会影响我接下来的步骤,创建一个新表并将新数据流式传输到新表。

另一方面,如果我尝试“截断旧表”,而不是“删除旧表并创建新表”,而流缓冲区中可能仍有数据,则“DML 语句无法修改仍在流缓冲区中的数据” ,所以“截断旧表”会失败。

简单来说,在这个用例中,

  • 我无法截断旧表,因为 Steam 缓冲区可能不为空。
  • 我应该“删除旧表并创建新表,然后将数据流式传输到新表”。但这似乎是我当前问题的根源,我的新数据无法流式传输到新表(即使新表具有新的对象ID,也不应该受到我只是删除旧表这一事实的影响)

Fel*_*ffa 5

避免在流式传输时截断和重新创建表。

来自官方文档:

https://cloud.google.com/bigquery/troubleshooting-errors#streaming

表创建/删除 - 流式传输到不存在的表将返回 notFound 响应的变体。创建响应表可能不会立即被后续流式插入识别。类似地,删除和/或重新创建表可能会创建一段时间,其中流式插入有效地传递到旧表并且不会出现在新创建的表中。

表截断 - 截断表的数据(例如,通过使用 WRITE_TRUNCATE 的 writeDisposition 的查询作业)可能会类似地导致一致性期间的后续插入被删除。

为避免丢失数据: 创建一个具有不同名称的新表。

  • 使用不同的名称创建新表是不合理的。我们使用这些表格进行报告。如果我们不断更改表的名称,我们到底应该如何保持数据最新呢?对于这样的问题,这是一个糟糕的解决方案。即使您不使用它进行报告,如果您不断更改表名称,您将如何保持数据完整性? (2认同)