从BigQuery读取小表时数据流OutOfMemoryError

时间:2016-04-22 12:24:52

标签: google-cloud-dataflow

我们有来自BigQuery的pipeline阅读数据,并处理各个日历年的历史数据。如果输入数据很小,会因OutOfMemoryError 错误而失败(~500MB)

在启动时,它从BigQuery读取大约10.000个元素/秒,在短时间内它减慢到数百个元素/秒然后它完全挂起。

观察'添加的元素'在下一个处理步骤(BQImportAndCompute)上,该值增加然后再次减小。在我看来,一些已经加载的数据被删除然后再次加载。

Stackdriver Logging控制台包含各种包含java.lang.OutOfMemoryError的堆栈跟踪错误,例如:

  

将工作项目进度更新报告给Dataflow服务时出错:

"java.lang.OutOfMemoryError: Java heap space
    at com.google.cloud.dataflow.sdk.runners.worker.BigQueryAvroReader$BigQueryAvroFileIterator.getProgress(BigQueryAvroReader.java:145)
    at com.google.cloud.dataflow.sdk.util.common.worker.ReadOperation$SynchronizedReaderIterator.setProgressFromIteratorConcurrent(ReadOperation.java:397)
    at com.google.cloud.dataflow.sdk.util.common.worker.ReadOperation$SynchronizedReaderIterator.setProgressFromIterator(ReadOperation.java:389)
    at com.google.cloud.dataflow.sdk.util.common.worker.ReadOperation$1.run(ReadOperation.java:206)

我怀疑管道拓扑存在问题,但运行相同的管道

    使用DirectPipelineRunner的
  1. 本地 正常工作
  2. 云中的
  3. ,大​​数据集上的DataflowPipelineRunner (5GB,另一年)正常工作
  4. 我认为问题是Dataflow如何在管道中并行化和分配工作。是否有可能检查或影响它?

2 个答案:

答案 0 :(得分:1)

这里的问题似乎与BigQuery表的大小无关,但可能与正在使用的BigQuery源的数量以及管道的其余部分有关。

  1. 您是否尝试过读取所有信息的查询,而不是从多个BigQuery源读取并展平它们?在一个步骤中执行此操作应简化管道并允许BigQuery更好地执行(针对多个表的一个查询与针对各个表的多个查询)。

  2. 另一个可能的问题是val source = Source(1 to 10) val sink = Sink.fold[Int, Int](0)(_ + _) // connect the Source to the Sink, obtaining a RunnableGraph val runnable: RunnableGraph[Future[Int]] = source.toMat(sink)(Keep.right) // how could I materialize to a Seq of Sinks? // materialize the flow and get the value of the FoldSink val sum: Future[Int] = runnable.run() 操作内或之后是否存在高度扇出。根据在那里进行的计算,您可以使用聪明的BQImportAndComputeCombineFn来减少扇出。如果您需要帮助确定如何改进该路径,请在WindowFn之后分享有关正在发生的事情的更多详细信息。

答案 1 :(得分:0)