带有 tez 的 aws emr 上的 Pig 脚本偶尔会因 OutOfMemoryException 而失败



我有一个使用自定义 UDF 在 emr 集群 (emr-5.4.0) 上运行的 pig 脚本。UDF 用于查找一些维度数据,它为其导入(有点)大量的文本数据。

在 pig 脚本中,UDF 的使用方式如下:

DEFINE LookupInteger com.ourcompany.LookupInteger(<some parameters>);

UDF 将一些数据存储在Map<Integer, Integer>

在某些输入数据上,聚合失败,出现如下异常

java.lang.OutOfMemoryError: GC overhead limit exceeded
at java.lang.String.split(String.java:2377)
at java.lang.String.split(String.java:2422)
[...]
at com.ourcompany.LocalFileUtil.toMap(LocalFileUtil.java:71)
at com.ourcompany.LookupInteger.exec(LookupInteger.java:46)
at com.ourcompany.LookupInteger.exec(LookupInteger.java:19)
at org.apache.pig.backend.hadoop.executionengine.physicalLayer.expressionOperators.POUserFunc.getNext(POUserFunc.java:330)
at org.apache.pig.backend.hadoop.executionengine.physicalLayer.expressionOperators.POUserFunc.getNextInteger(POUserFunc.java:379)
at org.apache.pig.backend.hadoop.executionengine.physicalLayer.PhysicalOperator.getNext(PhysicalOperator.java:347)
at org.apache.pig.backend.hadoop.executionengine.physicalLayer.expressionOperators.POBinCond.genericGetNext(POBinCond.java:76)
at org.apache.pig.backend.hadoop.executionengine.physicalLayer.expressionOperators.POBinCond.getNextInteger(POBinCond.java:118)
at org.apache.pig.backend.hadoop.executionengine.physicalLayer.PhysicalOperator.getNext(PhysicalOperator.java:347)

当使用mapreduce运行猪聚合时不会发生这种情况,因此我们的解决方法是将pig -t tez替换为pig -t mapreduce

由于我是亚马逊 emr 的新手,并且是带有 tez 的猪,我希望获得有关如何分析或调试问题的一些提示。

编辑:在 tez 堆栈上运行 pig 脚本时,它看起来像一个奇怪的运行时行为。

请注意,猪脚本使用的是

  • 复制联接(要联接的较小关系需要适合内存)和
  • 已经提到的UDF,它正在初始化一个Map<Integer, Interger>,产生上述的OutOfMemoryError。

我们找到了另一种使用 tez 后端的解决方法。使用增加的mapreduce.map.memory.mbmapreduce.map.java.opts值(mapreduce.map.memory.mb的 0.8 倍)。这些值绑定到 ec2 实例类型,通常是固定值(请参阅 aws emr 任务配置)。

通过(暂时)将值加倍,我们能够使 pig 脚本成功。

为 m3.xlarge 核心实例设置了以下值,该实例具有默认值:

  • mapreduce.map.java.opts := -Xmx1152m
  • mapreduce.map.memory.mb := 1440

猪启动命令

pig -Dmapreduce.map.java.opts=-Xmx2304m 
-Dmapreduce.map.memory.mb=2880 -stop_on_failure -x tez ... script.pig

编辑

一位同事提出了以下想法:

OutOfMemory: GC overhead limit exceeded的另一种解决方法可能是为有问题的关系添加显式STORELOAD语句,这将使 tez 将数据刷新到存储。这也有助于调试问题,因为可以使用其他 pig 脚本观察(临时、中间)数据。

相关内容

最新更新