您的位置:首页 > 其它

[置顶] hive数据倾斜优化

2017-09-10 23:20 429 查看
关于hive的优化
Hive倾斜—不患寡而患不均

一、创建表时候的优化
a)       大表拆分为小表
b)       如果使用外部分区表的话,要注意多级分区,比如以天为分区的话,每天为分区,以小时为分区的话,要以小时为二级分区。
c)       数据存储:更改存储格式、数据压缩。
二、对表数据查询的优化
a)       Sql语句的优化:尽可能的加入合理的过滤语句,使查询到的数据更合理、更少而有效;对于分区表的查询尽可能使用分区字段。
b)       对MapReduce的优化:对reduce个数的优化、对jvm重用、数据查询之前的推测执行等。
c)       具体如下
三、一些小技巧
1、对fetch task的优化
我们可以使用fetch taske更改显示内容的多少。
设置参数的优先级:在命令行或者代码设置参数 > hive-site.xml>hive-default.xml
或者:set hive.fetch.task.conversion=more;   //单次交互模式下有效,
或者以这种模式运行hive:bin/hive --hiveconf hive.fetch.task.conversion=more
2、开启严格模式
strictmode:严格模式设置,严格模式下将会限制一些查询操作
     文件格式,ORC PARQUET 等  
     分区表
      select 查询不加where过滤条件,不会执行
四、查询操作优化
优化sql语句,如先过滤再join;先分组(group by)再做distinct;
1、加入分组
原因:如果有1TB的数据,如果单次查询,可能会只是用一个reduce,但是如果我们加入了分组(group by),就会调用多个reduce,这使效率提高。
eg1.
Select count(*)cnt
From store_saless
4000
s
     join household_demographics hd on(ss.ss_hdemo_sk = hd.hd_demo_sk)
     join time_dim t on (ss.ss_sold_time_sk =t.t_time_sk)
     join store s on (s.s_store_sk =ss.ss_store_sk)
Where
     t.t_hour = 8
     t.t_minute >= 30
     hd.hd_dep_count = 2
order by cnt;
2、全表关联的时候join的同时过滤
在SELECT中,只拿需要的列,如果有,尽量使用分区过滤,少用SELECT *。
在分区剪裁中,当使用外关联时,如果将副表的过滤条件写在Where后面,那么就会先全表关联,之后再过滤,比如:
SELECT a.empno
FROM emp a
left outer joinemp_part b
ON (a.deptno =b.depno)
WHERE b.day ='20150828′;
 
         正确的写法是写在ON后面:
 
SELECT a.id
FROM emp a
left outer joinemp_part b
ON (a.deptno = b.depno AND b.day = '2015082818');
3、先分组,在DISTINCT
少用COUNT DISTINCT
数据量小的时候无所谓,数据量大的情况下,由于COUNT DISTINCT操作需要用一个Reduce Task来完成,这一个Reduce需要处理的数据量太大,就会导致整个Job很难完成,一般COUNT DISTINCT使用先GROUP BY再COUNT的方式替换:
eg3.
 
SELECT day,
COUNT(DISTINCTid) AS uv
FROM emp
GROUP BY day
 
可以转换成:
 
SELECT day,
COUNT(id) AS uv
FROM (SELECTday,id FROM emp GROUP BY day,id) a
GROUP BY day;
4. MapReduce过程的map、shuffle、reduce端的snappy压缩
 
需要先替换hadoop的native本地包开启压缩
在mapred-site.xml文件设置启用压缩及压缩编码
在执行SQL执行时设置启用压缩和指定压缩编码
              5、设置Map和reduce个数:默认情况下一个块对应一个map任务,map数据我们一般不去调整,
reduce个数根据reduce处理的数据量大小进行适当调整
这体现了“分而治之”的思想。
 
确定map个数与合并小文件。
6、hive的并行执行
假设一个sql语句运行的时候产生多个job,比如一个sql与1.2.3个job,其中第1、2个job在查询(join查询语句)的过程后在与第三个job结果进行join查询,我们可以将1、2job在join同时job3可以同时并行执行。
 
       分布式并行化
set hive.exec.parallel=true; //一次性配置
<description>Whether to execute jobs inparallel</description>
 
set hive.exec.parallel.thread.number=8;
<description>How many jobs at most can beexecuted in parallel</description>
7、JVM重用
一个job可能有多个map reduce任务,每个任务会开启一个JVM虚拟机,默认情况下一个任务对应一个JVM,任务运行完JVM即销毁,到了下一次MapReduce任务又会重启。这样大大消耗了时间。
 
因此我们可以设置JVM重用参数,一般不超过5个,这样一个JVM内可以连续运行多个任务,jvm不会销毁。
 
JVM重用是Hadoop调优参数的内容,对Hive的性能具有非常大的影响,特别是对于很难避免小文件的场景或者task特别多的场景,这类场景大多数执行时间都很短。hadoop默认配置是使用派生JVM来执行map和reduce任务的,这是jvm的启动过程可能会造成相当大的开销,尤其是执行的job包含有成千上万个task任务的情况。
JVM重用可以使得JVM实例在同一个JOB中重新使用N次,N的值可以在Hadoop的mapre-site.xml文件中进行设置(建议参考5~10)
mapred.job.reuse.jvm.num.tasks(旧版)
mapreduce.job.jvm.numtasks(新版)
hadoop.apache.org/docs/r2.5.2/hadoop-mapreduce-client/hadoop-mapreduce-client-core/mapred-default.xml
http://hadoop.apache.org/docs/r2.5.2/hadoop-mapreduce-client/hadoop-mapreduce-client-core/mapred-default.xml
8、推测执行:例如一个Job应用有10个MapReduce任务(map 及reduce),其中9个任务已经完成,那么application Master会在另外启动一个相同的任务来运行未完成的那个,最后哪个先运行完成就把另一个kill掉
 
       启用speculative最大的好处是,一个map执行的时候,系统会在其他空闲的服务器上启动相同的map来同时运行,哪个运行的快就使用哪个的结果,另一个运行慢的在有了结果之后就会被kill。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: