82.Hive SQL插入动态分区的异常分析
作者:互联网
82.1 问题情况
INSERT … SELECT语句向Parquet或者ORC格式的表中插入数据时,启用了动态分区,无法正常执行
Hive客户端:
Task with the most failures(4):
Diagnostic Messages for this Task:
Error: GC overhead limit exceeded
...
FAILED: Execution Error, return code 2 from org.apache.hadoop.hive.ql.exec.mr.MapRedTask
MapReduce Jobs Launched:
Stage-Stage-1: Map: 1 HDFS Read: 0 HDFS Write: 0 FAIL
Total MapReduce CPU Time Spent: 0 msec
YARN的8088中查看具体map task报错:
2017-10-27 17:08:04,317 FATAL [main] org.apache.hadoop.mapred.YarnChild: Error running child : java.lang.OutOfMemoryError: GC overhead limit exceeded
82.2 解决方法
方法一:启用hive.optimize.sort.dynamic.partition,将其设置为true
- 这种优化方式在写parquet文件时使用的内存要相对少一些,但代价是要对分区字段进行排序
- 这个优化只有map任务的mapreduce会引入reduce过程,这样动态分区的那个字段比如日期在传到reducer时会被排序
- 由于分区字段是排序的,因此每个reducer只需要保持一个文件写入器(file writer)随时处于打开状态,在收到来自特定分区的所有行后,关闭记录写入器(record writer),从而减小内存压力
SET hive.optimize.sort.dynamic.partition=true;
INSERT OVERWRITE TABLE [table] SELECT ...
方法二:增加每个mapper的内存分配,即增大mapreduce.map.memory.mb和mapreduce.map.java.opts,这样所有文件写入器(filewriter)缓冲区对应的内存会更充沛
方法三:将查询分解为几个较小的查询,以减少每个查询创建的分区数量
- Hive为每个打开的Parquet文件缓冲区(file buffer)分配128MB
- 这个buffer大小由参数parquet.block.size控制
- 最佳性能,parquet的buffer size需要与HDFS的block size保持对齐(比如相等),从而使每个parquet文件在单个HDFS的块中,以便每个I/O请求都可以读取整个数据文件,而无需通过网络传输访问后续的block
-- set Parquetbuffer size to 256MB (in bytes)
set parquet.block.size=268435456;
生成动态分区的一些参数说明
hive.exec.dynamic.partition
## 默认值:false
## 是否开启动态分区功能,默认false关闭
## 使用动态分区时候,该参数必须设置成true
mapreduce.input.fileinputformat.split.maxsize
mapreduce.input.fileinputformat.split.minsize
## 这个两个参数联合起来用,主要是为了方便控制mapreduce的map数量
## 比如设置为1073741824,就是为了让每个map处理1GB的文件
mapreduce.map.java.opts
## map任务的Java堆栈大小设置,一般设置为小于等于上面那个值的75%,这样可以保证map任务有足够的堆栈外内存空间
mapreduce.map.memory.mb
## map任务的物理内存分配值,常见设置为1GB,2GB,4GB等
hive.exec.max.created.files
## 默认值:100000
## 整个MR Job中,最大可以创建多少个HDFS文件
## 一般默认值足够了,除非你的数据量非常大,需要创建的文件数大于100000,可根据实际情况加以调整
hive.exec.max.dynamic.partitions
## 默认值:1000
## 在所有执行MR的节点上,最大一共可以创建多少个动态分区
hive.exec.max.dynamic.partitions.pernode
## 默认值:100
## 在每个执行MR的节点上,最大可以创建多少个动态分区
## 该参数需要根据实际的数据来设定
## 比如:源数据中包含了一年的数据,即day字段有365个值,那么该参数就需要设置成大于365,如果使用默认值100,则会报错
hive.exec.dynamic.partition.mode
## 默认值:strict
## 动态分区的模式,默认strict,表示必须指定至少一个分区为静态分区,nonstrict模式表示允许所有的分区字段都可以使用动态分区
## 一般需要设置为nonstrict
大数据视频推荐:
CSDN
大数据语音推荐:
企业级大数据技术应用
大数据机器学习案例之推荐系统
自然语言处理
大数据基础
人工智能:深度学习入门到精通
标签:map,##,分区,mapreduce,Hive,hive,SQL,82,默认值 来源: https://blog.csdn.net/m0_47454596/article/details/122131397