来自云存储 (GCS) 的 reading/writing 时,云数据流 运行 真的很慢

Cloud Dataflow Running really slow when reading/writing from Cloud Storage (GCS)

自从使用最新版本的 Cloud Dataflow (0.4.150414) 以来,我们的工作 运行 从云存储 (GCS) 读取时非常慢。在使用 10 个虚拟机 运行 20 分钟后,我们只能读取大约 20 条记录,而以前我们可以毫无问题地读取数百万条记录。

它似乎挂起,尽管没有错误被报告回控制台。

我们收到一封电子邮件,通知我们最新版本的速度会变慢,可以通过使用更多 VM 来应对,但我们在 50 个 VM 上得到了类似的结果。

这里是供参考的职位编号:2015-04-22_22_20_21-5463648738106751600

实例:n1-standard-2
区域:us-central1-a

您的工作似乎是对 DoFn 使用辅助输入。由于 Java 的 Cloud Dataflow SDK 处理侧输入的方式最近发生了变化,您的性能问题很可能与此有关。我正在重新发布相关问题的答案。


证据似乎表明您的管道处理边输入的方式存在问题。具体来说,对于主输入的每个元素,副输入很可能会一次又一次地从 BigQuery 中重新读取。这与数据流工作者使用的虚拟机类型的变化完全正交,如下所述。

这与 Java 版本 0.3.150326 的数据流 SDK 中所做的更改密切相关。在该版本中,我们将侧输入 API 更改为按 window 应用。调用 sideInput() 现在 return 值仅在特定 window 对应于主输入元素的 window,而不是整个侧输入 PCollectionView。因此,无法再从 DoFnstartBundlefinishBundle 中调用 sideInput(),因为 window 尚不清楚。

例如,以下代码片段存在一个问题,会导致重新读取每个输入元素的侧输入。

@Override
public void processElement(ProcessContext c) throws Exception {
  Iterable<String> uniqueIds = c.sideInput(iterableView);

  for (String item : uniqueIds) {
    [...]
  }

  c.output([...]);
}

可以通过在第一次调用 processElement 期间将边输入缓存到转换的 List 成员变量(假设它适合内存)来改进此代码,并使用缓存的 List 而不是后续调用中的侧输入。

此解决方法应该可以恢复您之前看到的性能,当时可以从 startBundle 调用侧输入。从长远来看,我们将致力于更好地缓存侧输入。 (如果这不能帮助完全解决问题,请通过电子邮件联系我们并分享相关代码片段。)


另外,确实,云数据流服务在 2015 年 4 月 9 日左右进行了一次更新,更改了数据流工作者使用的默认虚拟机类型。具体来说,我们减少了每个工作人员的默认核心数,因为我们的基准测试表明它对于典型的工作具有成本效益。这 不是 任何类型的数据流服务的减速——默认情况下,它只是以每个工作人员更少的资源运行。用户仍然可以选择覆盖工作人员的数量以及工作人员使用的虚拟机类型。

我们遇到了类似的问题。这是当侧输入从 BigQuery table 读取数据时,它的数据是流式传输的,而不是批量加载的。当我们复制 table(s),并从副本中读取时,一切正常。

如果您的 table 是流式传输的,请尝试复制它们并阅读副本。这是一个解决方法。

参见: