HIVE调优-数据倾斜优化(详细版)

avatar
作者
猴君
阅读量:2

HIVE调优-数据倾斜优化

目录

HIVE调优-数据倾斜优化

1.排序优化

1)order by 

2)distribute by + sort by 

3)cluster by语句:

2.数据倾斜优化

1)原因:

2)表现:

3)创建表格(查看一下具体效果)

4) 如果想展示数据倾斜效果:

5) 解决方法:



1.排序优化


1)order by 


                全局排序操作, 只有一个Reduce任务去对数据进行排序,会造成全部的数据堆积在一个Reduce任务中进行处理
                    经常会出现OOM异常? 一个Reduce任务的内存是有限的,承载不了太多数据

2)distribute by + sort by 


                distribute by:是指我们的分区操作
                sort by: 跟上distribute by 之后可以实现在分区内进行排序,
                如果当前的Reduce数量为1,那么也没有优化的效果,可以通过设置reduce的数量对不同分区中的数据进行拆分排序
                 通过 set mapreduce.job.reduces = N; 设置Reduce数量,默认参数值为-1 即根据资源及查询语句情况进行分配reduce,

3)cluster by语句:


                如果分区字段和排序字段是同一个字段,那么和 distribute by + sort by 效果一致

2.数据倾斜优化


1)原因:


                1.Key分布不均,导致某一些Key在做Reduce端处理时,执行较慢
                2.数据重复,在关联时,会产生笛卡尔积,致使数据膨胀,严重的可能会导致集群挂掉 
            

2)表现:


                任务进度长时间维持在99%(或100%),
                查看任务监控页面,发现只有少量(1个或几个)reduce子任务未完成。因为其处理的数据量和其他reduce差异过大
 

3)创建表格(查看一下具体效果)

1.创建带有部分NULL的学生表和成绩表

  1.创建带有部分NULL的学生表和成绩表  DROP TABLE learn4.student_null; CREATE EXTERNAL TABLE IF NOT EXISTS learn4.student_null( id STRING COMMENT "学生ID", name STRING COMMENT "学生姓名", age int COMMENT "年龄", gender STRING COMMENT "性别", clazz STRING COMMENT "班级" ) ROW FORMAT DELIMITED FIELDS TERMINATED BY ",";  load data local inpath "/usr/local/soft/hive-3.1.2/data/student_null.txt" INTO TABLE learn4.student_null;  DROP TABLE learn4.score_null; CREATE EXTERNAL TABLE IF NOT EXISTS learn4.score_null( id STRING COMMENT "学生ID", subject_id STRING COMMENT "科目ID", score int COMMENT "成绩" ) ROW FORMAT DELIMITED FIELDS TERMINATED BY ",";  load data local inpath "/usr/local/soft/hive-3.1.2/data/score_null.txt" INTO TABLE learn4.score_null;   select * from learn4.student_null limit 10; select * from learn4.score_null limit 10; 

2.大空表与小空表进行关联
 

设置reduces =5  set mapreduce.job.reduces = 5;

SELECT T1.id ,count(*) as num FROM learn4.student_null T1 JOIN learn4.score_null T2 ON T1.id = T2.id  GROUP BY T1.id; 

我们打开master:8088  找到我们刚刚执行的命令 点击history 发现是打不开的

所以我们需要去配置一下日志文件

配置文件 vim mapred-site.xml     <property>       <name>mapreduce.jobhistory.done-dir</name>     <value>${yarn.app.mapreduce.am.staging-dir}/done</value> </property>  <property>         <name>mapreduce.jobhistory.intermediate-done-dir</name>         <value>${yarn.app.mapreduce.am.staging-dir}/done_intermediate</value> </property>  <property>         <name>yarn.app.mapreduce.am.staging-dir</name>         <value>/hadoop/yarn/historylog</value> </property>   hdfs dfs -mkdir -p /hadoop/yarn/historylog  # 启动历史服务 mr-jobhistory-daemon.sh start historyserver

4) 如果想展示数据倾斜效果:


    1.保证两张表的数据相差不大
    2.可以关闭MapJOIN优化,防止执行MapJOIN流程

--查看具体的偏差的结果可以去 Reduce Tasks for job 历史中查看
-- 可以得到结论:数据倾斜之后 部分Reduce的执行时间明显比其他Reduce任务要长
 


5) 解决方法:


1.对会产生笛卡尔积的数据进行初步过滤

SELECT T1.id ,count(*) as num FROM learn4.student_null T1 JOIN learn4.score_null T2 ON T1.id = T2.id   AND (T1.id != "null_student" or T2.id != "null_student") GROUP BY T1.id;


2.可以对Key比较集中的数据进行加随机数,然后再进行处理

SELECT T1.id ,count(*) as num FROM learn4.student_null T1 JOIN learn4.score_null T2 ON concat(T1.id,floor((rand()*10)%5)) = concat(T2.id,floor((rand()*10)%5))  GROUP BY T1.id;   SELECT substring(T.id,1,-1) as id ,sum(T.num) --对打散的ID统计过的结果进行汇总 FROM ( SELECT T1.id  ,count(*) as num    --对打散的ID进行统计 FROM ( SELECT concat(T1.id,floor((rand()*10)%5)) as id  --将T1表中的数据进行打散 FROM learn4.student_null) T1 JOIN  ( SELECT concat(T1.id,floor((rand()*10)%5)) as id  --将T2表中的数据进行打散 FROM learn4.score_null) T2 ON T1.id =T2.id )T GROUP BY substring(T.id,1,-1);

3.通过参数进行调整


设置开启Map端的聚合操作

set hive.map.aggr = true

设置groupby的检查点条数

set hive.groupby.mapaggr.checkinterval = 100000


开启GROUP BY 的负载均衡操作

set hive.groupby.skewindata = true   

通过调整该参数,使得有倾斜的数据在Map reduce过程中 被随机的从Map端发送到Reduce端进行处理,

reduce会对随机发送过来的数据进行 初步的处理,之后再进行后续的统计

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!