繁体   English   中英

无法通过 Python SDK 使用 BigQuery 运行多个 UPDATE

[英]Unable to run multiple UPDATE with BigQuery via Python SDK

我正在使用 Apache Beam 和 Dataflow 使用 Python 进行 ETL,并且我正在使用 BigQuery 作为数据库/数据仓库。

ETL 基本上会执行一些处理,然后更新 BigQuery 中已有的数据。 由于 Apache Beam 中没有更新转换,我不得不使用 BigQuery SDK 并编写自己的 UPDATE 查询,并将 map 写入每一行。

查询按顺序完成时工作正常,但是当我使用多个工作人员时,我收到以下错误:

{'reason': 'invalidQuery', 'message': 'Could not serialize access to table my_table due to concurrent update'}

我确保永远不会同时访问/更新同一行(一行基本上是一个 id,每个 id 都是唯一的),我还尝试使用没有 Beam/Dataflow 的简单 Python 脚本运行相同的代码,并且我当我开始使用多个线程而不是一个线程时仍然出现相同的错误。

有没有人在使用 BigQuery SDK 时遇到过同样的问题? 你有什么建议可以避免这个问题吗?

我认为从您的Beam Dataflow作业到append数据更好。 Bigquery更面向appendBeam中的BigueryIO适用于append操作。

如果您有Cloud Composer/AirflowCloud Workflows等编排器,则可以通过以下步骤以batch模式对数据进行重复数据删除:

  • 创建临时表和决赛桌
  • 您的协调器截断您的临时表
  • 您的协调器运行您的 Dataflow 作业
  • 数据流作业读取您的数据
  • 数据流作业将 append 模式的结果写入staging表中的 Bigquery
  • 您的协调器在暂存表和最终表之间使用Bigquery运行具有merge查询的任务。 如果元素存在,合并查询允许在最终表中插入或更新行。

https://cloud.google.com/bigquery/docs/reference/standard-sql/dml-syntax?hl=en#merge_statement

合并查询示例:

MERGE dataset.Inventory T
USING dataset.NewArrivals S
ON T.product = S.product
WHEN MATCHED THEN
  UPDATE SET quantity = T.quantity + S.quantity
WHEN NOT MATCHED THEN
  INSERT (product, quantity) VALUES(product, quantity)

我有一个用例,其中我有一个包含大约 150K 记录的 BQ 表,我需要每月更新它的内容(这意味着大约 100K UPDATE和几千APPEND

当我设计我的 Beam/Dataflow 作业以使用 BQ python API 库更新记录时,我陷入了配额问题(更新数量有限)以及并发问题。

我不得不改变我的管道正在使用的方法,从读取 BQ 表和更新记录,到处理 BQ 表,更新需要更新的内容,以及 append 什么是新的,然后保存到新的 BQ 表。

一旦作业成功完成且没有错误,您可以用新创建的表替换旧表。

GCP 提到:

只要两个语句不修改同一分区中的数据,同时对表运行两个变异 DML 语句就会成功。 尝试改变同一分区的两个作业有时可能会遇到并发更新失败。

接着:

BigQuery 现在会自动处理此类故障。 为此,BigQuery 将重新启动作业。

这种重试机制能否成为一种解决方案? 任何人都可以详细说明这一点?

资料来源: https://cloud.google.com/blog/products/data-analytics/dml-without-limits-now-in-bigquery

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM