Combine.PerKey 在全局 window 上的内存使用

Memory usage of Combine.PerKey on a global window

我们使用 Combine.PerKey 和自定义 KeyedCombineFn 对一些 PCollection 执行连接。 PCollections 被分配给一个 GlobalWindow,在 AfterProcessingTime.pastFirstElementInPane.

上有一个 Repeatedly.forever 触发器

PCollections 包含大约 100 万个键,但对于给定的键,只有几百个元素。 KeyedCombineFn 在其累加器中保留了大约几 KB(有时高达 5 MB)的数据。

现在我们已经增加了我们在管道中处理的数据量,我们看到了 java.lang.OutOfMemoryError:Java 堆 space 错误。该管道在 Google Cloud Dataflow 上的 n1-highmem-4 机器上运行。

我们的假设是 Dataflow worker 独立管理每个键的状态,并根据可用 RAM 的大小对 write/load 它 to/from 磁盘进行启发式处理。因此,目标是让单个状态适合一个工人的记忆。

这个假设是否正确?如果是这样,为什么我们会看到 OOM 错误?如果不是,您介意详细说明 Dataflow worker 如何管理内存中的状态吗?

Dataflow 工作人员的行为确实与您假设的大致相同,但其中涉及一些估计,并且您的数据可能会破坏它。您的累加器的序列化大小与对象的 in-memory 大小是否存在很大差异?

尝试解决此问题的最简单方法是 运行 在较少的大型机器上,例如 n1-highmem-8