BigQueryIO - 使用流和FILE_LOADS

时间:2018-03-19 16:26:00

标签: google-cloud-platform google-bigquery google-cloud-dataflow apache-beam

我的管道:Kafka - >数据流流(Beam v2.3) - >大量查询

鉴于低延迟在我的情况下并不重要,我使用FILE_LOADS来降低成本,如下所示:

BigQueryIO.writeTableRows()
  .withJsonSchema(schema)
  .withWriteDisposition(WriteDisposition.WRITE_APPEND)
  .withCreateDisposition(CreateDisposition.CREATE_IF_NEEDED)
  .withMethod(Method.FILE_LOADS)
  .withTriggeringFrequency(triggeringFrequency)      
  .withCustomGcsTempLocation(gcsTempLocation)
  .withNumFileShards(numFileShards) 
  .withoutValidation()
  .to(new SerializableFunction[ValueInSingleWindow[TableRow], TableDestination]() {
    def apply(element: ValueInSingleWindow[TableRow]): TableDestination = {
      ...
    }
  }

此数据流步骤在管道中引入了一个总是更大的延迟,因此它无法跟上Kafka吞吐量(小于50k事件/秒),即使有40 n1-standard-s4个工作人员也是如此。如下面的屏幕截图所示,此步骤的系统滞后非常大(接近管道正常运行时间),而Kafka系统滞后只有几秒钟。

System lag introduced by BigQueryIO.Write

如果我理解正确,Dataflow会将这些元素写入 gcsTempLocation 中的 numFileShards ,并且每个 triggeringFrequency 都会启动一个加载作业,将它们插入到BigQuery中。例如,如果我选择5分钟的 triggeringFrequency ,我可以看到(使用bq ls -a -j)所有加载作业需要不到1分钟才能完成。但仍然是这一步骤引入了越来越多的延迟,导致Kafka消耗越来越少的元素(由于bcackpressure)。增加/减少 numFileShards triggeringFrequency 并不能解决问题。

我没有手动指定任何窗口,我只是默认窗口。文件不会在 gcsTempLocation 中累积。

知道这里出了什么问题吗?

1 个答案:

答案 0 :(得分:1)

您提到您没有明确指定一个窗口,这意味着默认情况下,Dataflow将使用"全局窗口"。 windowing documentation包含此警告:

  

警告:数据流的默认窗口行为是分配全部   PCollection的元素到单个全局窗口,甚至是   无界的PCollections。在使用分组转换之前,例如   GroupByKey在无界PCollection上,你必须设置一个非全局的   开窗功能。请参阅设置PCollection的窗口函数。

     

如果您没有为无界限设置非全局窗口功能   PCollection并随后使用分组变换,如   GroupByKey或Combine,您的管道将生成错误   构造和数据流作业将失败。

     

您也可以为PCollection设置非默认触发器   允许全局窗口早期发出"其他一些结果   条件。

您的管道似乎没有进行任何显式分组,但我想知道通过BigQuery写入内部分组是否会导致问题。

您是否可以在界面中看到您的下游DropInputs是否收到了任何元素?如果没有,这表明数据在上游BigQuery步骤中被阻止。