Hive 配置单元映射联接:内存不足异常

Hive 配置单元映射联接:内存不足异常,hive,mapreduce,Hive,Mapreduce,我正在尝试使用一个大表(10G)和一个小表(230MB)执行map-side。在连接关键列之后,我将使用所有列生成输出记录 我使用了下面的设置 设置hive.auto.convert.join=true 设置hive.mapjoin.smalltable.filesize=262144000 日志: **2013-09-20 02:43:50 Starting to launch local task to process map join; maximum mem

我正在尝试使用一个大表(10G)和一个小表(230MB)执行map-side。在连接关键列之后,我将使用所有列生成输出记录

我使用了下面的设置

设置hive.auto.convert.join=true

设置hive.mapjoin.smalltable.filesize=262144000

日志:

**2013-09-20 02:43:50     Starting to launch local task to process map join;      maximum       memory = 1065484288

2013-09-20 02:44:05     Processing rows:        200000  Hashtable size: 199999  Memory usage:   430269904       rate:0.404

2013-09-20 02:44:14     Processing rows:        300000  Hashtable size: 299999  Memory usage:   643070664       rate:0.604

Exception in thread "Thread-0" java.lang.OutOfMemoryError: Java heap space
        at java.util.jar.Manifest$FastInputStream.<init>(Manifest.java:313)
        at java.util.jar.Manifest$FastInputStream.<init>(Manifest.java:308)
        at java.util.jar.Manifest.read(Manifest.java:176)
        at java.util.jar.Manifest.<init>(Manifest.java:50)
        at java.util.jar.JarFile.getManifestFromReference(JarFile.java:168)
        at java.util.jar.JarFile.getManifest(JarFile.java:149)
        at sun.misc.URLClassPath$JarLoader$2.getManifest(URLClassPath.java:696)
        at java.net.URLClassLoader.defineClass(URLClassLoader.java:228)
        at java.net.URLClassLoader.access$000(URLClassLoader.java:58)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:197)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
        at org.apache.hadoop.util.RunJar$1.run(RunJar.java:126)
Execution failed with exit status: 3
Obtaining error information
Task failed!
Task ID:
  Stage-7
Logs:
FAILED: Execution Error, return code 3 from org.apache.hadoop.hive.ql.exec.MapredLocalTask
ATTEMPT: Execute BackupTask: org.apache.hadoop.hive.ql.exec.MapRedTask**
**2013-09-20 02:43:50开始启动本地任务以处理映射加入;最大内存=1065484288
2013-09-20 02:44:05处理行数:200000哈希表大小:199999内存使用率:430269904速率:0.404
2013-09-20 02:44:14处理行数:300000哈希表大小:299999内存使用率:643070664速率:0.604
线程“thread-0”java.lang.OutOfMemoryError中出现异常:java堆空间
位于java.util.jar.Manifest$FastInputStream。(Manifest.java:313)
位于java.util.jar.Manifest$FastInputStream。(Manifest.java:308)
位于java.util.jar.Manifest.read(Manifest.java:176)
位于java.util.jar.Manifest。(Manifest.java:50)
位于java.util.jar.JarFile.getManifestFromReference(JarFile.java:168)
位于java.util.jar.JarFile.getManifest(JarFile.java:149)
位于sun.misc.URLClassPath$JarLoader$2.getManifest(URLClassPath.java:696)
位于java.net.URLClassLoader.defineClass(URLClassLoader.java:228)
在java.net.URLClassLoader.access$000(URLClassLoader.java:58)
在java.net.URLClassLoader$1.run(URLClassLoader.java:197)
位于java.security.AccessController.doPrivileged(本机方法)
位于java.net.URLClassLoader.findClass(URLClassLoader.java:190)
位于java.lang.ClassLoader.loadClass(ClassLoader.java:306)
位于sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
位于java.lang.ClassLoader.loadClass(ClassLoader.java:247)
位于org.apache.hadoop.util.RunJar$1.run(RunJar.java:126)
执行失败,退出状态:3
获取错误信息
任务失败!
任务ID:
第7阶段
日志:
失败:执行错误,从org.apache.hadoop.hive.ql.exec.MapredLocalTask返回代码3
尝试:执行备份任务:org.apache.hadoop.hive.ql.exec.MapRedTask**
但我仍然面临OOM异常,集群中设置的堆大小是1GB。 请协助我需要考虑哪些属性并调整以使该地图侧加入工作

处理行:300000哈希表大小:299999内存使用率:643070664速率:0.604

在300k行时,HT已经使用了堆的60%。要问的第一个问题:您确定表顺序正确吗?联接中的小表真的是数据中的小表吗?编写查询时,大表应该是JOIN子句中的最后一个。您在0.9或0.11上使用哪个配置单元版本


如果您在配置单元0.11上并且正确指定了连接,那么首先要尝试增加堆大小。从上面的数据(300k行~>650Mb堆)可以计算出需要多少堆。

我遇到了这个问题,只能通过使用
设置hive.auto.convert.join=false
设置hive.auto.convert.join=false
它不会给你内存异常

set hive.auto.convert.join = false;

它不会给你一个内存异常,因为它没有使用mapside连接。它使用的是普通的mapreduce任务本身。

您应该考虑到这一点,尤其是当使用压缩方式存储表时,表的大小可能不会太大,但当解压时,表的大小可能会增加10倍或更多,除此之外,在哈希表中表示数据会占用更多的空间。因此,您的表可能小于~260MB,这是您为hive.mapjoin.smalltable.filesize设置的值,但其解压缩版本的哈希表表示可能不小于此值,这就是为什么hive尝试在内存中加载表,最终导致OutOfMemoryError异常的原因。 根据:
“不需要检查表是否是压缩表以及表的潜在大小。”

感谢Remus的回复,我不明白一件事,小表的大小为230 mb,包含约900K条记录。为什么需要650MB/300k行。Java哈希表表示中存在大量开销。请参阅hive.mapjoin.followby.gby.localtask.max.memory.usage的默认值。在作业失败的情况下,usage为0.55(对于Group by,为0.90,对于非Group by),看起来就像它达到60.4%时一样。尽管您的答案在某些情况下可能会有所帮助,但我认为在这种情况下,join中表的顺序并不重要。Hive选择较小的一个加载到它帮助的内存库中:)