【问题标题】:BigQuery Java 函数超时
【发布时间】:2022-01-17 03:24:00
【问题描述】:

我正在对大约 120 个表进行一系列计算。

算法:读取最终表,找到 where day=something 并将结果附加到现有表中

    For table2 in tablearray
    {
    query = "SELECT * " +
    " FROM (SELECT * FROM tablefinal where day=someday) AS tmp " +
    "WHERE NOT EXISTS (" +
    "SELECT * FROM table2 t2 where  t2.user_id=tmp.user_id AND  t2.day=tmp.day);"
    
    then append rows to table2...
     QueryJobConfiguration queryConfig =
                    QueryJobConfiguration.newBuilder(query).setDestinationTable(destinationTable)
          .setWriteDisposition(JobInfo.WriteDisposition.WRITE_APPEND).build();
....

  bigquery.query(queryConfig);

    }

使用 120 表仍然使用 finaltable 作为数据源。

问题。耗时太长。像 700 秒。 540 秒后,谷歌功能消失。 结果是对的,就是太慢了……

问题如何加快速度(这些表很小~100K 行)? 我可以并行发送一堆查询吗?

【问题讨论】:

  • 是同步计算吗?或者您可以异步执行计算吗? (例如,如果您使用 Cloud Scheduler 运行您的函数,它是异步的,在用户操作之外并等待答案)
  • 纪尧姆,感谢您的回答。我相信它是异步的,我可以独立运行这些查询。

标签: java google-bigquery google-cloud-pubsub


【解决方案1】:

您可以在代码中同时运行请求以并行化请求,但这不是最佳方式。

就个人而言,我建议您为要运行的每个查询发布一条 PubSub 消息。所以,这里的过程:

  • Cloud Scheduler 运行第一个 Cloud Functions
  • 第一个 Cloud Functions 遍历表以查询并在 PubSub 中发布一条消息以执行每个查询:消息中包含的参数由您决定
  • 第二个 Cloud Functions 绑定到 PubSub 主题执行查询。 (如果您愿意,还可以创建 PubSub 推送订阅并调用 HTTP Cloud Function 或 HTTP 中的其他内容,例如 Cloud Run 或 App Engine)

这个过程是可扩展的(明天你有 250 个表,不用担心,它会扩展!!)。不要忘记在第二个 Cloud Functions 上设置重试参数,因为对 BigQuery 的高速并行请求可能会产生暂时性问题

【讨论】:

    【解决方案2】:

    试试 Magnus - Workflow Automator - 您可以在 GCP Marketplace 上找到它 - 作为 Potens.io BigQuery 工具套件的一部分

    在 Magnus 中,您可以使用 Loop Task 轻松构建工作流,该工作流将获取一个表列表,并为每个表执行您需要的任何查询/语句。

    您可以将循环任务设置为在异步模式下执行 - 因此所有表都将并行处理

    如您所见,您甚至可以控制允许的并发迭代次数 - 因此您尊重各自的 API 限制

    查看https://potensio.zendesk.com了解更多详情

    披露:我是 Viant Tech 的 Potens.io 项目的作者和负责人

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-02-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-29
      • 1970-01-01
      • 2012-06-18
      • 2013-01-31
      相关资源
      最近更新 更多