【问题标题】:Apache Beam Java 2.26.0: BigQueryIO 'No rows present in the request'Apache Beam Java 2.26.0:BigQueryIO '请求中没有行'
【发布时间】:2021-03-09 15:43:01
【问题描述】:

自从 Beam 2.26.0 更新以来,我们在 Java SDK 流数据管道中遇到了错误。我们已经对该问题进行了相当长的一段时间的调查,但无法找到根本原因。降级到 2.25.0 时,管道按预期工作。

我们的管道负责提取,即从 Pub/Sub 消耗并提取到 BigQuery。具体来说,我们使用PubSubIO 源和BigQueryIO 接收器(流模式)。在运行管道时,我们遇到以下错误:

{
  "code" : 400,
  "errors" : [ {
    "domain" : "global",
    "message" : "No rows present in the request.",
    "reason" : "invalid"
  } ],
  "message" : "No rows present in the request.",
  "status" : "INVALID_ARGUMENT"
}

我们最初的猜测是管道的逻辑存在某种错误,导致BigQueryIO 接收器失败。经过调查,我们得出的结论是,PCollection 输入接收器确实包含正确的数据。

今天早些时候,我查看了changelog 并注意到BigQueryIO 接收器收到了许多更新。我特别担心以下变化:

  1. BigQuery 的 DATETIME 类型现在映射到 Beam 逻辑类型 org.apache.beam.sdk.schemas.logicaltypes.SqlTypes.DATETIME
  2. Java BigQuery 流式插入现在默认启用超时。传递 --HTTPWriteTimeout=0 以恢复旧行为

关于第一次更新,我确保在生成的TableRow 对象中禁用所有DATETIME。在这种特定情况下,错误仍然存​​在。

对于第二个更改,我不确定如何将 --HTTPWriteTimeout=0 标志传递给管道。如何最好地做到这一点?

关于此问题的根本原因还有其他建议吗?

提前致谢!

【问题讨论】:

标签: google-bigquery google-cloud-dataflow apache-beam


【解决方案1】:

我们终于能够解决这个问题,并请放心,这是一段艰难的旅程。我们基本上调试了整个 BigQueryIO 连接器,得出以下结论:

  1. 转发到 BigQuery 的 TableRow 对象用于包含枚举值。由于这些不可序列化,因此会将空负载转发到 BigQuery。在我看来,这个错误应该更加明确(为什么突然改变了?)。

    • 通过向每个枚举条目 (com.google.api.client.util.Value) 添加 @value 注释解决了该问题。
  2. 同样的TableRow 对象还包含byte[] 类型的值。此值被注入到具有 bytes 类型的 BigQuery 列中。虽然这在之前没有明确计算 base64 的情况下工作,但它现在产生了错误。

    • 通过自己计算 base64 解决了该问题(此设置也在下面的 post 中讨论)。

【讨论】:

  • 是否对 Beam 进行了更改以使其更易于调试,或者可能完全不需要解决方法?
  • 您好罗伯特,感谢您的回复。让这个特别难以调试的事情是,我们没有收到关于 TableRow 不可序列化的错误。我觉得这个错误应该引发用户可见的异常。我不确定这是 Beam 的一部分还是执行器的实现细节。
【解决方案2】:

--HTTPWriteTimeoutpipeline option。您可以像设置跑步者等一样设置它(通常在命令行上)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-02-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多