首页 > 解决方案 > 在加入并将它们导出到 GCS 之前,如何等待 BigQuery 上的异步表写入?

问题描述

我有一个在 Google Cloud Platform 上运行的系统,它的工作原理如下:

首先,有一个 Cloud Function 由特定存储桶上的数据上传触发。然后,它组织这些数据并生成处理器作业作为“.json”,并将其保存到另一个存储桶中。

还有第二个云函数——系统的核心——由这个“.json”上传触发。然后,它处理数据并将输出结果作为单个表写入 BigQuery 数据集。

我还编写了另一个 Cloud Function,它连接了这个 BigQuery 数据集中的所有表,并将其导出到 Google Cloud Storage 存储桶中的 CSV。

因此问题出现了:只有将所有表都插入 BigQuery 后,我才能调用最后一个聚合云函数。我该如何管理?只有在所有表格都存在之后,我才能触发此功能?

标签: google-cloud-platformgoogle-bigquerygoogle-cloud-functions

解决方案


没有简单的方法,但我有两个建议

  • 如果您没有时间限制并且可以按顺序处理文件,则可以执行此操作
    • 第一个函数进行拆分并构建overview.json文件。overwien.json然后用 in 参数调用第二个函数,文件中第一个 json 的名称
    • 第二个函数根据参数处理JSON文件的数据,将它们写入BQ。然后使用文件中的下一个条目调用第二个函数overview.json。如果是最后一个条目,则调用第三个函数
    • 处理完所有数据后调用第三个函数

它有效,但你失去了并行化的力量。

  • 另一种解决方案是使用 Datastore/Firestore。而要做到这一点
    • 第一个函数进行拆分并在 Datastore/Firestore 中写入一个条目,其中包含要处理的 JSON 文件列表及其状态为“未处理”。
    • 第二个函数在 json 上传时触发(如今天),处理数据,将它们写入 BigQuery,将 Datastore/Firestore 中 JSON 文件的状态更新为“已处理”,然后调用第三个函数
    • 第三个函数查询 Datastore/Firestore 并检查所有要处理的 json 文件是否处于“已处理”状态。如果否,则退出该功能。如果是,则执行该函数中的处理。

我更喜欢这个解决方案。您必须注意最后一个函数的竞争条件(如果您愿意,我可以为您提供处理它的提示),并且您需要有一个全局构建 ID 以不混合 2 个不同执行的状态更新(如果有 2并发执行第一个函数)

更新

对于比赛条件,我通常执行此操作

  • 创建一个空间(表或集合)来记录某些内容。在您的情况下,它可以与 Firestore 中的概述文档一起使用。
  • 第三个功能,当它检查所有部分都已处理后,检查第三个功能是否正在运行
    • 如果是,退出
    • 如果否,请在表/集合中写入由函数生成的唯一 ID(例如 UUID)(在您的情况下为 Firestore)
  • 第三次再次读取表/集合(在您的情况下在 Firestore 中)并检查保存的 ID 是否是它自己的 ID
    • 如果是,则处理
    • 如果没有,退出

它并不完美,但它可以涵盖大多数情况。


推荐阅读