Google cloud dataflow 全局窗口上Combine.PerKey的内存使用情况

Google cloud dataflow 全局窗口上Combine.PerKey的内存使用情况,google-cloud-dataflow,Google Cloud Dataflow,我们使用Combine.PerKey和自定义KeyedCombineFn在几个PCollection上执行联接。在AfterProcessingTime.pastFirstElementInPane上,将PCollections分配给具有Repeative.forever触发器的全局窗口 PCollection包含大约1M个键,但对于给定的键,只有几百个元素。KeyedCombineFn在其累加器中保留大约几KB(有时高达5 MB)的数据 现在我们已经增加了管道中处理的数据量,我们看到java.

我们使用Combine.PerKey和自定义KeyedCombineFn在几个PCollection上执行联接。在AfterProcessingTime.pastFirstElementInPane上,将PCollections分配给具有Repeative.forever触发器的全局窗口

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

现在我们已经增加了管道中处理的数据量,我们看到java.lang.OutOfMemoryError:java堆空间错误。该管道在谷歌云数据流上的n1-highmem-4机器上运行

我们的假设是,数据流工作人员独立管理每个密钥的状态,并根据其可用RAM的多少,使用启发式方法将其写入/加载到磁盘。因此,目标是让单个状态适合一个工作者的记忆


这个假设正确吗?如果是这样,为什么我们会看到OOM错误?如果没有,您介意详细说明数据流工作人员如何管理内存中的状态吗?

数据流工作人员的行为确实与您假设的大致相同,但其中涉及到一些估计,您的数据可能有问题。累加器的序列化大小和对象的内存大小是否存在很大差异


要想解决这个问题,最简单的方法是在更少的大型机器上运行,比如n1-highmem-8

谢谢!在那种情况下,我们有可能是这样。你所说的“巨大差异”是什么意思?有什么经验法则可以避免这个问题吗?顺便问一下,您是否有任何关于如何在正在运行的流式数据流作业中衡量这一点的建议?worker Harnese目前缓存了100MB的序列化数据,相当于内存中的对象。如果这足以超过机器的限制,你可以点击这个。最好的方法是分析堆转储,您可以通过设置--heapDumpOnOOM:谢谢。改变我们的序列化程序似乎成功了。