优化的三个角度:
架构:分区表、合理利用中间结果集
SQL:执行计划
参数:reduce join转map join
A。column pruning(列裁剪)
查询的时候需要哪些列,直接查这些列即可,不要全局查询。
能使用 select a,b,c from xxx,尽量不要使用select * from xxx。
B。parrtition pruning(分区裁剪)
查询的时候需要哪些分区,直接查这些分区即可,不要全局查询。
能使用 select * from table_name where partition_date='2018-04-10' ; ,尽量不要使用select * from table_name ; 。
C。对表或分区进行分桶(大表join大表)
2张表对于连接的字段进行分桶,处理左边表内某个桶的Mapper他知道右边表内对应的行在对应的桶内,因此Mapper只需要获取那个桶,然后取得数据进行JOIN
D。合理利用中间结果集
SQL1包含: select a,b,c,z from xxx group ...
SQL2包含:select a,b,c,d,e,f from xxx group ....
我们可以在sql1和sql2执行之前先创建临时表
create table tmp_1 as select a,b,c,d,e,f,z from xxx group ....
然后再执行SQL1和SQL2。
这种方式可以大大地降低I/O,但依赖性加强了。
E。对大表join小表将reduce join转成map join
将小表数据直接通过collect算子拉取到Driver端的内存中来,然后对其创建一个Broadcast变量;接着对大表执行map类算子,在算子函数内,从Broadcast变量中获取较小表的全量数据,与小表的每一条数据按照连接key进行比对,如果连接key相同的话,那么就将两个表数据用你需要的方式连接起来。
F。启用推测式执行
一个作业的执行时间取决于最后一个task执行情况,如果最后一个或几个task所在机器负载较高,这就可能会大大增加作业的运行时间,形成长尾作业。我们可以设定一个阈值,比如最后一个或几个task执行时间超得过已经执行时间的 百分之多少的时候,在 另一台或几台低负载机器启动最后一个或几个task,哪边先执行完则采用哪边的结果。
无论是什么框架,只要问到长尾作业如何解决,就是采用这种 方式。
关键参数:hive.mapred.reduce.tasks.speculative.execution 是否打开推测式执行,默认为true(打开)
小伙伴们查一下这个参数对应的阈值是多少哟,去源码里面找
如果整个集群负载都特别大,这种方式就要慎重啦。
G。jvm复用
MapReduce的每个task都是一个进程,进程的启用和销毁都需要大量时间,启用jvm复用,则下一个task执行直接使用上一个task占用的进程即可,这样可以大大地提升作业的性能。
jvm复用在Hive只要打开一个参数即可。
set mapred.job.reuse.jvm.num.tasks=10;默认值为1,表示一个JVM可以顺序执行的tsak数量为1。
H。reducer数量优化
reducer数量过多可能造成小文件过多,reducer数量过少可能造成作业运行太慢。所以合理地配置reducer的数量很重要。
关键参数1:mapred.reduce.tasks 默认值-1,表示hive会自动设置reducer的数量。(这个参数肯定是要调整的)
关键参数2:hive.exec.reducers.bytes.per.reducer 0.14版本之后默认值为256MB,表示每一个reducer处理的数据量
I。排序优化
Order By(全局排序):会将所有的数据在一个reducer上执行,得到的结果是整体有序的。但是由于不能并发执行,所以效率比较低。只有一个reducer,作业跑不出来,而且很可能数据倾斜。
Sort By(局部排序):排序操作在多个reducer上执行,得到的结果是局部有序(一个reducer内)的,但是整体数据不一定是严格有序的。另外,这个语句还可能造成数据的重叠和丢失。由于MapReduce是采用Hash的方式来组织数据的,所以当使用Sort By时,一个reducer的输出会覆盖另一个reducer的数据。
Distribute By:为Sort By而生!它可以修正SortBy带来的负面作用,避免数据的覆盖和丢失。Distribute By将保证具有相同的指定关键字的记录进入到同一个reducer进行处理,这样就可以避免reducer在输出数据时将不同reducer的记录放到同一个位置,从而造成数据的覆盖!
J。设置数据负载均衡
hive和其它关系数据库一样,支持count(distinct)操作,但是对于大数据量中,如果出现数据倾斜时,会使得性能非常差,解决办法为设置数据负载均衡,其设置方法为设置hive.groupby.skewindata参数。改参数默认值为false,设置为true可以解决一般的数据倾斜问题。当然,如果对于group by导致的数据倾斜,则最好还要设置hive.map.aggr参数(对应MR中的combiner),启用该参数执行聚合操作会先在map端进行一次聚合。
K。predicate pushdown(ppd谓词下压)
hive.optimize.ppd:是否支持谓词下推,默认开启;所谓谓词下推,将外层查询块的 WHERE 子句中的谓词移入所包含的较低层查询块(例如视图),从而能够提早进行数据过滤以及有可能更好地利用索引。
hive.optimize.ppd.storage:谓词下推开启时,谓词是否下推到存储handler,默认开启,在谓词下推关闭时不起作用;
hive.ppd.recognizetransivity:在等值join条件下是否产地重复的谓词过滤器,默认开启;
L。压缩调优:
M。存储格式调优: