HIVE MapJoin异常问题处理总结

本文涉及的产品
EMR Serverless StarRocks,5000CU*H 48000GB*H
简介: HIVE被很广泛的使用,使用过程中也会遇到各种千奇百怪的问题。这里就遇到的MapJoin Local 内存不足的问题进行讨论,从问题描述、mapjion原理以及产生该问题的原因,解决方案做一下介绍,最后对该问题进行了进一步的思考,希望对解决该类问题的朋友有所帮助。

问题描述

在跑hive作业的时候,偶尔会遇到下面的异常 FAILED: Execution Error, return code 3 from org.apache.hadoop.hive.ql.exec.mr.MapredLocalTask 。通过查看日志,你可以看到这是map join的问题,会看到Starting to launch local task to process map join; maximum memory = xxx,Execution failed with exit status: 3 等等这样的日志。在网上搜索也可以看到一些问题的解释,例如 stackoverflow上就有一个 http://stackoverflow.com/questions/22977790/hive-query-execution-error-return-code-3-from-mapredlocaltask

搜索结果建议的解决方案

    1. set hive.auto.convert.join = false; 关闭mapjion
    1. 调小hive.smalltable.filesize,默认是25000000(在2.0.0版本中)
    1. hive.mapjoin.localtask.max.memory.usage 调大到0.999
    1. set hive.ignore.mapjoin.hint=false; 关闭忽略mapjoin的hints

原理及问题分析

MapJoin原理可以参见这里,讲的比较清楚。出现问题的地方就是MapredLocalTask这里,在客户端本地启动一个Driver进程,扫描小表的数据,将其转换成一个HashTable的数据结构,这个过程中在做内存检查,即checkMemoryStatus的时候,抛出了异常。我们看一下这里的检查点

    double percentage = (double) usedMemory / (double) maxHeapSize;
    String msg = Utilities.now() + "\tProcessing rows:\t" + numRows + "\tHashtable size:\t"
        + tableContainerSize + "\tMemory usage:\t" + usedMemory + "\tpercentage:\t" + percentageNumberFormat.format(percentage);
    console.printInfo(msg);
    if(percentage > maxMemoryUsage) {
      throw new MapJoinMemoryExhaustionException(msg);
    }

跟当前进程的MaxHeap有关,跟当前进程的UsedMemory有关,跟参数maxMemoryUsage有关(hive.mapjoin.localtask.max.memory.usage),通过分析比较我们可以发现,上述的方案1和4,直接关闭mapjion,避免启动MapredLocalTask,就不会出现这样的check,进而不会出现问题;上述的方案2,减小join表的大小,进而减小UsedMemory,也可以解决这个问题;上面的方案3, 调大maxMemoryUsage,使内存充分利用,也可以解决这个问题。我们注意到maxHeapSize 这个参数,没有针对性的解决方案

增加的一种解决方案,调大MapredLocalTask JVM启动参数

解决方案还是需要考虑不影响性能。
调大MapredLocalTask 的JVM启动参数,进而可以增加maxHeapSize,同样也可以解决这个问题。如何去调大这个参数呢?通过查看MapredLocalTask代码我们可以看到

      jarCmd = hiveJar + " " + ExecDriver.class.getName();
      String hiveConfArgs = ExecDriver.generateCmdLine(conf, ctx);
      String cmdLine = hadoopExec + " jar " + jarCmd + " -localtask -plan " + planPath.toString()
          + " " + isSilent + " " + hiveConfArgs;
      ...
      Map<String, String> variables = new HashMap<String, String>(System.getenv());
      ...
      // Run ExecDriver in another JVM
      executor = Runtime.getRuntime().exec(cmdLine, env, new File(workDir));

启动新的ExecDriver,使用的是hadoop jar,系统环境参数继承了父进程的系统环境变量(里面逻辑有一些参数会覆盖)。而hadoop jar 启动java进程,内存参数会受哪些地方影响呢?如果没有设置,受hadoop自身一些脚本配置的影响;HADOOP_HEAPSIZE,如果设置了该变量,JVM参数就是-Xmx${HADOOP_HEAPSIZE}m ;如果不设置 ,就会受/usr/lib/hadoop-current/libexec/hadoop-config.sh里面配置的JAVA_HEAP_MAX=-Xmx1000m 。有没有印象?你使用hadoop jar启动的一些进程参数都是-Xmx1000m, 如果注意观察,ExecDriver这个进程也是这个参数。知道这个参数之后,可以在/usr/lib/hadoop-current/libexec/hadoop-config.sh 这里将参数调大,例如设置JAVA_HEAP_MAX=-Xmx1408m 可以解决问题。

研究与思考

通过查看checkMemoryStatus 的代码,我们可以看到,这个比较的逻辑不太合适,当前内存使用达到了一定阈值,并不代表内存不够用,因为还有gc存在啊,如果gc之后还是超过了这个阈值,确实需要抛出异常。基于这样的分析,在HIVE JIRA上提了一个issue 并有相应的一些想法和patch。如果感兴趣,欢迎讨论交流,请戳HIVE-15221

相关实践学习
基于EMR Serverless StarRocks一键玩转世界杯
基于StarRocks构建极速统一OLAP平台
快速掌握阿里云 E-MapReduce
E-MapReduce 是构建于阿里云 ECS 弹性虚拟机之上,利用开源大数据生态系统,包括 Hadoop、Spark、HBase,为用户提供集群、作业、数据等管理的一站式大数据处理分析服务。 本课程主要介绍阿里云 E-MapReduce 的使用方法。
相关文章
|
7月前
|
SQL 分布式计算 关系型数据库
使用 Spark 抽取 MySQL 数据到 Hive 时某列字段值出现异常(字段错位)
在 MySQL 的 `order_info` 表中,包含 `order_id` 等5个字段,主要存储订单信息。执行按 `create_time` 降序的查询,显示了部分结果。在 Hive 中复制此表结构时,所有字段除 `order_id` 外设为 `string` 类型,并添加了 `etl_date` 分区字段。然而,由于使用逗号作为字段分隔符,当 `address` 字段含逗号时,数据写入 Hive 出现错位,导致 `create_time` 值变为中文字符串。问题解决方法包括更换字段分隔符或使用 Hive 默认分隔符 `\u0001`。此案例提醒在建表时需谨慎选择字段分隔符。
152 6
|
SQL 分布式计算 Java
sqoop to hive GC overhead limit exceeded 大表抽取到hive中发生异常
如果你已经试过了别的博客提供的修改内存的方法,但是美效果的话,不妨看看我的解决办法。 为什么Sqoop Import抛出这个异常?
269 0
|
SQL Java Apache
hive_异常_01_hive启动异常-Role admin already exists(未解决)
一、异常信息 hive安装成功之后,执行hive命令时,控制台正常,但是通过命令: hive -hiveconf hive.root.logger=DEBUG,console;   去查看日志时,却发现出现报如下异常: 18/03/26 18:18:29 [main]: DEBUG metastore.
2943 0
|
SQL Java Apache
hive_异常_01_(未解决)FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask. org.apache.hadoop.hbase.HTableDescriptor.addFamily
一、异常现象 单独的 hadoop、hbase 、hive 都是正常的,但是在 hive 整合hbase 时,在 hive中输入以下建表语句, CREATE TABLE hbase_table_1(key int, value string) STORED BY 'org.
4652 0
|
SQL 分布式计算 监控
hive在E-MapReduce集群的实践(一)hive异常排查入门
hive是hadoop集群最常用的数据分析工具,只要运行sql就可以分析海量数据。初学者在使用hive时,经常会遇到各种问题,不知道该怎么解决。 本文是hive实践系列的第一篇,以E-MapReduce集群环境为例,介绍常见的hive执行异常,定位和解决方法,以及hive日志查看方法。
6951 0
|
SQL Java 关系型数据库
hive_异常_01_ Terminal initialization failed; falling back to unsupported
一、异常现象 hive初始化数据库时,在执行了 schematool -initSchema -dbType mysql 这个命令时,终端抛出如下异常: [ray@rayner bin]$ schematool -initSchema -dbType mysql Met...
1956 0
|
SQL HIVE
hive 异常 (Attempt to do update or delete on table terminal that does not use an )
    hive 异常 (Attempt to do update or delete on table terminal that does not use an )   hive > delete from terminal where 1=1 ;  出现以下    ...
2298 0
|
SQL HIVE
FAILED: Hive Internal Error: java.lang.RuntimeException(Error while making MR scratch directory异常的解决
<div style="color:rgb(51,51,51); font-family:Arial; font-size:14px; line-height:26px"> hive&gt; select * from dummy;</div> <div style="color:rgb(51,51,51); font-family:Arial; font-size:14px; lin
1632 0