Hive 动态分区插入数据总结

12 篇文章 2 订阅
8 篇文章 1 订阅

Hive 动态分区插入数据总结

1、问题描述

执行以下sql导致reduce端OOM,分区数有485个按天分区,数据主要是存量数据一次性导入数仓中遇到的问题。

服务器 :8核12G内存

Map内存参数值:

mapreduce.map.memory.mb=1024

mapreduce.map.java.opts=-Xmx768m -XX:+UseConcMarkSweepGC;

Reduce内存参数值:

mapreduce.reduce.memory.mb=2048

mapreduce.reduce.java.opts=-Xmx1536m -XX:+UseConcMarkSweepGC;

 

Sql语句:

 

分区是按照天分区:

 

使用以下SQL语句从ods层动态分区插入到dwd层,因为从数据库存量数据一次性抽取,数据量大概3w多,总的分区数在578个,在以上配置即使加大map以及reduce的内存,还是会抛OOM(以测试过)。

所以先抽取部分分区数据做优化测试,选取100多个不到120个分区数,sql如下:

报OOM截图:

 

 

由后台日志看出,4个reduce都是内存溢出。(100多个分区,调大reduce内存是可以解决的)

 

 

导致reduce端处理的每个分区数都产生了大量的recordWriter文件写入器。FileSinkOperator: New Final Path导致内存中保存太多句柄和数据,导致OOM或者内存超被Yarn Kill。

  1. 异常分析

Parquet和ORC都是列式批处理文件格式,这些文件格式要求在写入文件之前将批次的行(batches of rows)缓存在内存中。在执行insert语句时,动态分区目前的实现是:至少为每个动态分区目录打开一个文件写入器(file writer)。由于这些缓冲区是按分区维护的,因此运行时所需的内存量随着分区数量的增加而增加。所以经常导致mappers或者reduces的OOM,具体取决于打开的文件写入器(file writer)的数量。

通过INSERT语句插入数据到动态分区表中,也可能会超过HDFS同时打开文件数的限制。

使用参数hive.exec.max.created.files 来控制最大创建的HDFS文件数,默认是100000。

如果没有join或者聚合操作,INSERT ....SELECT * FROM TABLE语句会被转换为只有map任务的作业。Mapper任务会读取输入记录然后将它们发送到目标分区目录。在这种情况下,每个mapper必须为遇到的每个动态分区创建一个新的文件写入器(file writer)。Mapper在运行时所需的内存量随着它遇到的分区数量的增加而增加。

  1. 问题解决方式

对sql进行优化

如果sql已经是最优状态

对map、reduce阶段进行调优,内存或者其他等等

如果内存够用、够大,则尝试调整以下两个参数让文件写入器(filewriter)缓冲区对应的内存会更充沛能解决问题。

mapreduce.map.memory.mb=4096

mapreduce.map.java.opts=-Xmx(4096*0.8) -XX:+UseConcMarkSweepGC;

mapreduce.reduce.memory.mb=8192

mapreduce.reduce.java.opts=-Xmx6553m -XX:+UseConcMarkSweepGC;

2.1 改变分区规则

第一种:因为每天的数据量不过千,可以以月份作为分区规则,按月分区的话,那么存量的数据动态分区插入则分区数明显很少,则执行成功。

第二种:按天分区,将存量的数据截至到今天的数据按量划分多个分区,如果数据量不大,就可以直接指定今天的日期作为分区。

比如:将存量的数据按照某个时间划分,将去年以前的数据统一规划到2020-09-18作为一个分区。

例如sql如下:

insert overwrite table lobehaviour_trade_daily partition (part) 
select dp_id, buyer_nick, to_date(created), payment, 0 as item, if(to_date(modified)<'2012-01-01','2012-01-01',to_date(modified)) as part
from taobao.s_trade_hbase 
where (part<'2013-10-30' or part='STABLE') and status='TRADE_FINISHED'
distribute by part;

 

2.2 采用distribute by分区字段

1.全表去重到中间表 时 distribute by   分区字段,这样就可以 将相同分区的数据放到同一个文件中 用时 15 分钟

 2.新处理过的中间表 动态分区至原表。

 

这种distribute by(列名)这种分区决定了reduce数,reduce数决定了文件数,虽然可以减少文件数,但是会导致数据倾斜的产生。

distribute by如同parititon分区,map端数据按照某个字段或者rand()随机数进行hash算法分发到各个分区中,有助于缓解数据倾斜问题,将数据均匀的分布到各个reduce中。

 

采用distribute by rand()测试下结果:还是报OOM。

2.3 hive.optimize.sort.dynamic.partition

针对上面的解决方式还是抛出OOM,查看了官方文档,有这个参数:官方翻译:启用该值时,动态分区列将被全局排序。这样就可以为reduce中的每个分区值只打开一个文件写入器(file writer),从而极大的减少reducer的内存压力。

在hive 0.13版本中加入并默认为true,hive0.14后默认为false,如果为true 的话,只为每个分区产生一个文件写入器,可以解决动态分区插入时的OOM问题,但会严重降低reducer处理写入一个分区的速度。

需要根据综合业务考虑是否开启,一般数据量不大的情况下,保持默认值。

本问题直接开启,问题完美解决。

  1. 涉及到的参数调优

4.1 hive.exec.dynamic.partition

默认值:false,是否开启动态分区功能,使用动态分区时,必须开启

4.2 hive.exec.dynamic.partition.mode

默认值:strict,动态分区模式,表示必须指定一个分区为静态分区,nonstrict模式表示允许所有的分区字段都可以使用动态分区。

4.3 hive.exec.max.dynamic.partitions.pernode

默认值:1000,在每个执行mr的节点上,最大可以创建的动态分区。

4.4 hive.exec.max.dynamic.partitions

默认值:1000,在所有执行mr的节点上,最大一共可创建的动态分区数。

4.5 hive.exec.max.created.files

默认值:100000,整个mr job中,最大可以创建多少个HDFS文件。

4.6 mapreduce.map.memory.mb

map任务的物理内存分配值,常见设置1G\2G\4G

4.7 mapreduce.map.java.opts

Map任务的java堆栈大小设置,一般设置为小于等于mapreduce.map.memory.mb的80%,可以保证map任务有足够的堆栈外内存空间。

4.8 mapreduce.reduce.memory.mb

reduce任务的物理内存分配值,常见为map任务分配值的2倍。

4.9 mapreduce.reduce.java.opts

同map任务分配的堆栈方式,80%

5.0 mapreduce.input.fileinputformat.split.maxsize、mapreduce.input.fileinputformat.split.minsize

Maxsize默认:256M主要是为了方便控制mapreduce的map数量,降低max值,则map数量就越多,max越大,map数量越少。

5.1 hive.optimize.sort.dynamic.partition

默认值:false,动态分区时,只为reduce产生一个文件写入器,从而减少reduce端的内存压力。

参考博文:https://blog.csdn.net/lzw2016/article/details/97818080

https://www.it1352.com/859957.html

https://docs.microsoft.com/zh-cn/archive/blogs/shanyu/hadoop-yarn-memory-settings-in-hdinsight

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值