① 数仓--Hive-面试之Hive设置配置参数的方法,列举8个常用配置
上述三种设定方式的优先级依次递增。即参数声明覆盖命令行参数,命令行参数覆盖配置文件设定。
这8个牢牢的背住吧,面试会被问道的
② Hive(五)之Hive-ef参数操作
假设公司让你定时在凌晨3点执行hive的数据清洗操作,执行完第一个任务紧接着执行第二个任务,如何让hive定时执行这样的操作?
主要用于排查逻辑错误或者查看常用命令
固定语法:set 属性名=属性值
例如:set hive.cli.print.header=false;
集群数据迁移的时候,需要对当前某个目录下的数据进行迁移,要对数据进行分开管理,这时候就要用到 location 的关键字
hive默认创建的是内部表( inner):
显示指定: external
hive > show tables -> 所展示出来的信息依赖于元数据信息,metastore中有的数据才能够进行show等操作。
删除外部表是不会删除数据本身的,是将metastore中的元数据删除,只是将数据和字段的双射关系删除(我的理解)。
③ hive 建表方式及参数详解
hive中有两种表:外部表和内部表(managed and external)。可以通过 desc formatted table_name 命令来查看表的信息,来辨别表是外部表还是内部表。 在hive默认创建到表是内部表,外部表创建需要加 EXTERNAL 命令,如: CREATE EXTERNAL table_name 。
内部表的文件,元数据和统计信息等由hive进行管理,一般被存储在 hive.metastore.warehouse.dir 目录下,当表被删除或者分区被删除,相对应的数据和元数据就会被删除。一般用来当做临时表。
外部表与内部表相反,可以指定location,可以不基于hive来操作外部表文件。当表被删除或者分区被删除时对应的数据还会存在。只是hive删除了其元信息,表的数据文件依然存在于文件系统中。若是表被删除,可以重新建这个表,指定location到数据文件处,然后通过msck repair table table_name命令刷新数据的元信息到hive中,也就是恢复了数据。
msck repair table 的详细用法就不讲了,可以参考 HIVE常用命令之MSCK REPAIR TABLE命令简述
④ Hive调优参数篇
工作中常用的 hive 参数调优,整理如下。
原则:
• 最少数据
• 最少字段
• 最少Job数
• 最少读取次数
• 避免数据倾斜
• 整体最优而不是局部最优
• JVM 内存
这里需要结合集群的资源来合理的设置切片大小。
最小数据
最小数据原则:(map阶段,shuffle阶段,rece阶段)
set hive.optimize.skewjoin=true;
磁盘的频繁IO也是一种不小的消耗,所以可以通过配置一些参数来减少磁盘的IO
⑤ 如何彻底删除hive以及配置好的环境变量
Copyright © 1999-2020, CSDN.NET, All Rights Reserved
搜索博文/帖子/用户
登录
奇子君
关注
hive 设置环境变量的方法总结 原创
2020-02-19 14:02:47
奇子君
码龄10年
关注
Hive提供三种可以改变环境变量的方法:
1.配置文件:修改${HIVE_HOME}/conf/hive-site.xml配置文件;
在Hive中,所有的默认配置都在${HIVE_HOME}/conf/hive-default.xml文件中,如果需要对默认的配置进行修改,可以创建一个hive-site.xml文件,放在${HIVE_HOME}/conf目录下。里面可以对一些配置进行个性化设定。在hive-site.xml的格式如下:
绝大多少配置都是在xml文件里面配置的,这里做的配置都全局用户都生效。用户自定义配置会覆盖默认配置。另外,Hive也会读入Hadoop的配置,因为Hive是作为Hadoop的客户端启动的,Hive的配置会覆盖Hadoop的配置。
2. 命令行参数:在启动Hive cli的时候进行配置,可以在命令行添加-hiveconf param=value来设定参数,例如:
hive --hiveconf maprece.job.queuename=queue
在Hive中所有MapRece作业都提交到队列queue中。这一设定对本次启动的会话有效,下次启动需要重新配置。
3. 参数申明:在已经进入cli时进行参数声明,可以在HQL中使用SET关键字设定参数,例如:
hive> set maprece.job.queuename=queue;
这种配置也是对本次启动的会话有效,下次启动需要重新配置。
上述三种设定方式的优先级依次递增。即参数声明覆盖命令行参数,命令行参数覆盖配置文件设定。
⑥ 2060s hivesos设置
有以下5种方法。
_
1.在${HIVE_HOME}/conf/hive-site.xml文件中添加参数设置。
2.在启动hivecli时,通过_hiveconfkey=value的方式进行设置。
3.在进入到cli之后,通过set命令设置。
4.hive-d。
5.hive参数初始化设置在当前用户的家目录下创建**.hiverc**文件,在当前文件中设置hive参数的命令,每次进入hivecli的时候,都会加载.hiverc的文件,执行文件中的命令。
⑦ hive性能优化及参数调优
记录一下自己在工作中经常用到的几个参数设置,从调整的实际效果看还是有效果的。
企业相关服务器资源配置:平均600台active的节点,
每个节点可用的内存在200G左右,可用的memory total:116T
1、**set hive.exec.parallel=true;**
开启job的并行:基本每个hql脚本都会开启这个参数,默认并行度为8,
在集群资源充足的情况下,可以提高job并行的数量:
set hive.exec.parallel.thread.number=16; (企业生产中我是很少用到这个的,都是用的默认值,因为太消耗资源怕影响别的任务,搞不好会被运维抓住,邮件通报批评!当然使用时还是看具体情况吧!)
因为需求中一张表的job的数量每次基本都在20个以上,在相关维度多,涉及到的字段逻辑复杂的情况下,
一张表中job的数量会超过100个,之前做的一个需求中insert插入的脚本中job的数量达到了169个,
在测试环境运行的时候只用了一个小时就跑完了,数据量在一亿条左右,大概有一百多G。
2、**set hive.map.aggr=true;**
在map端中会做部分聚集操作,效率更高但需要更多的内存,可以根据自己企业的资源情况来设置,
如果我的脚本涉及到的数据量不大的话,我一般不会开启这个参数。
3、**set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;**
hive0.5开始的默认值,执行map前进行小文件合并,在一个job中生成的map的数量很多的时候,
和第二个参数一起开启配合使用,在实际生产中多次验证发现可以减少一倍以上的map数量。
在开启前我的一个job的map数量有577个,开启后的map的数量只有196个,极大提高程序的运行效率。
4、**set mapred.max.split.size=256000000;**
每个Map(一个切片的)最大输入大小(这个值决定了合并后文件的数量),和第3个参数配合一起使用
默认值也是256000000,
mapred.min.split.size默认值是10000000
dfs.block.size默认是128M,这个参数通过hive来更改是没有实际用的,只能通过hdfs来修改
***实际在hive中,并不是split的大小要小于等于blocksize,而是可以远大于blocksize,为什么???(map的数量)***
<1>当hive需要处理的文件是压缩,且压缩算法不支持文件切分的时候,决定map个数的因素主要是文件块实际存储的大小,
如果文件块本身很大,比如500Mb左右,那么每个map处理的splitsize至少要是500Mb左右。
这个时候我们不能人为通过参数降低每个map的splitsize来增加map个数,只能通过增加splitsize,减少map个数,
如果hive处理的文件是压缩模式,且压缩模式不支持文件切分,那么这个时候我们只能通过控制参数来减少map个数,而不能通过配置参数来增加map个数,所以Hive对于压缩不可切分文件的调优有限
<2>如果Hive处理的的文件为非压缩格式或者压缩可切分,且inputFormat为CombineHiveInputFormat时,
则控制map个数是由以下四个参数起作用,关于这四个参数作用优先级与使用注意事项请参考如下:
一般来讲这几个参数的结果大小要满足以下条件:
max.split.size >= min.split.size >= min.size.per.node >= min.size.per.rack
几个参数的作用优先级为:
max.split.size <= min.split.size <= min.size.per.node <= min.size.per.rack
总结:所以对于控制map的个数进行调优,首先需要看是否开启了压缩,压缩算法是否支持切分,参数的设置等等!
5、**set mapred.min.split.size.per.node=256000000;**
一个节点上split的至少的大小(这个值决定了多个DataNode上的文件是否需要合并) ,
和第3和第4个参数一起配合使用。
6、**set mapred.min.split.size.per.rack=256000000;**
一个交换机下split的至少的大小(这个值决定了多个交换机上的文件是否需要合并) ,
也适合第3,4,5的参数一起配合使用。
7、**set hive.exec.mode.local.auto=true;**
开启本地模式,这个参数在自己学习中可能经常用到,但是在实际生产中用到的还是比较少,
因为这个参数开启后,针对的是小数据集,在单台机器上处理所有的任务,对生产中的任务不适用!
8、**set hive.exec.recers.bytes.per.recer=512*1000*1000;**
每个rece任务处理的数据量,默认为256M,在hive0.14.0之前默认是1G,我们公司设置的是512M,写的是512*1000*1000因为在网络传输中用的是1000,而不是1024机制,
将该参数值调小可以增加rece的数量,提高运行的效率,
当然也不是rece的数量越多越好,因为启动和初始化rece都是会消耗资源和时间的,
而且有多少个rece就会有多少个输出文件,如果这些文件作为下一个任务的输入,就会造成小文件过多的问题
9、**hive.exec.recers.max**
每个任务最大的rece数,默认为1009,在hive0.14.0之前默认是999
计算recer数的公式很简单N=min(参数9,总输入数据量/参数8)
即,如果rece的输入(map的输出)总大小不超过1G,那么只会有一个rece任务;
10、**set mapred.rece.tasks = 15;**
设置rece的个数(在实际生产中谨慎使用)
那么什么时候可以进行手动设定rece数量呢?比如系统自动计算的rece个数,因为集群资源不足,
造成程序运行出现OOM(内存溢出不足)时,可以根据推定的rece个数手动增加数量,保证程序在跑的慢的基础上可以完整运行
那么在什么情况下只有一个rece呢?
<1>、当map的输出文件小于hive.exec.recers.bytes.per.recer时
<2>、手动设置set mapred.rece.tasks =1时
<3>、使用了order by时(全局排序会使用一个rece去处理)
<4>、表关联时出现笛卡尔积
<5>、单独使用count时,比如:select count(*) from tablename,
如果改写加入了group by配合使用就不会出现一个rece,比如:select sign_date,count(*) from tablename group by sign_date;
11、**set mapred.job.reuse.jvm.num.tasks=10;**
用于避免小文件的场景或者task特别多的场景,这类场景大多数执行时间都很短,因为hive调起maprece任务,JVM的启动过程会造成很大的开销,尤其是job有成千上万个task任务时,JVM重用可以使得JVM实例在同一个job中重新使用N次
12、**set hive.exec.dynamic.partition=true;**
表示开启动态分区功能
13、**set hive.exec.dynamic.partition.mode=nonstrict;**
表示允许所有分区都是动态的,
默认是strict,表示必须保证至少有一个分区是静态的
14、**set hive.groupby.skewindata=true;**
有数据倾斜的时候进行负载均衡 ,决定group by操作是否支持倾斜数据,其实说白了就相当于MR中的conbiner做了一次预聚合。
注意:只能对单个字段聚合。
控制生成两个MR Job,第一个MR Job Map的输出结果随机分配到rece中减少某些key值条数过多某些key条数过小造成的数据倾斜问题。
在第一个 MapRece 中,map 的输出结果集合会随机分布到 rece 中, 每个rece 做部分聚合操作,并输出结果。这样处理的结果是,相同的 Group By Key 有可能分发到不同的rece中,从而达到负载均衡的目的;
第二个 MapRece 任务再根据预处理的数据结果按照 Group By Key 分布到 rece 中(这个过程可以保证相同的 Group By Key 分布到同一个 rece 中),最后完成最终的聚合操作
15、**set hive.auto.convert.join=true;**
开启map join
16、**set hive.mapjoin.smalltable.filesize=512000000;**
map join的小表的大小,也是开启和关闭map join的阈值
17、**hive.exec.compress.output=true;**
开启压缩,我们公司使用的是默认的压缩算法deflate
压缩算法有:<1>、org.apache.hadoop.io.compress.GzipCodec,
<2>、org.apache.hadoop.io.compress.DefaultCodec,
<3>、com.hadoop.compression.lzo.LzoCodec,
<4>、com.hadoop.compression.lzo.LzopCodec,
<5>、org.apache.hadoop.io.compress.BZip2Codec
使用的压缩算法:
set maprece.output.fileoutputformat.compress.codec=org.apache.hadoop.io.compress.DefaultCodec
**针对上述小文件合并的三个参数值做以下解释:**
大于文件块大小128m的,按照128m来分隔,小于128m,大于100m的,按照100m来分隔,把那些小于100m的(包括小文件和分隔大文件剩下的),进行合并
⑧ Hive优化之Hive的配置参数优化
Hive是大数据领域常用的组件之一,主要用于大数据离线数仓的运算,关于Hive的性能调优在日常工作和面试中是经常涉及的一个点,因此掌握一些Hive调优是必不可少的一项技能。影响Hive效率的主要因素有数据倾斜、数据冗余、job的IO以及不同底层引擎配置情况和Hive本身参数和HiveSQL的执行等。本文主要从建表配置参数方面对Hive优化进行讲解。
1. 创建一个普通表
table test_user1(id int, name string,code string,code_id string ) ROW FORMAT DELIMITED FIELDS TERMINATED BY ',';
2. 查看这张表的信息
DESCRIBE FORMATTED test_user1;
我们从该表的描述信息介绍建表时的一些可优化点。
2.1 表的文件数
numFiles表示表中含有的文件数,当文件数过多时可能意味着该表的小文件过多,这时候我们可以针对小文件的问题进行一些优化,HDFS本身提供了解决方案:
(1)Hadoop Archive/HAR:将小文件打包成大文件。
(2)SEQUENCEFILE格式:将大量小文件压缩成一个SEQUENCEFILE文件。
(3)CombineFileInputFormat:在map和rece处理之前组合小文件。
(4)HDFS Federation:HDFS联盟,使用多个namenode节点管理文件。
除此之外,我们还可以通过设置hive的参数来合并小文件。
(1)输入阶段合并
需要更改Hive的输入文件格式,即参数hive.input.format,默认值是org.apache.hadoop.hive.ql.io.HiveInputFormat,我们改成org.apache.hadoop.hive.ql.io.CombineHiveInputFormat。这样比起上面对mapper数的调整,会多出两个参数,分别是mapred.min.split.size.per.node和mapred.min.split.size.per.rack,含义是单节点和单机架上的最小split大小。如果发现有split大小小于这两个值(默认都是100MB),则会进行合并。具体逻辑可以参看Hive源码中的对应类。
(2)输出阶段合并
直接将hive.merge.mapfiles和hive.merge.mapredfiles都设为true即可,前者表示将map-only任务的输出合并,后者表示将map-rece任务的输出合并,Hive会额外启动一个mr作业将输出的小文件合并成大文件。另外,hive.merge.size.per.task可以指定每个task输出后合并文件大小的期望值,hive.merge.size.smallfiles.avgsize可以指定所有输出文件大小的均值阈值,默认值都是1GB。如果平均大小不足的话,就会另外启动一个任务来进行合并。
2.2 表的存储格式
通过InputFormat和OutputFormat可以看出表的存储格式是TEXT类型,Hive支持TEXTFILE, SEQUENCEFILE, AVRO, RCFILE, ORC,以及PARQUET文件格式,可以通过两种方式指定表的文件格式:
(1)CREATE TABLE ... STORE AS <file_format>:在建表时指定文件格式,默认是TEXTFILE
(2)ALTER TABLE ... [PARTITION partition_spec] SET FILEFORMAT <file_format>:修改具体表的文件格式
如果要改变创建表的默认文件格式,可以使用set
hive.default.fileformat=<file_format>进行配置,适用于所有表。同时也可以使用set
hive.default.fileformat.managed = <file_format>进行配置,仅适用于内部表或外部表。
扩展:不同存储方式的情况
TEXT,
SEQUENCE和
AVRO文件是面向行的文件存储格式,不是最佳的文件格式,因为即便只查询一列数据,使用这些存储格式的表也需要读取完整的一行数据。另一方面,面向列的存储格式(RCFILE,
ORC, PARQUET)可以很好地解决上面的问题。关于每种文件格式的说明,如下:
(1)TEXTFILE
创建表时的默认文件格式,数据被存储成文本格式。文本文件可以被分割和并行处理,也可以使用压缩,比如GZip、LZO或者Snappy。然而大部分的压缩文件不支持分割和并行处理,会造成一个作业只有一个mapper去处理数据,使用压缩的文本文件要确保文件不要过大,一般接近两个HDFS块的大小。
(2)SEQUENCEFILE
key/value对的二进制存储格式,sequence文件的优势是比文本格式更好压缩,sequence文件可以被压缩成块级别的记录,块级别的压缩是一个很好的压缩比例。如果使用块压缩,需要使用下面的配置:set
hive.exec.compress.output=true; set io.seqfile.compression.type=BLOCK
(3)AVRO
二进制格式文件,除此之外,avro也是一个序列化和反序列化的框架。avro提供了具体的数据schema。
(4)RCFILE
全称是Record Columnar File,首先将表分为几个行组,对每个行组内的数据进行按列存储,每一列的数据都是分开存储,即先水平划分,再垂直划分。
(5)ORC
全称是Optimized Row Columnar,从hive0.11版本开始支持,ORC格式是RCFILE格式的一种优化的格式,提供了更大的默认块(256M)
(6)PARQUET
另外一种列式存储的文件格式,与ORC非常类似,与ORC相比,Parquet格式支持的生态更广,比如低版本的impala不支持ORC格式。
配置同样数据同样字段的两张表,以常见的TEXT行存储和ORC列存储两种存储方式为例,对比执行速度。
TEXT存储方式
总结: 从上图中可以看出列存储在对指定列进行查询时,速度更快, 建议在建表时设置列存储的存储方式 。
2.3 表的压缩
对Hive表进行压缩是常见的优化手段,一些存储方式自带压缩选择,比如SEQUENCEFILE支持三种压缩选择:NONE,RECORD,BLOCK。Record压缩率低,一般建议使用BLOCK压缩;
ORC支持三种压缩选择:NONE,ZLIB,SNAPPY。我们以TEXT存储方式和ORC存储方式为例,查看表的压缩情况。
配置同样数据同样字段的四张表,一张TEXT存储方式,另外三张分别是默认压缩方式的ORC存储、SNAPPY压缩方式的ORC存储和NONE压缩方式的ORC存储,查看在hdfs上的存储情况:
TEXT存储方式
默认压缩ORC存储方式
SNAPPY压缩的ORC存储方式
NONE压缩的ORC存储方式
总结 :可以看到ORC存储方式将数据存放为两个block,默认压缩大小加起来134.69M,SNAPPY压缩大小加起来196.67M,NONE压缩大小加起来247.55M,TEXT存储方式的文件大小为366.58M,且默认block两种存储方式分别为256M和128M,ORC默认的压缩方式比SNAPPY压缩得到的文件还小,原因是ORZ默认的ZLIB压缩方式采用的是deflate压缩算法,比Snappy压缩算法得到的压缩比高,压缩的文件更小。 ORC不同压缩方式之间的执行速度,经过多次测试发现三种压缩方式的执行速度差不多,所以建议采用ORC默认的存储方式进行存储数据。
2.4 分桶分区
Num Buckets表示桶的数量,我们可以通过分桶和分区操作对Hive表进行优化:
对于一张较大的表,可以将它设计成分区表,如果不设置成分区表,数据是全盘扫描的,设置成分区表后,查询时只在指定的分区中进行数据扫描,提升查询效率。要注意尽量避免多级分区,一般二级分区足够使用。常见的分区字段:
(1)日期或者时间,比如year、month、day或者hour,当表中存在时间或者日期字段时,可以使用些字段。
(2)地理位置,比如国家、省份、城市等
(3)业务逻辑,比如部门、销售区域、客户等等
与分区表类似,分桶表的组织方式是将HDFS上的一张大表文件分割成多个文件。分桶是相对分区进行更细粒度的划分,分桶将整个数据内容按照分桶字段属性值得hash值进行区分,分桶可以加快数据采样,也可以提升join的性能(join的字段是分桶字段),因为分桶可以确保某个key对应的数据在一个特定的桶内(文件),所以巧妙地选择分桶字段可以大幅度提升join的性能。通常情况下,分桶字段可以选择经常用在过滤操作或者join操作的字段。
创建分桶表
create
table test_user_bucket(id int, name string,code string,code_id string )
clustered by(id) into 3 buckets ROW FORMAT DELIMITED FIELDS TERMINATED
BY ',';
查看描述信息
DESCRIBE FORMATTED test_user_bucket
多出了如下信息
查看该表的hdfs
同样的数据查看普通表和分桶表查询效率
普通表
分桶表
普通表是全表扫描,分桶表在按照分桶字段的hash值分桶后,根据join字段或者where过滤字段在特定的桶中进行扫描,效率提升。
本文首发于: 数栈研习社
数栈是云原生—站式数据中台PaaS,我们在github上有一个有趣的开源项目: FlinkX
FlinkX是一个基于Flink的批流统一的数据同步工具,既可以采集静态的数据,比如MySQL,HDFS等,也可以采集实时变化的数据,比如MySQL
binlog,Kafka等,是全域、异构、批流一体的数据同步引擎,大家如果有兴趣,欢迎来github社区找我们玩~