Apache Beam Java 2.26.0:BigQueryIO 'No rows present in the request'
Apache Beam Java 2.26.0: BigQueryIO 'No rows present in the request'
自从 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
接收器收到了大量更新。我特别担心以下变化:
- BigQuery 的 DATETIME 类型现在映射到 Beam 逻辑类型 org.apache.beam.sdk.schemas.logicaltypes.SqlTypes.DATETIME
- Java BigQuery 流式插入现在默认启用超时。传递
--HTTPWriteTimeout=0
以恢复旧行为
关于第一次更新,我确保在生成的 TableRow
对象中禁用所有 DATETIME
。在这种特定情况下,错误仍然存在。
对于第二个更改,我不确定如何将 --HTTPWriteTimeout=0
标志传递给管道。如何最好地实现这一目标?
关于此问题的根本原因还有其他建议吗?
提前致谢!
--HTTPWriteTimeout
是一个 pipeline option。您可以像设置跑步者等一样设置它(通常在命令行上)。
我们终于能够解决这个问题,请放心,这是一段非常愉快的旅程。我们基本上调试了整个 BigQueryIO 连接器并得出以下结论:
转发到 BigQuery 的 TableRow
个对象用于包含枚举值。由于这些不可序列化,空负载被转发到 BigQuery。在我看来,这个错误应该更加明确(为什么突然改变了这个?)。
- 通过向每个枚举条目 (
com.google.api.client.util.Value
) 添加 @value
注释解决了该问题。
同一个 TableRow
对象也包含 byte[]
类型的值。此值已注入 bytes
类型的 BigQuery 列中。虽然这在之前没有显式计算 base64 的情况下工作,但现在会产生错误。
- 通过我们自己计算 base64 解决了这个问题(此设置也在下面 post 中讨论)。
自从 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
接收器收到了大量更新。我特别担心以下变化:
- BigQuery 的 DATETIME 类型现在映射到 Beam 逻辑类型 org.apache.beam.sdk.schemas.logicaltypes.SqlTypes.DATETIME
- Java BigQuery 流式插入现在默认启用超时。传递
--HTTPWriteTimeout=0
以恢复旧行为
关于第一次更新,我确保在生成的 TableRow
对象中禁用所有 DATETIME
。在这种特定情况下,错误仍然存在。
对于第二个更改,我不确定如何将 --HTTPWriteTimeout=0
标志传递给管道。如何最好地实现这一目标?
关于此问题的根本原因还有其他建议吗?
提前致谢!
--HTTPWriteTimeout
是一个 pipeline option。您可以像设置跑步者等一样设置它(通常在命令行上)。
我们终于能够解决这个问题,请放心,这是一段非常愉快的旅程。我们基本上调试了整个 BigQueryIO 连接器并得出以下结论:
转发到 BigQuery 的
TableRow
个对象用于包含枚举值。由于这些不可序列化,空负载被转发到 BigQuery。在我看来,这个错误应该更加明确(为什么突然改变了这个?)。- 通过向每个枚举条目 (
com.google.api.client.util.Value
) 添加@value
注释解决了该问题。
- 通过向每个枚举条目 (
同一个
TableRow
对象也包含byte[]
类型的值。此值已注入bytes
类型的 BigQuery 列中。虽然这在之前没有显式计算 base64 的情况下工作,但现在会产生错误。- 通过我们自己计算 base64 解决了这个问题(此设置也在下面 post 中讨论)。