Google cloud dataflow 从BigQuery读取小表时发生Dataflow OutOfMemoryError

Google cloud dataflow 从BigQuery读取小表时发生Dataflow OutOfMemoryError,google-cloud-dataflow,Google Cloud Dataflow,我们有一个从BigQuery读取数据和处理不同日历年的历史数据的程序。如果输入数据很小(~500MB),则会出现OutOfMemoryError故障 在启动时,它从BigQuery读取大约10.000个元素/秒,在短时间后,它会减慢到数百个元素/秒,然后完全挂起 在下一个处理步骤(BQImportAndCompute)中观察“添加的元素”,值会先增加,然后再次减少。在我看来,一些已经加载的数据被删除,然后再次加载 Stackdriver日志控制台包含包含java.lang.OutOfMemory

我们有一个从BigQuery读取数据和处理不同日历年的历史数据的程序。如果输入数据很小(~500MB),则会出现OutOfMemoryError故障

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

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

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

向数据流服务报告工作项进度更新时出错:

我怀疑管道的拓扑结构有问题,但运行的是同一条管道

  • 本地使用DirectPipelineRunner工作良好
  • 在云中在大型数据集上使用DataflowPipelineRunner(5GB,另一年)工作正常

  • 我假设问题在于数据流如何在管道中并行和分配工作。是否有可能检查或影响它?

    您是否尝试过使用Stackdriver进行调试


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

  • 你没有从多个BigQuery源中读取数据并将其展平,而是尝试从一个获取所有信息的查询中读取数据吗?在一个步骤中完成这一操作将简化管道,并允许BigQuery更好地执行(针对多个表的一个查询与针对单个表的多个查询)

  • 另一个可能的问题是
    BQImportAndCompute
    操作内部或之后是否存在高度扇出。根据正在进行的计算,您可以使用Smart
    CombineFn
    s或
    WindowFn
    s减少扇出。如果您想了解如何改进该路径,请分享有关
    BQImportAndCompute
    之后发生的事情的更多详细信息


  • 有关
    BQImportAndCompute
    正在做什么的详细信息?另外,
    BQConcat
    看起来像一个
    flatte
    ,对吗?是否有一个特定的作业ID,我们应该查看它发生了什么?BQImportAndCompute正在读取TableRow并转换到另一个POJO。是的,它是扁平的。例如,jobID 2016-04-22_07_09_50-6916524826145032691。事实上,当时所有手动取消的作业都没有完成。另外,我后来发现,在抛出OfMemory之后,JVM并没有退出。我已连接到worker并试图终止JVM进程。然后更多的数据被处理到下一个OOM。重复几次后,由于重试次数过多,管道失败。为了进行比较,同一管道(java代码)作业2016-04-22_05_01_130-3684926617487173331输入大小4.07 GB-已完成。Jobs 2016-04-21_08_51_03-96494788151185303602016-04-21_10_04_12-4127814452160753674输入大小339MB-失败。我将管道的源代码放在github上,我将尝试降低扇出度。
    "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)