GCP 数据流 运行 流式插入 BigQuery:GC 抖动

GCP Dataflow running streaming inserts into BigQuery: GC Thrashing

我正在使用 Apache Beam 2.13.0 和 GCP Dataflow runner。

我在从批处理管道流式摄取到 BigQuery 时遇到问题:

PCollection<BigQueryInsertError> stageOneErrors =
  destinationTableSelected
    .apply("Write BQ Attempt 1",
      BigQueryIO.<KV<TableDestination, TableRow>>write()
                .withMethod(STREAMING_INSERTS)
                .to(new KVTableDestination())
                .withFormatFunction(new KVTableRow())
                .withExtendedErrorInfo()
                .withFailedInsertRetryPolicy(InsertRetryPolicy.neverRetry())
                .withCreateDisposition(CreateDisposition.CREATE_NEVER)
                .withWriteDisposition(WriteDisposition.WRITE_APPEND))
                .getFailedInsertsWithErr();

错误:

 Shutting down JVM after 8 consecutive periods of measured GC thrashing. 
 Memory is used/total/max = 15914/18766/18766 MB, 
 GC last/max = 99.17/99.17 %, #pushbacks=0, gc thrashing=true. 
 Heap dump not written.

相同的代码在流模式下正确工作(如果省略了显式方法设置)。

该代码适用于相当小的数据集(少于 200 万条记录)。超过 250 万失败。

从表面上看,它似乎与此处描述的问题类似:Shutting down JVM after 8 consecutive periods of measured GC thrashing

创建一个单独的问题以添加更多详细信息。

我能做些什么来解决这个问题吗?看起来问题出在 BigQueryIO 组件本身 - GroupBy 键失败。

包含 GroupByKey 的转换的问题在于它将等到 所有 当前 window 的数据在分组之前被接收。

在 Streaming 模式下,这通常很好,因为传入的元素被 window 编入单独的 windows,因此 GroupByKey 仅对一小部分数据进行操作。

然而,在批处理模式下,当前window 是全局Window,这意味着GroupByKey 将等待整个输入数据集被读取和接收,然后才开始执行分组。如果输入数据集很大,那么您的工作人员将 运行 内存不足,这解释了您在此处看到的内容。

这就提出了一个问题:为什么在处理 Batch 数据时使用 BigQuery Streaming insert?流式插入 relatively expensive (compared to bulk which is free!) and have smaller quota/limits 比批量导入要多:即使您解决了所遇到的问题,Bigquery 本身可能还有更多问题有待发现。

在与支持人员和开发人员进行广泛讨论后,我们了解到不鼓励使用来自批处理管道的 BigQuery 流入口,目前(从 2.13.0 开始)不支持。