[hive]hive优化
1.fetch抓取
1)什么是fetch抓取
fetch抓取是指hive对select 所有字段、select 指定字段、limit可以不必使用MapReduce计算,在这种情况下,hive可以简单地读取表对应的存储目录下的文件.
然后输出查询结果到控制台,这比走MR来说,大大减少了运行时间.
2)相关配置
hive.default.xml文件中hive.fetch.task.conversion默认是more.该属性设置为more以后,在全局查找,字段查找,limit查找等都不走mapreduce.
<property><name>hive.fetch.task.conversion</name><value>more</value><description>值可以选择:[none,minimal,more]0. none:全部走MR1. minimal:部分走MR2. more:全局查找,字段查找,limit查找都不走MR</description>
</property>
2.本地模式
1)什么是本地模式
大多数MR job是需要并行执行的,有时hive输入的数据量是非常小的,在这种情况下为触发任 务消耗的时间可能会比实际job的执行时间要多的多。此时执行hive本地模式,即在单台计算机上处理所有的任务。对于小的数据集,执行时间可能明显缩短。
2)相关配置
设置hive.exec.mode.local.auto的值为true,来让hive在适当的时候自动启动本地MR模式
set hive.exec.mode.local.auto=true;
设置本地MR的最大数据量,当输入数据量小于这个值时采用local MR模式,默认为128M
set hive.exec.mode.local.auto.inputbytes.max=50000000;
设置local MR的最大输入文件个数,当输入文件个数小于这个值时采用local MR模式,默认为4.
set hive.exec.mode.local.auto.input.files.max=10;
三表的优化
1.小表join大表
实际测试发现,新版的hive小表放在左边和右边已经没有明显区别。当执行map join时,小表join大表和大表join小表没有区别,会加载小表到大表的每个map端,在map端完成join.
以前是:前面的表都会被加载到内存中,后面的表进行磁盘扫描。
2.大表join大表
1)空key过滤
在mapreduce程序中,相同key对应的数据都会发送到相同的reduce task上。而所有值为Null的key都会被发送到同一个reduce task上,如果这样的数据太多,会导致内存不够。很多情况下,这些值为null的key对应的数据也是异常数据,我们可以直接把他们过滤掉。
2)空key转换
有时,空key对应的数据不是异常数据,其数据必须要包括在join中,为了不让所有空key都对应的数据跑到相同的reduce task。出现数据倾斜,内存溢出等问题。我们可以给值为null的赋一个随机的值,使得其对应的数据可以随机且均匀分布在不同的reduce上。
下面这个sql表是t1中的id为null时不参与聚合,在join时,将它的key临时转为一个随机数,这样避免了分到一个reduce中.但是这个t1的id实际上没有个改变,只是join的时候用作key时变了.
select t1.*
from t1 full join t2
on case when t1.id is null then concat('hive',rand()) else t1.id end = t2.id;
3)SMB Join(重点)
SMB=sort merge bucket join
如何进行SMB join?
1.两表是分别以join on的条件建立的分桶表,且分的桶数相同.
2.set hive.optimize.bucketmapjoin=true;set hive.optimize.bucketmapjoin.sortedmerge=true;set hive.input.format=org.hadoop.hive.ql.io.BucketizedHiveInputFormat;
3.map join
1)common join
什么是common join?
如果不指定map join或者不符合map join的条件,那么hive解析器会将join操作转换成common join,即:在reduce阶段完成join. 整个过程包含:map、shuffle、reduce阶段。
①map阶段
读取源表的数据,在map端输出时,以join on条件作为key,如果join有多个关联键,则以这些关联键的组合作为key。map输出的value为join之后所关心的(select 或者 where中需要用到的)列。同时,在value中还包含表的tag信息,用于标明此value对应哪个表。
②shuffle阶段
将key-value按照key的hash值推送至不同的reduce中,这样确保两个表中相同的key位于同一个reduce中。
③reduce阶段
根据key的值完成join操作,期间通过tag来识别不同表的数据。
2)hive map join
①什么是map join?
就是在map阶段进行表之间的连接,而不是进入到reduce阶段才进行连接。这样就节省了在shuffle阶段时要进行的大量数据传输,从而起到了优化job的作用。
②map join的原理
通常情况下,相同key的key-value存在于不同的map task中。这样就必须在reduce task阶段连接。要使map task能够顺利进行,那么就必须满足这样的条件:只有一份表的数据分布在不同的map中,其他连接表的数据必须在该表的不同map中有完整的拷贝。
③map join使用的场景
在两个要连接的表中,有一个很大,有一个很小,这样这个小表可以存放在内存中而不影响性能。我们把小表的文件复制到那张大表的map task中,再让map把文件读到内存中待用。
④hive内置提供的优化机制之一就包括map join
在很久以前,这个选项就自动开启:默认小表25M
set hive.auto.convert.join=true;
hive还提供了另一个参数:表文件的大小作为开启和关闭map join的阈值.
hive.mapjoin.smalltable.filesize=25000000 即25M
当指定map join时,小表join大表和大表join小表没有区别。会加载小表到每个map端,在map端完成join。
4.join数据倾斜
set hive.skewjoin.key=100000; 默认为10万.
join的key对应的记录条数超过这个值则会进行拆分,值根据数据量设置
ste hive.optimize.skewjoin=false;
如果是join过程中出现数据清切应该设置为true;如果开启了,在join的过程中会开启两个MR,通过下面的参数可以控制第二个job的mapper数量
set hive.skewjoin.mapjoin.map.tasks=10000;默认1万;
5.group by
①并不是所有的聚合操作都需要在reduce端完成,很多聚合操作可以先在map端进行预聚合,然后在reduce端得出最终结果。
hive.map.aggr=true;
是否在map端进行预聚合,默认为true
set hive.groupby.mapaggr.checkinterval=100000;
在map端进行聚合操作的条目数目
②hive.groupby.skewindata=true 注:skew倾斜
该方法在reduce端预聚合,聚合程度比map阶段预聚合程度高(因为map片多,个数多).
当选项设定为true,会有两个MR job。
在第一个MR job中,map的输出结果会随机分发到reduce中。每个reduce做部分聚合操作,
并输出结果。这样处理的结果是相同的group by key有可能被分发到不同的reduce中,从而
达到负载均衡的目的。
第二个MR job再根据预处理的数据结果按照group by key分布到一个reduce中(这个可以
保证相同的group by key被分到同一个reduce中)。最后完成最终的聚合操作。
6.count(distinct)去重
该操作在一个reduce task中执行,当数据量大的时候,这个reduce task需要处理的数据量太大,会导致整个job难以完成。用先group by id再count(id) 来替换。
7.笛卡尔积
应尽量避免笛卡尔积。因为只用一个reduce task执行笛卡尔积,出现笛卡尔积的情景:
1)select t1,t2
2)join时不加条件
8.行列过滤
列处理:在select中指定想要的列,尽量避免用select *
行处理:当使用left join、right join、full join时,如果将后面表的过的过滤写在where后面。就会先全表关联,之后再过滤。
四.并行执行
什么是并行执行?
hive会将一个查询转化成一个或多个阶段,这样的阶段可以是mapreduce阶段,limit阶段,或者hive执行过程中可能经历的其他阶段。
默认情况下,hive一次只会执行一个阶段,不过,某个特定的job可能包含众多的阶段,而这些阶段是可以并行执行的,这样可能使整个job执行时间缩短。
通过设置hive.exec.parallel(并行)=true就可以开启并行执行,不过在共享集群中,需要注意,如果Job中并行阶段增多,那么集群利用率就会增加。
set hive.exec.parallel=true;
打开任务并行执行
set hive.exec.parallel.thread.number=16;
同一个sql允许最大并行度,默认为8
当然,得是在系统资源比较空闲的时候才有优势,否则没资源,并行也起不来
五.严格模式
严格模式可以防止用户执行那些可能造成不好影响的查询。开启严格模式:
set hive.mapred.mode=strict;
默认是nonstrict
严格模式限制3种类型的查询
1.对分区表的查询必须在where子句对分区字段限定条件,即不允许扫描所有分区。
2.使用order by 必须学limit
因为order by为了执行全局排序将所有的结果数据分发到一个reduce task中进行处理。强制要求用户增加这个limit语句可以防止reduce task额外执行很长时间。
3.限制笛卡尔积
六.推测执行
在分布式集群环境下,因为程序bug(或hadoop本身的bug),资源分布不均等问题,会造成同一个job的多个任务速度不一致的情况。有些任务的运行速度可能明显慢于其他任务(比如一个job的某个任务的进度只有50%,而其他已经执行完毕),则这个任务会拖累job整体的执行进度。为了避免这种情况发生,hadoop采用了推测执行机制,它根据一定的法则推测出“拖后腿”的任务,让该任务与原始任务同时处理同一份数据,并最终选用最先成功运行完成任务的计算结果作为最终结果。speculative:推测的
设置开启推测执行参数:Hadoop的mapred-site.xml文件中进行配置
<property><name>mapreduce.map.speculative</name><value>true</value>
</property><property><name>mapreduce.reduce.speculative</name><value>true</value>
</property>hive本身也提供了配置项来控制reduce-site的推测执行
<property><name>hive.mapred.reduce.tasks.speculative.execution</name><value>true</value>
</property>
七.HIve Map优化
1.设置合理的Map个数
通常情况下,job会通过input目录产生一个或多个map task,map task的个数由:
input文件总个数,input文件大小,块的大小决定,有多少片,就有多少个maptask。
1)复杂文件增加Map数
当input的文件都很大,任务逻辑复杂,map执行非常慢的时候,可以考虑增加Map数。来使得每个map处理的数据量减少,从而提高任务的执行效率。
增加map的方法:根据下面的公式调节片的大小
computeSlite(Math.max(
minSize,
Math.min(maxSize,blocksize)))=blocksize=128M
调整maxSize最大值,让maxSize最大值低于blocksize就可以增加map的个数.
2)是不是map数越多越好
不是,如果有很多小文件。一个map task处理一个小文件,则每个map task的任务启动和初始化时间远远大于逻辑处理时间,这样会造成大量的资源浪费,而且,同时执行的map task的数量是受限的。
3)是不是每个map处理的接近128M的文件就高枕无忧了?
不一定,比如一个127M的文件,正常会用一个map task去执行,但这个文件中有1个或2个字段,但却有几千万个记录。如果该map处理的逻辑比较复杂,用一个 map任务去做,肯定比较耗时。
3.小文件进行合并(亲测)
1.通过设置读取片的大小来设置
set mapred.max.split.size=1682000000;
切片的最大值
set mapred.min.split.size=1346000000;
切片的最小值
set mapred.min.split.size.per.node=1346000000;
每个节点切片的最小值
set mapred.min.split.size.per.rack=1346000000;
每个机架切片的最小值2.通过另起一个job来合并小文件
set hive.merge.mapredfiles=true;
对mr进行设置
set hive.merge.mapfiles=true;
only-map进行设置
set hive.merge.smallfiles.avgsize=16000000;默认为16M
set hive.merge.size.per.task=256000000;
合并后每个文件的目标大小,默认为256000000,256M
切分的过程:
1.三个重要的属性:
mapSplitSize:切片大小的最大值
minSplitSizeNode:同一个节点的数据块形成切片时,切片大小的最小值
minSplitSizeRack:通一机架的数据块形成切片时,切片大小的最小值
2.切片形成该过程
1)不断得带节点列表,逐个节点(以块为单位形成切片)
遍历累计每个节点上的数据块,如果累加数据块的大小>=maxSplitSize则将这些数据块形成一 个切片.继续改过程,直到剩余数据块累加大小<maxSplitSize,则进行下一步
2)如果剩余数据块累加大小>=minSizeNode,则将这些数据块形成一个切片。继续该过程,直到数据块累加大小<minSplitSizeNode。然后进行下一步。
3)不断迭代机架列表,逐个机架(以块为单位),形成切片。如果累加数据块大小>=maxSplitSize,则将这些数据块形成一个切片,直到剩余数据块累加大小<maxSplitSize则进行下一步
4)遍历并累加所有机架上的剩余数据块,如果累加数据块大小>=maxSplitSize则将这些数据块形成一个切片,继续该过程,直到剩余数据块累加大小<maxSplitSize,则进行下一步。
5)最终将剩余的数据块形成一个切片。
八.设置合理的reduce task数
1.调整reduce个数方法一
1)默认每个Reduce处理的数据量默认是256Mset hive.exec.reducers.bytes.per.reducer=256000000;
2)每个application最大的reduce数,默认为1009,如果指定为负值,则hive在自动确定reducer数量时将此值作为最大的reducer数量. set hive.exec.reducers.max=1009
3)计算reducer数的公式N=min(参数2,总输入数据量/参数1)
2.调整reduce个数方法二
在hadoop的maped-default.xml文件中修改
设置每个Job的Reduce个数
set mapreduce.job.reduces=15;默认为-1表示禁用
3.reduce task个数并不是越多越好
过多的启动和初始化reduce task会消耗时间和资源.另外有多少个reduce task就会有多少个输出文件,如果生成了很多小文件,那么如果这些小文件作为下一个任务输入,则会出现小文件过多的问题。
在设置reduce个数的时候也需要考虑这两个原则:处理大数据量利用合适的reduce数,使单个reduce任务处理数据量大小要合适。
九.数据倾斜
group by数据倾斜:map aggre、skewindata两个job
多个key同时导致数据倾斜:多设置reduce task个数
join数据倾斜:map join、skewjoin两个job、SMB、空值处理
十.explain查看执行计划
用法:
explain extended select xxx from xxx;
十一.谓词下推
将SQL语句的where谓词逻辑都尽可能提前执行,减少下游处理的数据量。对应逻辑优化器是:PredicatePushDown.
set hive.optimize.ppd.=true;谓词下推,默认是true
会自动将join后where中的where提前:先where再join
textfile 和sequencefile的存储格式都是基于行存储的。
十二.合适的文件格式
1.列式存储和行式存储
1)行存储的特点
当查询满足条件的一整行数据时,列存储需要去每个聚集的字段找到对应的每个列的值,行存储只需要找到其中的第一个值,其余的值都在相邻地方,所以此时行存储查询的速度更快。
2)列存储的特点
因为每个字段的数据聚集存储,在查询只需要少数几个字段的时候,能大大减少读取的数据量。表中相同列的值的类型肯定是相同的,列式存储可以针对性的设计更好的压缩算法。
orc和parquet是基于列式存储的。
2.textfile
默认格式,数据不做压缩,磁盘开销大,有序列化和反序列化的开销。压缩后的textfile无法分割和合并,查询效率最低(序列化和反序列化),可以直接存储,load的速度最快。
3.orc格式
建表语句
create table xx(
...
)
row format delimited
fields terminated by '\t'
stored as orc tblproperties("orc.compress"="NONE");snappy压缩:
stored as orc tblproperties("orc.compress"="SNAPPY");也可以通过alter table来设置
alter table xx set tblproperties('orc.bloom.filter.columns'='*','orc.compress'='SNAPPY');
orc是列式存储的。使用orc格式,可以降低磁盘存储空间,查询效率也不会差,建议使用orc的snappy压缩。
由于数据压缩,数据量变小,所以Job启动后生成的map,reduce数目也会变少,占用的container就会少,所以变相增加了集群的计算能力。
4.parquet
spark默认为parquet,具有很好的压缩性能,可以指定每一列的压缩方式, 可以减少大量的表扫描、序列化和反序列化的时间。支持复杂的嵌套数据烈性:json。
建表语句
create table xxx(
xxx
)
row format delimited
fields terminated by "\t"
stored as parquet
;--设置压缩格式为snappy,根据需要来设置压缩格式,默认不压缩
alter table xxx tblproperties('parquet.compression'='SNAPPY');
5.总结
1.textfile存储空间消耗比较大,并且压缩的text无法分割和合并。查询效率最低,因为要反序列化。可以直接存储, load数据的速度最高。
2.orc,查询效率高(二进制存储,不需要反序列化,是自解析的,且为列式存储)。load时需要将text转换成parquet,速度低。因为存储空间少,所以也减少了maptask reducetask,和container的数量,提高集群的计算能力。无论在存储还是查询上,orc都比parquet好。
3.parquet,查询效率高(二进制存储,不需要反序列化,是自解析的,且为列式存储)。load时需要将text转换成parquet,速度低。因为存储空间少,所以也减少了maptask reducetask,和container的数量,提高集群的计算能力。适配spark,impala。
[hive]hive优化相关推荐
- hive性能优化指南
1.概述 继续<hive性能优化指南--初级篇>一文中的剩余部分,本篇博客赘述了在工作中总结Hive的常用优化手段和在工作中使用Hive出现的问题.下面开始本篇文章的优化介绍. 2.介绍 ...
- Hive性能优化(全面)
1.介绍 首先,我们来看看Hadoop的计算框架特性,在此特性下会衍生哪些问题? 数据量大不是问题,数据倾斜是个问题. jobs数比较多的作业运行效率相对比较低,比如即使有几百行的表,如果多次关联多次 ...
- Hive 性能优化(全面)解决数据倾斜等问题
Hive性能优化(全面) 1.介绍 首先,我们来看看Hadoop的计算框架特性,在此特性下会衍生哪些问题? 数据量大不是问题,数据倾斜是个问题. jobs数比较多的作业运行效率相对比较低,比如即使有几 ...
- Hive性能优化(全面)解决数据倾斜等问题
Hive性能优化(全面) 1.介绍 首先,我们来看看Hadoop的计算框架特性,在此特性下会衍生哪些问题? 数据量大不是问题,数据倾斜是个问题. jobs数比较多的作业运行效率相对比较低,比如即使有几 ...
- Hive join 优化实战
由于 hive 与传统关系型数据库面对的业务场景及底层技术架构都有着很大差异,因此,传统数据库领域的一些技能放到 Hive 中可能已不再适用.关于 hive 的优化与原理.应用的文章,前面也陆陆续续的 ...
- 总结:Hive性能优化上的一些总结
Hive性能优化上的一些总结 注意,本文百分之九十来源于此文:Hive性能优化,很感谢作者的细心整理,其中有些部分我做了补充和追加,要是有什么写的不对的地方,请留言赐教,谢谢 前言 今天电话面试突然被 ...
- hive sql优化和shuffle过程优化
hive sql优化 sort by代替order by HiveSQL中的order by与其他SQL方言中的功能一样,就是将结果按某字段全局排序,这会导致所有map端数据都进入一个reducer中 ...
- 7.Hive性能优化及Hive3新特性
1.Hive表设计优化 分区表优化查询速度 分桶表优化join速度 索引优化(在Hive3后移除,了解即可) 2.Hive表数据优化 2.1 文件格式 概述 Hive数据存储的本质市HDFS,所有数据 ...
- Hive SQL优化思路分享
Hive的优化主要分为:配置优化.SQL语句优化.任务优化等方案. 其中在开发过程中主要涉及到的可能是SQL优化这块. 优化的核心思想是: 减少数据量(例如分区.列剪裁)避免数据倾斜(例如加参数.Ke ...
最新文章
- 局域网指定 IP 地址后无法上网的问题
- int数组初始化_Java中到底有没有多维数组
- Oracle闪回详解
- php中rsa加密及解密和签名及验签
- linux pe大小,lvm中的pe默认是4M 最大能支持多大 1T?2T
- 求约瑟夫环问题最后胜利者的一般解法以及数学推导方法
- AWS推出RoboMaker,可构建智能机器人应用程序
- win10安装ubuntu系统出现的一些问题以及解决方案
- php mysql 命令行模式_phpstudy(mysql命令行的增删改查)
- 网站地图(sitemap)在线生成
- vscode markdown preview enhanced css font
- php气泡效果,ps简单制作漂亮的人物气泡效果
- html 的scor属性,scrollheight属性
- 用友u8服务器修改ipv4,如何修改用友服务器ip地址
- 【智能无线小车系列十】智能小车一体化测试
- 网络基础知识 第一章上
- 动态获取织梦CMS最新更新 利于收录的SiteMap.php文件
- liunx服务器配置
- 机器人 抓取 Grasp Pose Detection (GPD) grasp类型转ROS的标准pose
- 重庆大学计算机学院 寝室,2020年重庆大学新生宿舍环境条件,大一新生男生女生宿舍内部图片【多图】...
热门文章
- 即将直播 | Pulsar Summit Asia 2022 峰会最新议程
- erlang nif windows x64 Failed to load NIF library : 'Unspecified error'
- 浪潮之巅第十四章 — 科技公司的吹鼓手:投资银行
- kotlin中的Map集合类
- Android day_06 (ListView的入门使用 了解数据适配Adapter以及打气筒的使用)
- js保留两位小数,整数不补零
- mysql 表的第2条到4条记录,mysql怎么查询第2到4条数据
- 听闻electron 打包可以让我费很长时间
- SQL2000恢复单MDF数据库过程
- 选择设计类培训学校的那些事儿