hive数据倾斜优化

关于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_salesss

     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; //一次性配置

Whether to execute jobs inparallel

 

set hive.exec.parallel.thread.number=8;

How many jobs at most can beexecuted in parallel

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。

你可能感兴趣的:(hive优化)