Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/360.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
OOM杀手杀死数据流工作者中的Java_Java_Google Cloud Dataflow_Apache Beam - Fatal编程技术网

OOM杀手杀死数据流工作者中的Java

OOM杀手杀死数据流工作者中的Java,java,google-cloud-dataflow,apache-beam,Java,Google Cloud Dataflow,Apache Beam,我有一个相当简单的流式数据流管道,使用批处理加载(启用流式引擎)从pubsub读取数据流并写入BigQuery。我们确实有一个版本的管道在工作,但它看起来非常脆弱,简单的代码添加似乎会使它崩溃,工作进程开始消耗内存 有时Java堆会填满,获取Java.lang.OutOfMemoryError,转储堆,jhat显示堆中充满Windmill.Message对象 更常见的情况是,机器变得非常慢(内核开始交换),然后内核杀死Java 今天,我有更多的证据可能有助于调试这个问题:一个实时工作者(co

我有一个相当简单的流式数据流管道,使用批处理加载(启用流式引擎)从pubsub读取数据流并写入BigQuery。我们确实有一个版本的管道在工作,但它看起来非常脆弱,简单的代码添加似乎会使它崩溃,工作进程开始消耗内存

  • 有时Java堆会填满,获取Java.lang.OutOfMemoryError,转储堆,jhat显示堆中充满Windmill.Message对象
  • 更常见的情况是,机器变得非常慢(内核开始交换),然后内核杀死Java
今天,我有更多的证据可能有助于调试这个问题:一个实时工作者(compute.googleapis.com/resource_id:“1183238143363133621”),开始交换,但成功地摆脱了该状态而没有崩溃。工作日志显示Java堆正在使用1GB(总内存),但当我将ssh连接到工作日志中时,“top”显示Java进程正在使用3.2GB

是什么导致Java在堆外使用如此多的内存

我使用的是Beam 2.15 PubsubIO,是Beam的BigQueryIO的一个克隆,经过一些修改。我曾尝试将机器尺寸增大,但这只会延迟失败。当pubsub订阅有很多积压工作时,它最终还是会填满内存

编辑:


更多细节:内存问题似乎比BigQueryIO发生得更早。在PubsubIO.Read和BigQueryIO.Write之间有两个步骤:解析和增强。Enhanced使用了一个侧面输入,所以我怀疑fusion并没有应用于合并这两个步骤。触发器启动非常慢(为什么?),因此由于侧面输入的合并,Enhanced启动缓慢。全局延迟约3分钟,即使在准备就绪后,WriteGroupedRecords有时在我知道数据准备就绪后10分钟调用。当它被调用时,它通常包含超过3分钟的数据。通常,尤其是当管道刚刚启动时,解析步骤将从pubsub中提取近1000000条记录。一旦Enhanced开始工作,它将快速处理1000000行并将它们转换为TableRows。然后,它从pubsub提取越来越多的数据,持续10分钟而不调用WriteGroupedRecords。运行人员似乎更喜欢早期的管道步骤(可能是因为积压工作中的元素数量太多),而不是触发窗口触发器以尽快激活后续步骤(和侧输入)。

您对触发频率和文件碎片数量的设置是什么?另外,您对BigQueryIO的修改是什么?(请注意,BigQuery BATCH_LOADS使用GroupByKey缓冲数据,并将X时间内的所有记录写入Y键,因此您需要确保X时间内处理的数据量除以Y文件适合单个计算机内存。)如果您能告诉我们Windmill.Message对象是在哪里分配的,这也会很有用。@LukaszCwik,首先我会回答您的问题。触发频率=3分钟;碎片=1。我试图总结正在加载的数据,使BigQueryIO.Write有点像sink+CombineFn的混合体。所以输入到BigQueryIO.Write是一个TableRow+CombineInput,来自BigQueryIO的输出是一个CombineResult(每个加载作业一个)。我还尝试过将Window(在500000或3分钟内触发)+WriteGroupedRecords更改为Window(每3分钟触发一次)+CombineFn(根据需要写入分组记录)。我保存了hprof文件,但提取有关Windmill.Messages的信息需要一些时间。与Windmill.Messages相比,我更关心的是Java进程使用了多少非Java堆内存。即使Java堆的分配少于50%(maxMemory>totalMemory*2),工作机也会因分页而变慢为爬行(SSHD需要10分钟的响应时间,因此很难连接到工作机,fluentd会及时停止向stackdriver发送日志)。最终,要么内核OOM杀手杀死Java,要么实例组管理器检测到响应能力不足,并重新启动一个新的工作者。但这需要一段时间(有时是一到两个小时)。我编辑了这个问题,并提供了更多细节。基本上,在我看来,RAM要求是无限制的,因为后面的步骤没有背压,而且触发器也不确定。我想我建议您提交一份支持票,以了解这些事情造成麻烦的原因:/