hive里的优化和高级功能

大数据和人工智能躺过的坑 大数据和人工智能躺过的坑     2022-08-14     213

关键词:

  在一些特定的业务场景下,使用hive默认的配置对数据进行分析,虽然默认的配置能够实现业务需求,但是分析效率可能会很低。

Hive有针对性地对不同的查询进行了优化。在Hive里可以通过修改配置的方式进行优化。

  以下,几种方式调优的属性。

 

1、列裁剪

  在通过Hive读取数据的时候,并不是所有的需求都要获取表内的所有的数据。有些只需要读取所有列中的几列,而忽略其他列的的数据。

例如,表Table1包含5个列Column1、Column2、Column3、Column4、Column5。下面的语句只会在表Table1中读取Column1、Column2、Column5三列,

Column3和Column4将被忽略。

  SELECT Column1,Column2  FROM Table1 WHERE Column5<1000;

  列裁剪的设置为hive.optimize.cp,默认为true。

  

2、分区裁剪

  在Hive中,可以根据多个维度对Hive表进行分区操作,且分区也可以多层嵌套。当有需要对目标表的某一个区域内的数据进行分析而不需要设计其他区域时,可以使用分区裁剪,将目标区域以条件的形式放在HiveQL中。

SELECT * FROM(SELECT c1 FROM T GROUP BY c1) idi

  WHERE idi.prtn = 100;

SELECT * FROM T1 JOIN(SELECT * FROM T2) idi ON (T1.c1=idi.c2)

  WHERE idi.prtn=100;

  以上语句在执行时,会在子查询中考虑idi.prtn=100这个条件,从而减少读入的数据的分区数目。分区裁剪的配置为hive.optimize.pruner,默认为hive。

 

3、join

  Hive同样支持join多表连接查询,例如内连接、外连接(左外连接、右外连接、全外连接)、半连接等。对于一条语句中有多个join的情况,当join的条件相同时,即使有多张表,都会合并为一个MapReduce,并不是多个MapReduce。

SELECT pv.ppid, u.name FROM propertie_view pc
JOIN user u ON(pv.userid = u.userid)
JOIN usergroup x ON(u.userid = x.userid)

  如果join的条件不相同,MapReduce的任务数目和join操作的数据是对应的,例如:

SELECT pv.ppid, u.name FROM propertie_view pv
JOIN user u ON(pv.userid = u.userid)
JOIN usergroup x ON(u.age = x.age)

 

  在使用写有join操作的查询语句时,由于在join操作的Reduce阶段,join执行时会将join操作符左边的表的内容加载进内存,所以写语句时应将条目少的表/子查询放在join操作符的左边,这样可以有效减少内存溢出错误的几率。

 

 

 

4、MapJoin

  MapJoin的合理使用同样能起到调优的效果。在实际的应用中有可能遇到join执行效率很低甚至不能执行的状况。例如,需要做不等值join,或者在join时有一个表极小。由于MapJoin会把小表全部读入内存中,Join操作在Map阶段完成,在Map阶段直接将另外一个表的数据和内存中表数据做匹配,所以不会对任务进行速度产生很大影响。即使笛卡尔积也是如此。

  例如:

SELECT /*+ MAPJOIN(pc) */ pv.ppid, u.name
FROM propertie_view pv
JOIN user u ON (pv.userid=u.userid)

 

 

5、Group By优化

  (1)Map端局部聚合

  众所周知,MapReduce计算框架中Reduce起到聚合操作的作用,但并不是所有的聚合操作都需要在Reduce端完成,很多聚合操作可以先在Map端进行局部聚合,最后在Reduce端做全局聚合得出最终结果。是否在Map端进行聚合由hive.map.agger控制,默认为True。

  而hive.groupby.mapagger.checkinterval用于控制在Map端进行聚合操作的条目数目,默认为100000。

  (2)数据倾斜

  有数据倾斜的时候需要进行负载均衡。是否需要进行负载均衡由hive.groupby.skewindata控制,默认为false。

  当选项设定为true时,编译器生成的查询计划会有两个MR Job。

  第一个MR Job中的Map的输出结果集合会随机分布到第一个MR Job的Reduce中,每个Reduce做局部聚合操作作为输出结果,这样处理的结果是相同的Group By Key有可能被分发到不同的Reduce中,从而实现负载均衡的目的;

  第二个MR Job再根据预处理的数据结果按照Group By Key分布到相应的Reduce中,最后完成最终的聚合操作。

 

 

 

 

 

Hive性能调优

1、优化的常用手段 

2、Hive的数据类型方面的优化

3、Hive的数据类型方面的优化

 

 

 

什么是数据倾斜?  

     由于数据的不均衡原因,导致数据分布不均匀,造成数据大量的集中到一点,造成数据热点

 

 

Hadoop框架的特性 

  不怕数据大,怕数据倾斜
  jobs数比较多的作业运行效率相对比较低,比如即使有几百行的表,如果多次关联多次汇总,产生十几个jobs,耗时很长。
  原因是map reduce作业初始化的时间是比较长的
  sum,count,max,min等UDAF,不怕数据倾斜问题,hadoop在map端的汇总合并优化,使数据倾斜不成问题
  count(distinct ),在数据量大的情况下,效率较低,因为count(distinct)是按group by 字段分组,按distinct字段排序,一般这种分布方式是很倾斜的

 

 

1、优化的常用手段 

  解决数据倾斜问题

  减少job数

  设置合理的map reduce的task数,能有效提升性能。

  了解数据分布,自己动手解决数据倾斜问题是个不错的选择

  数据量较大的情况下,慎用count(distinct)。

  对小文件进行合并,是行至有效的提高调度效率的方法。

  优化时把握整体,单个作业最优不如整体最优。

 

 

 

 

 

2、Hive的数据类型方面的优化

优化原则

  合理的设置Buckets。在一些大数据join的情况下,map join有时候会内存不够。
  如果使用Bucket Map Join的话,可以只把其中的一个bucket放到内存中,内存中原来放不下的内存表就变得可以放下。
  这需要使用buckets的键进行join的条件连结,并且需要如下设置

  set hive.optimize.bucketmapjoin = true

 

 

 

 

3、Hive的操作方面的优化

3.1 全排序

  Hive的排序关键字是SORT BY,
  它有意区别于传统数据库的ORDER BY也是为了强调两者的区别–SORT BY只能在单机范围内排序。

 

3.2 做笛卡尔积

  当Hive设定为严格模式(hive.mapred.mode=strict)时,不允许在HQL语句中出现笛卡尔积
  MapJoin是的解决办法
  MapJoin,顾名思义,会在Map端完成Join操作。这需要将Join操作的一个或多个表完全读入内存
  MapJoin的用法是在查询/子查询的SELECT关键字后面添加/*+ MAPJOIN(tablelist) */提示优化器转化为MapJoin(目前Hive的优化器不能自动优化MapJoin)
  其中tablelist可以是一个表,或以逗号连接的表的列表。tablelist中的表将会读入内存,应该将小表写在这里
  在大表和小表做笛卡尔积时,规避笛卡尔积的方法是,给Join添加一个Join key,原理很简单:将小表扩充一列join key,并将小表的条目复制数倍,join key各不相同;将大表扩充一列join key为随机数。

 

 

3.3 控制Hive的Map数

  通常情况下,作业会通过input的目录产生一个或者多个map任务
  主要的决定因素有:
  input的文件总个数,
  input的文件大小,
集群设置的文件块大小(目前为128M, 可在hive中通过set dfs.block.size;命令查看到,该参数不能自定义修改)

 

是不是map数越多越好?
  答案是否定的。如果一个任务有很多小文件(远远小于块大小128m),则每个小文件也会被当做一个块,用一个map任务来完成,而一个map任务启动和初始化的时间远远大于逻辑处理的时间,就会造成很大的资源浪费。而且,同时可执行的map数是受限的。

 

是不是保证每个map处理接近128m的文件块,就高枕无忧了?
  答案也是不一定。比如有一个127m的文件,正常会用一个map去完成,但这个文件只有一个或者两个小字段,却有几千万的记录,如果map处理的逻辑比较复杂,用一个map任务去做,肯定也比较耗时。

 

针对上面的问题3和4,我们需要采取两种方式来解决:即减少map数和增加map数;

  举例
a) 假设input目录下有1个文件a,大小为780M,那么hadoop会将该文件a分隔成7个块(6个128m的块和1个12m的块),从而产生7个map数
b)假设input目录下有3个文件a,b,c,大小分别为10m,20m,130m,那么hadoop会分隔成4个块(10m,20m,128m,2m),从而产生4个map数
即如果文件大于块大小(128m),那么会拆分,如果小于块大小,则把该文件当成一个块

 

 

 

3.4 决定reducer个数

  Hadoop MapReduce程序中,reducer个数的设定极大影响执行效率

  不指定reducer个数的情况下,Hive会猜测确定一个reducer个数,基于以下两个设定:
参数1:hive.exec.reducers.bytes.per.reducer(默认为1G)
参数2 :hive.exec.reducers.max(默认为999)

 

  计算reducer数的公式
N=min(参数2,总输入数据量/参数1)

  依据Hadoop的经验,可以将参数2设定为0.95*(集群中TaskTracker个数)
  reduce个数并不是越多越好
  同map一样,启动和初始化reduce也会消耗时间和资源;

  另外,有多少个reduce,就会有多少个输出文件,如果生成了很多个小文件,那么如果这些小文件作为下一个任务的输入,则也会出现小文件过多的问题。


什么情况下只有一个reduce?
  很多时候你会发现任务中不管数据量多大,不管你有没有设置调整reduce个数的参数,任务中一直都只有一个reduce任务;

  其实只有一个reduce任务的情况,除了数据量小于hive.exec.reducers.bytes.per.reducer参数值的情况外,还有以下原因:
a)没有group by的汇总
b)用了Order by

 

 

 

 

3.5 合并 MapReduce 操作

Multi-group by
  Multi-group by是Hive的一个非常好的特性,它使得Hive中利用中间结果变得非常方便。

 

FROM log
insert overwrite table test1 select log.id group by log.id
insert overwrite table test2 select log.name group by log.name

  上述查询语句使用了Multi-group by特性连续group by了2次数据,使用不同的group by key。这一特性可以减少一次MapReduce操作。

 

Bucket 与 Sampling
  Bucket是指将数据以指定列的值为key进行hash,hash到指定数目的桶中。这样就可以支持高效采样了。

 

  Sampling可以在全体数据上进行采样,这样效率自然就低,它还是要去访问所有数据。而如果一个表已经对某一列制作了bucket,就可以采样所有桶中指定序号的某个桶,这就减少了访问量。

  如下例所示就是采样了test中32个桶中的第三个桶。
SELECT * FROM test 、、、TABLESAMPLE(BUCKET 3 OUT OF 32);

 

 

 

3.6 JOIN 原则

  在使用写有 Join 操作的查询语句时有一条原则:应该将条目少的表/子查询放在 Join 操作符的左边

  原因是在 Join 操作的 Reduce 阶段,位于 Join 操作符左边的表的内容会被加载进内存,将条目少的表放在左边,可以有效减少发生 OOM 错误的几率。

 

Map Join
Join 操作在 Map 阶段完成,不再需要Reduce,前提条件是需要的数据在 Map 的过程中可以访问到。

 

例如:
INSERT OVERWRITE TABLE phone_traffic
SELECT /*+ MAPJOIN(phone_location) */ l.phone,p.location,l.traffic from phone_location p join log l on (p.phone=l.phone)

相关的参数为:

hive.join.emit.interval = 1000 How many rows in the right-most join operand Hive should buffer before emitting the join result.
hive.mapjoin.size.key = 10000
hive.mapjoin.cache.numrows = 10000

 

 

 

 

3.7 Group By

  Map 端部分聚合
并不是所有的聚合操作都需要在 Reduce 端完成,很多聚合操作都可以先在 Map 端进行部分聚合,最后在 Reduce 端得出最终结果基于 Hash

  参数包括:
hive.map.aggr = true 是否在 Map 端进行聚合,默认为 True
hive.groupby.mapaggr.checkinterval = 100000 在 Map 端进行聚合操作的条目数目。

 

  有数据倾斜的时候进行负载均衡
hive.groupby.skewindata = false
  当选项设定为 true,生成的查询计划会有两个 MR Job。第一个 MR Job 中,
  Map 的输出结果集合会随机分布到 Reduce 中,每个 Reduce 做部分聚合操作,并输出结果,
  这样处理的结果是相同的 Group By Key 有可能被分发到不同的 Reduce 中,从而达到负载均衡的目的;
  第二个 MR Job 再根据预处理的数据结果按照 Group By Key 分布到 Reduce 中(这个过程可以保证相同的 Group By Key 被分布到同一个 Reduce 中),
最后完成最终的聚合操作。

 

 

 

3.8 合并小文件

  文件数目过多,会给 HDFS 带来压力,并且会影响处理效率,可以通过合并 Map 和 Reduce 的结果文件来消除这样的影响:

hive.merge.mapfiles = true 是否和并 Map 输出文件,默认为 True
hive.merge.mapredfiles = false 是否合并 Reduce 输出文件,默认为 False
hive.merge.size.per.task = 256*1000*1000 合并文件的大小

 

hive里的扩展接口

 hive里的扩展接口,主要包括CLI(控制命令行接口)、Beeline和JDBC等方式访问Hive。  CLI和Beeline都是交互式用户接口,并且功能相似,但是语法和实现不同。  JDBC是一种类似于编程访问关系型数据库的编程接口。  ... 查看详情

为啥我无法在 Hive 中使用具有多个插入子句的高级聚合功能?

】为啥我无法在Hive中使用具有多个插入子句的高级聚合功能?【英文标题】:WhyamIunabletouseadvancedaggregationfeatureswithamultipleinsertclauseinHive?为什么我无法在Hive中使用具有多个插入子句的高级聚合功能?【发布时间】:2017-01-0507:35:22... 查看详情

hive原理及sql优化

1.Hive原理Hive是构建在Hadoop上的数据仓库软件框架,支持使用SQL来读,写和管理大规模数据集合。Hive入门非常简单,功能非常强大,所以非常流行。通常来说,Hive只支持数据查询和加载,但后面的版本也支... 查看详情

hive与优化方法(代码片段)

Hive与优化方法文章目录Hive与优化方法一、Hive概念二、Hive架构三、Hive与数据库的比较四、Hive中一些重要的概念4.1内部表和外部表4.2分区表4.3Hive排序关键字4.4Hive分桶4.5三种排序窗函数的区别4.6Hive解析MR的Reduce数量的确定4.7Hive的... 查看详情

hive里的hiveql——查询语言

  Hive的操作与传统关系型数据库SQL操作十分类似。   Hive主要支持以下几类操作:DDL  1、DDL:数据定义语句,包括CREATE、ALTER、SHOW、DESCRIBE、DROP等。      详细点,就是  Hive支持大量SQL数据定义语言(DataD... 查看详情

安卓手机wifi会自动关闭怎么办

...,系统会自动排去不稳定的WIFI,这种情况只需要点击WIFI里的高级设置,取消掉避开状况不佳的网络即可。参考技术A1.如果设置不休眠,关闭了省电模式以后,wifi还掉线。比如过几分钟就自己关闭,打开一个软件试试,比如QQ,... 查看详情

hive的高级操作(代码片段)

二、视图1、Hive的视图和关系型数据库的视图区别和关系型数据库一样,Hive也提供了视图的功能,不过请注意,Hive的视图和关系型数据库的数据还是有很大的区别:  (1)只有逻辑视图,没有物化视图;  (2)视图只能查... 查看详情

sparksql和hive到底啥关系

...法树(AST)起,就全部由SparkSQL接管了。执行计划生成和优化都由Catalyst负责。借助Scala的模式匹配等函数式语言特性,利用Catalyst开发执行计划优化策略比Hive要简洁得多。去年Sparksummit上Catalyst的作者MichaelArmbrust对Catalyst做了一个... 查看详情

hive里的用户定义函数udf

  Hive可以通过实现用户定义函数(User-DefinedFunctions,UDF)进行扩展(事实上,大多数Hive功能都是通过扩展UDF实现的)。想要开发UDF程序,需要继承org.apache.hadoop.ql.exec.UDF类,并重载evaluate方法。HiveAPI提供@Description声明,使用... 查看详情

hive优化之hive的配置参数优化

...数和HiveSQL的执行等。本文主要从建表配置参数方面对Hive优化进行讲解。1.创建一个普通表tabletest_user1(idint,namestring,codestring,code_idstring)ROWFORMATDELIMITEDFIELDSTERMINATED BY',';2.查看这张表的信息DESCRIBEFORMATTED test_user1;我们从... 查看详情

hive里的分区和分桶再谈

    分桶是细粒度的,分桶是不同的文件。  分区是粗粒度的,即相当于,表下建立文件夹。分区是不同的文件夹。 桶在对指定列进行哈希计算时,会根据哈希值切分数据,使每个桶对应一个文件。  里面的... 查看详情

hive与优化方法(代码片段)

Hive与优化方法文章目录Hive与优化方法一、Hive概念二、Hive架构三、Hive与数据库的比较四、Hive中一些重要的概念4.1内部表和外部表4.2分区表4.3Hive排序关键字4.4Hive分桶4.5三种排序窗函数的区别4.6Hive解析MR的Reduce数量的确定4.7Hive的... 查看详情

Hive 查询优化

】Hive查询优化【英文标题】:Hivequeryoptimization【发布时间】:2019-10-0306:45:15【问题描述】:我的要求是获取拥有超过1个电子邮件ID和type=1的学生的ID和姓名。我正在使用类似的查询selectdistinctb.id,b.name,b.email,b.type,a.cntfrom(selectid,cou... 查看详情

hive和sparksql优化(代码片段)

优化步骤问题定位,通过日志和代码分析,定位任务耗时长的原因hive任务,对于hive任务,可以通过日志查看哪个application、以及是哪个阶段耗时较长,另外,可以通过stage编号,结合explain查看执行计划... 查看详情

hive任务优化——小文件合并相关参数(代码片段)

文章目录一、Hive提供的文件合并功能hive文件合并的实现原理二、文件合并在HiveonSpark中的失效问题解决方案三、开启文件合并的优缺点一、Hive提供的文件合并功能熟悉hdfs的都知道,hdfs不建议存储小文件,原因是大量的... 查看详情

hive性能优化(新手重新标注版)

...有Map,Spill,Shuffle,Sort,Reduce等多个阶段,所以针对Hive查询的优化可以大致分为针对MR中单个步骤的优化(其中又会有细分),针对MR全局的优化,和针对整个查询(多MRJob)的优化,下文会分别阐述。在开始之前, 查看详情

23.flink-高级特性-新特性-streamingfliesink介绍代码演示flink-高级特性-新特性-flinksql整合hive添加依赖和jar包和配置(代码片段)

23.Flink-高级特性-新特性-StreamingFlieSink23.1.介绍23.2.代码演示24.Flink-高级特性-新特性-FlinkSQL整合Hive24.1.介绍24.2.版本24.3.添加依赖和jar包和配置24.4.FlinkSQL整合Hive-CLI命令行整合24.5.FlinkSQL整合Hive-代码整合23.Flink-高级特性-新特性-Stream... 查看详情

我眼中的nginx:深入nginx/openresty服务里的dns解析

张超:又拍云系统开发高级工程师,负责又拍云CDN平台相关组件的更新及维护。GithubID:tokers,活跃于OpenResty社区和Nginx邮件列表等开源社区,专注于服务端技术的研究;曾为ngx_lua贡献源码,在Nginx、ngx_lua、CDN性能优化、日志优化... 查看详情