google-cloud-dataflow – 从BigQuery读取小表时的Dataflow OutOfMemoryError

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

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

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

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

Error reporting workitem progress update to Dataflow service:

"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工作正常
>在云中使用大数据集上的DataflowPipelineRunner(5GB,再过一年)工作正常

我假设问题是Dataflow如何在管道中并行化和分配工作.有没有可能检查或影响它?

最佳答案 这里的问题似乎与BigQuery表的大小无关,但可能与正在使用的BigQuery源的数量和管道的其余部分有关.

>您是否尝试从提取所有信息的查询中读取,而不是从多个BigQuery源读取并展平它们?在一个步骤中执行此操作应简化管道并允许BigQuery更好地执行(针对多个表的一个查询与针对各个表的多个查询).
>另一个可能的问题是BQImportAndCompute操作内或之后是否存在高度扇出.根据在那里进行的计算,您可以使用聪明的CombineFns或WindowFns减少扇出.如果您需要帮助确定如何改进该路径,请分享有关BQImportAndCompute之后发生的事情的更多详细信息.

点赞