前言
- Hive:2.3.0
- Hadoop:2.7.7
- JDK:1.8.0_221
- Tez:0.9.1
报错一
报错内容:
在Hive下使用Tez引擎执行MR Job时报错:Container killed on request. Exit code is 143
问题分析:
从Container killed on request
这几个关键字就可以猜测,Container在非正常结束时被kill,很有可能就是Container使用的内存超出Container限制导致的。
查看Hive运行日志:
Hive的默认日志存放路径为${sys:java.io.tmpdir}/${sys:user.name}
,可以通过修改log4j日志框架配置文件hive/conf/hive-log4j2.properties
中的property.hive.log.dir
参数,自定义Hive日志文件输出路径。Hive日志默认按天进行滚动,property.hive.log.dir
下的hive.log
文件代表当天运行日志,带有后缀的代表之前某天的Hive运行日志文件。
通过日志定位问题:
通过查看Hive运行日志,发现了Application失败的诊断信息(Diagnostics),并根据Hive日志提供的app跟踪链接(本次日志中显示的是http://hadoop102:8088/cluster/app/application_1591155550718_0012),查看到了具体的诊断信息:
Diagnostics: Container [pid=35306,containerID=container_1591155550718_0012_02_000001] is running beyond virtual memory limits. Current usage: 244.1 MB of 1 GB physical memory used; 2.3 GB of 2.1 GB virtual memory used. Killing container.
由诊断信息可以得知,Container运行时超过了虚拟内存限制,故非正常终结kill了Container,故接下来首个尝试的优化方案就是调整Hadoop集群的虚拟内存相关参数
解决方案:
方案一:
解除YARN的虚拟内存检查,即不限制Container对于虚拟内存的使用,在yarn-site.xml配置文件的configuration标签中增加以下配置参数:
<!-- 是否限制Container对于虚拟内存的使用,即使超出预设的虚拟内存大小 -->
<property>
<name>yarn.nodemanager.vmem-check-enabled</name>
<value>false</value>
<description>
Whether virtual memory limits will be enforced for containers.
</description>
</property>
在yarn-site.xml配置文件中设置此参数,然后发往集群中所有节点,然后重启Hadoop集群
方案二:
既然是Container导致虚拟内存不足,故尝试增大虚拟内存,即增大虚拟内存与分配给Container的物理内存比例,在yarn-site.xml配置文件的configuration标签中设置以下参数,适当增大此比例:
<!-- 用于分配给Container的虚拟内存与物理内存的比例,
当物理内存不够用时,便会使用虚拟内存通过外部存储设备,代替部分物理内存使用. -->
<!-- 默认值:2.1 -->
<property>
<name>yarn.nodemanager.vmem-pmem-ratio</name>
<value>4</value>
<description>
Ratio between virtual memory to physical memory when
setting memory limits for containers. Container allocations are
expressed in terms of physical memory, and virtual memory usage
is allowed to exceed this allocation by this ratio.
</description>
</property>
在yarn-site.xml配置文件中设置此参数,然后发往集群中所有节点,然后重启Hadoop集群
方案三:
减少Tez Task的JVM堆内存分配,降低JVM堆内存与Container内存大小的比例,即在tez-size.xml文件中设置参数tez.container.max.java.heap.fraction
的值,此参数默认值为0.8,适当降低此值,然后重启Hive。
<property>
<name>tez.container.max.java.heap.fraction</name>
<value>0.2</value>
<description>
Double value. Tez automatically determines the Xmx for the JVMs used to run
Tez tasks and app masters. This feature is enabled if the user has not
specified Xmx or Xms values in the launch command opts. Doing automatic Xmx
calculation is preferred because Tez can determine the best value based on
actual allocation of memory to tasks the cluster. The value if used as a
fraction that is applied to the memory allocated Factor to size Xmx based
on container memory size. Value should be greater than 0 and less than 1.
Set this value to -1 to allow Tez to use different default max heap fraction
for different container memory size. Current policy is to use 0.7 for container
smaller than 4GB and use 0.8 for larger container.
如果没有设置 tez.am.launch.cmd-opts 参数,则便会使用此功能.
此参数设定Tez Job所能使用的JVM堆内存占整个Container内存大小的比例
如果YARN中的container内存资源较少,则将此值适当减小,反之则适当增大,默认值为0.8.
</description>
<type>float</type>
</property>
报错二:
在配置Tez成功之后,使用默认的MR执行Job时报错:
FAILED: Execution Error, return code -101 from org.apache.hadoop.hive.ql.exec.mr.MapRedTask. DEFAULT_MR_AM_ADMIN_USER_ENV
报错原因:
这是因为在配置Tez时,添加了tez的jar包路径到HADOOP_CLASSPATH
中,其中由于tez-0.9.1/lib
下存在几个hadoop依赖,而这些依赖与当前hadoop集群的版本不同,而导致版本冲突,故在Hive中使用MR引擎执行任务时,报出此错误
解决方案:
1)删除tez-0.9.1/lib
下的hadoop相关的jar包:
rm hadoop-mapreduce-client-core-2.7.0.jar
rm hadoop-mapreduce-client-common-2.7.0.jar
2)将集群中hadoop中的对应jar包复制添加到tez-0.9.1/lib
下(实测也可以不添加):
cp /opt/module/hadoop-2.7.7/share/hadoop/mapreduce/hadoop-mapreduce-client-core-2.7.7.jar /opt/module/tez-0.9.1/lib
cp /opt/module/hadoop-2.7.7/share/hadoop/mapreduce/hadoop-mapreduce-client-common-2.7.7.jar /opt/module/tez-0.9.1/lib
3)测试:
启动Hive CLI,关闭Hive自动本地模式,并运行测试命令
set hive.execution.engine=mr;
set hive.exec.mode.local.auto=false;
use test;
SELECT deptno, avg(sal) as avg_sal FROM emp group by deptno;