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

Posted

技术标签:

【中文标题】带有 tez 的 aws emr 上的 Pig 脚本偶尔会因 OutOfMemoryException 而失败【英文标题】:Pig script on aws emr with tez occasionally fails with OutOfMemoryException 【发布时间】:2018-01-25 07:34:51 【问题描述】:

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

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

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

UDF 将一些数据存储在Map&lt;Integer, Integer&gt;

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

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)

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

由于我是 amazon emr 的新手,并且是 tez 的新手,我希望能提供一些有关如何分析或调试问题的提示。

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

请注意,猪脚本正在使用

复制连接(要连接的较小关系需要适应内存)和 已经提到的 UDF,它正在初始化一个 Map&lt;Integer, Interger&gt;,产生上述的 OutOfMemoryError。

【问题讨论】:

【参考方案1】:

我们发现了另一种使用 tez 后端的解决方法。对mapreduce.map.memory.mbmapreduce.map.java.opts 使用增加的值(mapreduce.map.memory.mb 的0.8 倍)。这些值绑定到 ec2 实例类型并且通常是固定值(请参阅aws emr task config)。

通过(暂时)将值加倍,我们能够使 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 将数据刷新到存储中。这也有助于调试问题,因为可以使用其他猪脚本观察(临时、中间)数据。

【讨论】:

以上是关于带有 tez 的 aws emr 上的 Pig 脚本偶尔会因 OutOfMemoryException 而失败的主要内容,如果未能解决你的问题,请参考以下文章

Pig Script 上的多个 AWS 账户

在 AWS EMR 上使用 pig 的 Java 堆空间

使用 java.lang.NoClassDefFoundError 在 AWS EMR 上运行 Pig UDF:org/apache/pig/LoadFunc

正在寻找将 aws pig 步骤注入已经运行的 emr 的 boto3 python 示例?

如何在 Amazon EMR 上的 pig 中使用 Python 流 UDF

Pig 的“转储”在 AWS 上不起作用