如果我先删除表并先创建表,然后再进行流传输,则Google BigQuery流有时会失败

时间:2018-08-23 23:51:25

标签: google-bigquery streaming

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

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

我已经做过好几次了,一切正常。但是最近我开始发现上述方法无效。

流完成后(未报告错误),我查询了表,有时它可以工作。有时,我的桌子空了。 (相同的脚本,相同的数据,运行多次,结果不同。有时可行,有时却不行。)

更令人费解的是,当我流式传输大量数据时,它似乎在大多数情况下都有效。但是当我流传输少量数据时,大多数情况下都会失败。

但如果我愿意

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

它始终有效。

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

所以我在Google Apps脚本中尝试过

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

它仍然给我带来同样的问题。

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

其他信息:

我再次尝试。

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

但是,如果我运行脚本,则在上一次运行之后立即运行,结果为空。数据不会流式传输到新表中。

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

但是根据该线程的回答BigQuery Stream and Delete while streaming buffer is not empty?

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

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

在这种情况下,简而言之,

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

2 个答案:

答案 0 :(得分:2)

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

摘自官方文档:

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

  

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

     

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

为避免丢失数据:用另一个名称创建一个新表。

答案 1 :(得分:0)

我在我的另一个主题中发布了有关流到BigQuery的信息。现在作为规则,如果可以的话,我将尽量避免流式传输。

  • 将数据加载到Cloud Storage
  • 然后将数据从Cloud Storage加载到BigQuery

这将解决许多与流媒体有关的问题。