hive能够设置默认值吗

hive能够设置默认值吗,第1张

你的问题 是不是能描述的详细一点? 我只能猜测一下,你是不是想集成hive的元数据库,可以实现多用户,一般在这种情况下 建议集成mysql作为hive的元数据库,如果你需要具体的步骤,可以留下邮箱,我之前写过一份关于这方面的材料可以打给你,另外你在集成mysql作为元数据仓库的时候应该注意 hive配置文件里面的 *** 作用户配置 在mysql应该存在,另外在mysql里注意要去的匿名用户,否则会报 权限不足异常

注意:以下SQL不会转为Mapreduce来执行,Explain用于显示执行计划,可以来验证sql是否发生mapreduce

        select仅查询本表字段

        where仅对本表字段做条件过滤

比如下面的语句是会发生mapreduce的(下面的reduce没有截图)

        (1)集群模式:hive默认采用的是集群的方式

        (2)本地模式:首先开启本地模式,测试的时候就可以以本地模式来节省集群资源

                set hive.exec.mode.local.auto=true

        注意:hive.exec.mode.local.auto.inputbytes.max默认值为128M表示加载文件的最大值,若大于该配置仍会以集群方式来运行

通过设置以下参数开启并行模式:默认是不开启并行计算,这是job是线性执行的

set hive.exec.parallel=true多个job并行执行提高效率

注意:hive.exec.parallel.thread.number(一次SQL计算中允许并行执行的job个数的最大值)

通过设置以下参数开启严格模式:

set hive.mapred.mode=strict(默认为:nonstrict非严格模式)

开启严格模式后,查询会有限制:

    (1)对于分区表,必须添加where对于分区字段的条件过滤,因为hive中的数据量一般都很大,避免全表扫描不添加会执行失败,非分区表正常查询

    (2)order by语句必须包含limit输出限制;还是为了避免全表扫描

    (3)限制执行笛卡尔积的查询。

(1)Order By - 对于查询结果做全排序,只允许有一个reduce处理(当数据量较大时,应慎用。严格模式下,必须结合limit来使用)

(2)Sort  By - 对于单个reduce的数据进行排序

(3)Distribute By - 分区排序,经常和Sort By结合使用

(4)Cluster By - 相当于 Sort By +Distribute By(Cluster By不能通过asc、desc的方式指定排序规则;可通过 distribute by column sort by column asc|desc 的方式)

Join计算时,将小表(驱动表)放在join的左边

Map Join:在Map端完成Join,join *** 作对应mapreduce是reduce阶段,因为shuffle,跟reduce阶段比较浪费时间,所以才有了map  join

两种实现方式:

(1)SQL方式,在SQL语句中添加MapJoin标记(mapjoin hint)

(2)开启自动mapjoin : 通过修改以下配置启用自动的map join:

set hive.auto.convert.join = true(该参数为true时,Hive自动对左边的表统计量,如果是小表就加入内存,即对小表使用Map

join)

相关配置参数:

hive.mapjoin.smalltable.filesize(大表小表判断的阈值,如果表的大小小于该值则会被加载到内存中运行)

hive.ignore.mapjoin.hint;(默认值:true;是否忽略mapjoin hint 即mapjoin标记)

hive.auto.convert.join.noconditionaltask(默认值:true;将普通的join转化为普通的mapjoin时,是否将多个mapjoin转化为一个mapjoin)

hive.auto.convert.join.noconditionaltask.size(将多个mapjoin转化为一个mapjoin时,其表的最大值)    

通过设置以下参数开启在Map端的聚合:

set hive.map.aggr=true开启后,map预聚合,相当于map端reduce减轻reduce 端压力

相关配置参数:

hive.groupby.mapaggr.checkinterval:map端group by执行聚合时处理的多少行数据(默认:100000)

hive.map.aggr.hash.min.reduction:进行聚合的最小比例(预先对100000条数据做聚合,若聚合之后的数据量/100000的值大于该配置0.5,则不会聚合)

hive.map.aggr.hash.percentmemory:map端聚合使用的内存的最大值

hive.map.aggr.hash.force.flush.memory.threshold:map端做聚合 *** 作是hash表的最大可用内容,大于该值则会触发flush

hive.groupby.skewindata: 是否对GroupBy产生的数据倾斜做优化,默认为false,当设置为true时,会进行两次mr,第一次把数据map端随机分配分区,达到均衡数据的目的,第二次进行正常的分区算法执行mr

文件数目小,容易在文件存储端造成压力,给hdfs造成压力,影响效率

设置合并属性

        是否合并map输出文件:hive.merge.mapfiles=true

        是否合并reduce输出文件:hive.merge.mapredfiles=true

        合并文件的大小:hive.merge.size.per.task=256*1000*1000

去重统计

        数据量小的时候无所谓,数据量大的情况下,由于COUNT DISTINCT *** 作需要用一个Reduce

Task来完成,这一个Reduce需要处理的数据量太大,就会导致整个Job很难完成,一般COUNT DISTINCT使用先GROUP

BY再COUNT的方式替换

由于maptask的数量一般跟切片数量有关,所有我们主要对reduce端设置数量

Map数量相关的参数

        mapred.max.split.size: 一个split的最大值,即每个map处理文件的最大值

        mapred.min.split.size.per.node:一个节点上split的最小值

        mapred.min.split.size.per.rack:一个机架上split的最小值

Reduce数量相关的参数

        mapred.reduce.tasks:强制指定reduce任务的数量

        hive.exec.reducers.bytes.per.reducer:每个reduce任务处理的数据量

        hive.exec.reducers.max:每个任务最大的reduce数

适用场景:

        (1)小文件个数过多

        (2)task个数过多

通过 set mapred.job.reuse.jvm.num.tasks=n来设置(n为task插槽个数)个人理解优点类似于各种连接池的作用

缺点:设置开启之后,task插槽会一直占用资源,不论是否有task运行,直到所有的task即整个job全部执行完成时,才会释放所有的task插槽资源!

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和reduce处理之前组合小文件。

(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-reduce任务的输出合并,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=trueset 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社区找我们玩~


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/bake/11910081.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-19
下一篇 2023-05-19

发表评论

登录后才能评论

评论列表(0条)

保存