猪本地模式、分组或连接=java.lang.OutOfMemoryError: Java堆空间不足

6

使用Apache Pig版本0.10.1.21(报告的版本号),CentOS 6.3(最终版本),jdk1.6.0_31(基于Virtualbox的Hortonworks Sandbox v1.2,配备3.5 GB RAM)。

$ cat data.txt
11,11,22
33,34,35
47,0,21
33,6,51
56,6,11
11,25,67

$ cat GrpTest.pig
A = LOAD 'data.txt' USING PigStorage(',') AS (f1:int,f2:int,f3:int);
B = GROUP A BY f1;
DESCRIBE B;
DUMP B;

pig -x local GrpTest.pig

[Thread-12] WARN  org.apache.hadoop.mapred.JobClient - No job jar file set.  User classes may not be found. See JobConf(Class) or JobConf#setJar(String).
[Thread-12] INFO  org.apache.hadoop.mapreduce.lib.input.FileInputFormat - Total input paths to process : 1
[Thread-13] INFO  org.apache.hadoop.mapred.Task -  Using ResourceCalculatorPlugin : org.apache.hadoop.util.LinuxResourceCalculatorPlugin@19a9bea3
[Thread-13] INFO  org.apache.hadoop.mapred.MapTask - io.sort.mb = 100
[Thread-13] WARN  org.apache.hadoop.mapred.LocalJobRunner - job_local_0002
java.lang.OutOfMemoryError: Java heap space
    at org.apache.hadoop.mapred.MapTask$MapOutputBuffer.<init>(MapTask.java:949)
    at org.apache.hadoop.mapred.MapTask$NewOutputCollector.<init>(MapTask.java:674)
    at org.apache.hadoop.mapred.MapTask.runNewMapper(MapTask.java:756)
    at org.apache.hadoop.mapred.MapTask.run(MapTask.java:370)
    at org.apache.hadoop.mapred.LocalJobRunner$Job.run(LocalJobRunner.java:212)
[main] ERROR org.apache.pig.tools.pigstats.PigStatsUtil - 1 map reduce job(s) failed!
[main] ERROR org.apache.pig.tools.grunt.Grunt - ERROR 1066: Unable to open iterator for alias B
java.lang.OutOfMemoryError: Java heap space错误会在我在本地模式下执行pig脚本时使用GROUP或JOIN时发生。当在HDFS上的mapreduce模式下执行脚本时,不会出现错误。问题1:为什么数据样本很小而且本地模式应该比HDFS模式使用更少的资源,但还是会出现内存溢出错误?问题2:是否有解决方案可以在本地模式下成功运行带有GROUP或JOIN的小型pig脚本?

我在本地MapReduce模式下进行分组或连接时从未遇到过任何问题,即使是在非常大的数据集上... 我想象你的JVM设置出了问题,或者你的本地pig/hadoop设置了某种允许最大内存为0的限制。你确定只有GROUP和JOIN在本地失败吗?如果你为一个非pig相关的Java程序使用大量内存会发生什么? - DMulligan
嗨,这是Hortonworks沙盒。当我通过GUI连接时(Hortons HUE GUI允许在同一沙盒上的Web浏览器上运行Pig、Hive),所有演示都可以完美运行,即使使用更大的数据集(10 MB)。因此,我认为JVM可以处理更大的负载。这显然是本地模式中的一个错误。只要涉及GROUP或JOIN,无论数据样本大小、Grunt shell还是Pig Script,Pig都会失败并显示java OutOfMemory错误。 - Polymerase
我不知道Hortonworks的任何信息,但如果你在本地使用DISTINCT查询是否可以正常工作?有一堆与Hadoop/pig相关的设置,用于允许洗牌、排序、连接等操作的最大内存。我的猜测仍然是其中一个设置为0。 - DMulligan
对于那些在查找ERROR 1066: Unable to open iterator for alias时发现了这篇文章的人,这里有一个通用解决方案 - Dennis Jaheruddin
2个回答

20
解决方案:强制pig为Java属性io.sort.mb分配更少的内存。我在这里设置了10 MB,错误消失了。不确定最佳值是多少,但至少在本地模式下可以练习pig语法。
$ cat GrpTest.pig
--avoid java.lang.OutOfMemoryError: Java heap space (execmode: -x local)
set io.sort.mb 10;

A = LOAD 'data.txt' USING PigStorage(',') AS (f1:int,f2:int,f3:int);
B = GROUP A BY f1;
DESCRIBE B;
DUMP B;

我可以在MR模式下保留set io.sort.mb 10;吗?还是应该将其删除? - Rajuk

0

原因是你本地分配给Java的内存比Hadoop集群机器上的少。这在Hadoop中实际上是一个非常常见的错误。当你在Pig中创建一个非常长的关系时,它通常会发生,因为Pig总是想要将一个完整的关系加载到内存中,并且不想以任何方式进行延迟加载。

当你执行像GROUP BY这样的操作时,你正在对许多记录进行非稀疏元组分组,因此你经常会暂时创建单个长关系,因为你基本上正在将许多单个关系全部塞进一个单个长关系中。要么更改你的代码,使你不会在任何时候创建单个非常长的关系(即按更稀疏的内容进行分组),要么增加Java可用的内存。


1
请看一下我的初始帖子。示例中使用的数据总大小不到100字节。换句话说,比这个评论的长度还要短。无论底层管道的智能程度如何,当绝对没有内存问题时,它失败了OutOfMemory是没有任何借口的。这显然是一个错误。 - Polymerase

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接