Google bigquery 通过加载作业(非流式)插入BigQuery

Google bigquery 通过加载作业(非流式)插入BigQuery,google-bigquery,google-cloud-dataflow,Google Bigquery,Google Cloud Dataflow,我希望使用Dataflow将数据加载到BigQuery表中,使用-而不是流(流对于我们的用例来说成本太高)。我看到Dataflow SDK内置了对通过BQ流插入数据的支持,但是我在Dataflow SDK中找不到任何支持开箱即用加载作业的东西 一些问题: 1) Dataflow SDK是否支持BigQuery加载作业插入的OOTB?若否,有否计划 2) 如果我需要自己动手,有哪些好方法 如果我必须自己动手,使用谷歌云存储执行BQ加载作业是一个多步骤的过程——将文件写入GCS,通过BQ API提交

我希望使用Dataflow将数据加载到BigQuery表中,使用-而不是流(流对于我们的用例来说成本太高)。我看到Dataflow SDK内置了对通过BQ流插入数据的支持,但是我在Dataflow SDK中找不到任何支持开箱即用加载作业的东西

一些问题:

1) Dataflow SDK是否支持BigQuery加载作业插入的OOTB?若否,有否计划

2) 如果我需要自己动手,有哪些好方法

如果我必须自己动手,使用谷歌云存储执行BQ加载作业是一个多步骤的过程——将文件写入GCS,通过BQ API提交加载作业,并(可选)检查状态,直到作业完成(或失败)。我希望可以使用现有的TextIO.write()功能来写入GCS,但我不确定如何通过对BQ API的后续调用来编写该步骤,以提交加载作业(也可以选择后续调用来检查作业的状态,直到作业完成)

此外,我将在流模式下使用Dataflow,窗口为60秒,因此我希望每60秒执行一次加载工作


建议?

BigQueryIO.write()
在输入
PCollection
有界时始终使用BigQuery加载作业。如果您希望它在没有绑定的情况下也使用它们,请指定
.withMethod(文件加载)。withTriggeringFrequency(…)

我不确定您使用的是哪个版本的Apache Beam,但现在可以使用流管道使用微批处理策略。如果你决定采用这样或那样的方式,你可以使用这样的方式:

.apply("Saving in batches", BigQueryIO.writeTableRows()
                    .to(destinationTable(options))
                    .withMethod(Method.FILE_LOADS)
                    .withJsonSchema(myTableSchema)
                    .withCreateDisposition(CreateDisposition.CREATE_IF_NEEDED)
                    .withWriteDisposition(WriteDisposition.WRITE_APPEND)
                    .withExtendedErrorInfo()
                    .withTriggeringFrequency(Duration.standardMinutes(2))
                    .withNumFileShards(1);
                    .optimizedWrites());
要记住的事情

  • 有两种不同的方法:
    FILE\u LOADS
    STREAMING\u INSERT
    ,如果使用第一种方法,则需要将
    包含在triggeringfrequency
    包含在numfileshards
    中。根据我的经验,对于第一种情况,最好使用分钟数,并且数量取决于吞吐量数据的数量。如果你收到了很多,试着把它保持在小的范围内,当你增加太多的时候,我看到了“卡住的错误”。碎片可能会影响你的GCS账单,如果你添加更多的碎片,那么每x分钟内每个表将创建更多的文件
  • 如果您的输入数据大小不是那么大,那么流式插入可以非常好地工作,而且成本应该不是什么大问题。在这种情况下,您可以使用
    STREAMING\u INSERT
    方法,并使用triggeringfrequency删除
    ,使用numfileshards删除
    。此外,您还可以添加带有FailedEntertryPolicy的
    ,如
    InsertRetryPolicy.retryTransientErrors()
    ,这样就不会丢失任何行(请记住,流\u插入不能保证幂等性,因此可能会出现重复)
  • 您可以在BigQuery中检查您的作业,并验证一切正常!当您试图定义触发频率和碎片时,请记住BigQuery作业的策略(我认为每个表有1000个作业)
  • 注意:您可以随时阅读这篇关于高效聚合管道的文章


    (删除答案,并转换为注释)。在批处理模式下,数据流将实际写入GCS,然后启动BigQuery批量加载作业以获取数据。然后,它应该在管道成功(或失败)后删除GCS中的文件,但其中存在bug()。在流模式下,它确实会使用流API。我们这里说的是什么尺寸?流媒体的成本仅为每200MB 0.01美元。也许你可以写两条管道——一条写入GCS(在流模式下),另一条在批处理模式下使用这些文件并使用BQ的批量加载?有趣的是,没有意识到DF写入BQ的方式与管道是批处理还是流式不同。我仍然在DFSDK中找不到批处理BQ加载代码,但可能它没有随SDK一起分发?关于流式处理成本,对于我们的用例来说,价格有点高——大约60亿1KB行/天,对于BQ流式处理插入,这大约是9000美元/月(最小1KB行的大小让我们丧命,因为我们的大多数行实际上是该大小的一半)。拥有两条管道的想法如何?一个写入GCS(流媒体),另一个(批量)收集数据并批量加载到BQ?那对你有用吗?也许谷歌的一位工程师会跳到这里,并给出更多(可能更好:)的建议。谢谢你的建议——流式传输到地面军事系统,批量加载到BQ也是我现在的想法,尽管我不喜欢增加的操作开销。我想我会更深入地研究代码,看看我是否可以让DF在流模式下对BQ进行批量加载。我今天碰巧看到了这个线程——这看起来是一个很棒的功能请求,我将在内部进行。延迟和成本之间存在明显的紧张关系——你能告诉我们什么类型的延迟是可以接受的吗?例如,流式传输到GCS,然后每24小时运行一次批量导入作业就可以了。。。