性能低的来源
hive性能优化时,把HiveQL当做M/R程序来读,即从M/R的运行角度来考虑优化性能,从更底层思考如何优化运算性能,而不仅仅局限于逻辑代码的替换层面。
Hadoop处理数据的显著特征:
1.数据的大规模并不是负载重点,造成运行压力过大原因是数据倾斜;
2.jobs数比较多也是作业运行效率低的原因之一,如一个几百行的表,多次关联对此汇总,产生几十个jobs,将需要花费大量时间且大部分时间用于作业分配,初始化和数据输出。M/R作业初始化的时间是比较耗时间资源的一个部分;
3.在使用SUM,COUNT,MAX,MIN等函数时,Hadoop在Map端的汇总合并优化过,就不用担心数据倾斜问题。
4.COUNT(DISTINCT)在数据量大的情况下,效率较低,因为COUNT(DISTINCT)是按GROUP BY字段分组,按DISTINCT字段排序。如:男UV,女UV,一天30亿的PV,如果按性别分组,分配2个reduce,每个reduce处理15亿数据
5.数据倾斜是导致效率大幅降低的主要原因,可以采用多一次 Map/Reduce 的方法, 避免倾斜。
配置角度优化
Hive系统内部已针对不同的查询预设定了优化方法,用户可以通过调整配置进行控制, 下面举例介绍部分优化的策略以及优化控制选项。
**1.列裁剪
Hive在读数据的时候,可以只读取查询中所需要用到的列,而忽略其它列。例如
SELECT a,b FROM q WHERE e<10;
这样做节省了读取开销,中间表存储开销和数据整合开销。
裁剪所对应的参数项为:hive.optimize.cp=true(默认值为真)
2.分区裁剪
在查询过程中减少不必要的分区。例如
SELECT * FROM (SELECTT a1,COUNT(1) FROM T GROUP BY a1) subq WHERE subq.prtn=100;
#(多余分区)SELECT * FROM T1 JOIN (SELECT * FROM T2) subq ON (T1.a1=subq.a2) WHERE subq.prtn=100;
查询语句若将“subq.prtn=100”条件放入子查询中更为高效,可以减少读入的分区 数目。Hive 自动执行这种裁剪优化。
分区参数为:hive.optimize.pruner=true(默认值为真)
3.JOIN操作
在操作有 join 的语句时,应该将条目少的表/子查询放在 Join 操作符的左边。因为在 Reduce 阶段,位于 Join 操作符左边的表的内容会被加载进内存,载入条目较少的表可以有效减少 OOM(out of memory)内存溢出。这便是“小表放前”原则。
4.MAP JOIN操作
Join 操作在 Map 阶段完成,不再需要Reduce,前提条件是需要的数据在 Map 的过程中可以访问到。比如查询:
INSERT OVERWRITE TABLE pv_users
SELECT /+ MAPJOIN(pv) / pv.pageid, u.age
FROM page_view pv
JOIN user u ON (pv.userid = u.userid);
可以在 Map 阶段完成 Join.
相关的参数为:
hive.join.emit.interval = 1000
hive.mapjoin.size.key = 10000
hive.mapjoin.cache.numrows = 10000
5.GROUP BY操作
需要注意的有两点:
Map端部分聚合
很多聚合操作都可以先在Map端进行部分聚合,然后reduce端得出最终结果。
需要修改的参数为:
hive.map.aggr=true(用于设定是否在 map 端进行聚合,默认值为真) hive.groupby.mapaggr.checkinterval=100000(用于设定 map 端进行聚合操作的条目数)
有数据倾斜时进行负载均衡
需要设定 hive.groupby.skewindata,当选项设定为 true 时,生成的查询计划有两 个 MapReduce 任务。在第一个 MapReduce 中,map 的输出结果集合会随机分布到 reduce 中, 每个 reduce 做部分聚合操作,并输出结果。这样处理的结果是,相同的 Group By Key 有可能分发到不同的 reduce 中,从而达到负载均衡的目的;第二个 MapReduce 任务再根据预处理的数据结果按照 Group By Key 分布到 reduce 中,最后完成最终的聚合操作。
6.合并小文件
文件数目小容易造成存储端瓶颈,给HDFS带来压力,影响处理效率。通过合并Map和Reduce的结果文件来消除这样的影响。
用于设置合并属性的参数有:
是否合并Map输出文件:hive.merge.mapfiles=true(默认值为真)
是否合并Reduce 端输出文件:hive.merge.mapredfiles=false(默认值为假)
合并文件的大小:hive.merge.size.per.task=25610001000(默认值为 256000000)
hql性能优化
最新推荐文章于 2023-07-20 10:47:55 发布