我们有来自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)
我怀疑管道拓扑存在问题,但运行相同的管道
我认为问题是Dataflow如何在管道中并行化和分配工作。是否有可能检查或影响它?
答案 0 :(得分:1)
这里的问题似乎与BigQuery表的大小无关,但可能与正在使用的BigQuery源的数量以及管道的其余部分有关。
您是否尝试过读取所有信息的查询,而不是从多个BigQuery源读取并展平它们?在一个步骤中执行此操作应简化管道并允许BigQuery更好地执行(针对多个表的一个查询与针对各个表的多个查询)。
另一个可能的问题是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()
操作内或之后是否存在高度扇出。根据在那里进行的计算,您可以使用聪明的BQImportAndCompute
或CombineFn
来减少扇出。如果您需要帮助确定如何改进该路径,请在WindowFn
之后分享有关正在发生的事情的更多详细信息。
答案 1 :(得分:0)