hive简介

6 篇文章 0 订阅
2 篇文章 0 订阅

1.HIVE基本概念

1.1 什么是 Hive

  • Hive:由 Facebook 开源用于解决海量结构化日志的数据统计
  • Hive 是基于 Hadoop 的一个数据仓库工具,可以将结构化的数据文件映射为一张表,并 提供类 SQL 查询功能
  • 本质是:将 HQL 转化成 MapReduce 程序
  1. Hive 处理的数据存储在 HDFS
  2. Hive 分析数据底层的实现是 MapReduce/Spark
  3. 执行程序运行在 Yarn 上

1.2 Hive 的优缺点

1.2.1 优点

  1. 操作接口采用类 SQL 语法,提供快速开发的能力(简单、容易上手)
  2. 避免了去写 MapReduce,减少开发人员的学习成本
  3. Hive 的执行延迟比较高,因此 Hive 常用于数据分析,对实时性要求不高的场合
  4. Hive 优势在于处理大数据,对于处理小数据没有优势,因为 Hive 的执行延迟比较高
  5. Hive 支持用户自定义函数,用户可以根据自己的需求来实现自己的函数

1.2.2 缺点

1.Hive 的 HQL 表达能力有限

  • 迭代式算法无法表达 
  • 数据挖掘方面不擅长

2.Hive 的效率比较低

  • Hive 自动生成的 MapReduce 作业,通常情况下不够智能化
  • Hive 调优比较困难,粒度较粗

1.3 Hive 架构原理

抽象图如下:


1.用户接口:Client
     CLI(hive shell)、JDBC/ODBC(java 访问 hive)、WEBUI(浏览器访问 hive)
2.元数据:Metastore
     元数据包括:表名、表所属的数据库(默认是 default)、表的拥有者、列/分区字段、表 的类型(是否是外部表)、表的数据所在目录等;
     默认存储在自带的 derby 数据库中,推荐使用 MySQL 存储 Metastore
3.Hadoop
    使用 HDFS 进行存储,使用 MapReduce 进行计算。
4.驱动器:Driver

  1. 解析器(SQL Parser):将 SQL 字符串转换成抽象语法树 AST,这一步一般都用第三方工具库完成,比如 antlr;对 AST 进行语法分析,比如表是否存在、字段是否存 在、SQL 语义是否有误。
  2. 编译器(Physical Plan):将 AST 编译生成逻辑执行计划。
  3. 优化器(Query Optimizer):对逻辑执行计划进行优化。 
  4. 执行器(Execution):把逻辑执行计划转换成可以运行的物理计划。对于 Hive 来说,就是 MR/Spark。

Hive通过给用户提供的一系列交互接口,接收到用户的指令(SQL),使用自己的Driver, 结合元数据(MetaStore),将这些指令翻译成 MapReduce,提交到 Hadoop 中执行,最后,将 执行返回的结果输出到用户交互接口

详细流程图如下:

官网地址

2.Hive安装地址

2.1安装步骤

请参考  安装文档

2.2注意

  • Metastore默认存储在自带的derby数据库中,此时一次只能打开一个窗口进行访问,启动多个窗口时会产生java.sql.SQLException异常
  • 企业级安装推荐mysql数据库存储元数据
  • HiveJDBC访问需要启动hiveserver2服务,测试如下:

// 1.启动服务

$ bin/hiveserver2

// 2.启动beeline

$bin/beeline

Beeline version 1.2.1 by Apache Hive

beeline>

// 3.连接hiveserver2

beeline> !connect jdbc:hive2://localhost:10000

Connected to: Apache Hive (version 1.2.1)

Driver: Hive JDBC (version 1.2.1)

Transaction isolation: TRANSACTION_REPEATABLE_READ

0: jdbc:hive2://hadoop102:10000> show databases;

3.Hive数据类型

3.1数据类型

请看官网

3.2类型转换

Hive的原子数据类型是可以进行隐式转换的,类似于Java的类型转换,例如某表达式使用INT类型,TINYINT会自动转换为INT类型,但是Hive不会进行反向转化,例如,某表达式使用TINYINT类型,INT不会自动转换为TINYINT类型,它会返回错误,除非使用CAST操作。

3.2.1.隐式类型转换规则(总结)

(1)任何整数类型都可以隐式地转换为一个范围更广的类型,如TINYINT可以转换成INT,INT可以转换成BIGINT。

(2)所有整数类型、FLOAT和STRING类型都可以隐式地转换成DOUBLE

(3)TINYINT、SMALLINT、INT都可以转换为FLOAT。

(4)BOOLEAN类型不可以转换为任何其它的类型。

3.2.2.可以使用CAST操作显示进行数据类型转换

例如CAST('1' AS INT)将把字符串'1' 转换成整数1;如果强制类型转换失败,如执行CAST('X' AS INT),表达式返回空值 NULL

3.2.3.可能的坑

上图为官网的隐式转换规则。

可以看到bigint可以映射转换成string;如果join时如果两边数据分别为bigint和string,bigint会自动转成string,可能有坑;其它转换亦如此

4.DDL数据定义

4.1概览

请参考  DDL (create/drop/alter/truncate/show/describe), Statistics (analyze)IndexesArchiving,

4.2管理表&外部表

4.2.1管理表

默认创建的表都是所谓的管理表,有时也被称为内部表。因为这种表,Hive会(或多或少地)控制着数据的生命周期。Hive默认情况下会将这些表的数据存储在由配置项hive.metastore.warehouse.dir(例如,/user/hive/warehouse)所定义的目录的子目录下。    当我们删除一个管理表时,Hive也会删除这个表中数据。管理表不适合和其他工具共享数据

4.2.2外部表

➢ 概念

因为表是外部表,所以Hive并非认为其完全拥有这份数据。删除该表并不会删除掉这份数据,不过描述表的元数据信息会被删除掉;如果外部表的表结构或者分区发生变化,则需要执行msck repair table命令对hive元数据进行修改

参考文档

➢ 使用场景

每天将收集到的网站日志定期流入HDFS文本文件。在外部表(原始日志表)的基础上做大量的统计分析,用到的中间表、结果表使用内部表存储,数据通过SELECT+INSERT进入内部表

4.2.3转换

(1)查询表的类型

hive (default)> desc formatted student2;

Table Type:             MANAGED_TABLE

(2)修改内部表student2为外部表

alter table student2 set tblproperties('EXTERNAL'='TRUE');

(3)查询表的类型

hive (default)> desc formatted student2;

Table Type:             EXTERNAL_TABLE

(4)修改外部表student2为内部表

alter table student2 set tblproperties('EXTERNAL'='FALSE');

(5)查询表的类型

hive (default)> desc formatted student2;

Table Type:             MANAGED_TABLE

注意:('EXTERNAL'='TRUE')('EXTERNAL'='FALSE')为固定写法,区分大小写!

4.3分区表&分桶表

4.3.1分区表

分区表实际上就是对应一个HDFS文件系统上的独立的文件夹,该文件夹下是该分区所有的数据文件。Hive中的分区就是分目录,把一个大的数据集根据业务需要分割成小的数据集。在查询时通过WHERE子句中的表达式选择查询所需要的指定的分区,这样的查询效率会提高很多

4.3.2分桶表

➢ 分区针对的是数据的存储路径;分桶针对的是数据文件:在同一个文件夹下分成不同的文件

➢使用场景

  1. 抽样
  2. bucket map join
  3. Sort Merge Bucket Join    请看 oralce&Hive join 简介

参考文档

5.DML数据操作

5.1概览

请参考  DML (load/insert/update/delete/mergeimport/exportexplain plan),

5.2 multiple inserts & dynamic partition

// 多路插入

Hive extension (multiple inserts):

FROM from_statement

INSERT OVERWRITE TABLE tablename1 [PARTITION (partcol1=val1, partcol2=val2 ...) [IF NOT EXISTS]] select_statement1

[INSERT OVERWRITE TABLE tablename2 [PARTITION ... [IF NOT EXISTS]] select_statement2]

[INSERT INTO TABLE tablename2 [PARTITION ...] select_statement2] ...;

 

// 动态分区

Hive extension (dynamic partition inserts):

INSERT OVERWRITE TABLE tablename PARTITION (partcol1[=val1], partcol2[=val2] ...) select_statement FROM from_statement;

INSERT INTO TABLE tablename PARTITION (partcol1[=val1], partcol2[=val2] ...) select_statement FROM from_statement;

6.SELECT

6.1概览

请参考  文档

6.2排序&分区

Order By:全局排序,一个Reducer

Sort By:每个Reduce内部排序

Distribute By:表示reduce时候按某些字段shuffle

Cluster By:当distribute by和sorts by字段相同时,可以使用cluster by方式

Partition By:分析函数的时候可以使用,可以理解为分组

6.3grouping sets、rollup、cube

GROUP BY a, b, c WITH CUBE  <=> GROUP BY a, b, c GROUPING SETS ( (a, b, c), (a, b), (b, c), (a, c), (a), (b), (c), ( ))


GROUP BY a, b, c, WITH ROLLUP is <=> GROUP BY a, b, c GROUPING SETS ( (a, b, c), (a, b), (a), ( ))

另外通过grouping__id可以确定按照什么分组,计算逻辑为求二进制矢量值,1代表参与聚合,0代表未参与聚合(2.3.0版本前相反) ;

如:() => (1,1,1) => (2^2 + 2^1 + 2^0) = 7

       (a,c)    => (0,1,0)  => (2^1) = 2

笔者在本地设置数据类型为int时,出现了bug,改成string后正常

说明:此语法为语法糖,相当于多个union all 的简写

参考文档   

6.4注意点

  • 只支持等值连接,不支持非等值连接
  • 连接谓词中不支持or

7.函数

7.1概览

请参考  文档

7.2自定义udf

请参考   hive中udf的编写  hive中udtf的编写及使用

8.压缩和存储

8.1Hadoop压缩配置

  • 为了支持多种压缩/解压缩算法
  • Hadoop引入了编码/解码器
  • 压缩性能的比较

你可以查看:   4.Hadoop数据压缩

8.2开启Map输出阶段压缩

// 1.开启hive中间传输数据压缩功能

hive (default)>set hive.exec.compress.intermediate=true;

// 2.开启mapreduce中map输出压缩功能

hive (default)>set mapreduce.map.output.compress=true;

//3.设置mapreduce中map输出数据的压缩方式

hive (default)>set mapreduce.map.output.compress.codec=org.apache.hadoop.io.compress.SnappyCodec;

8.3 开启Reduce输出阶段压缩

当Hive将输出写入到表中时,输出内容同样可以进行压缩。属性hive.exec.compress.output控制着这个功能。用户可能需要保持默认设置文件中的默认值false,这样默认的输出就是非压缩的纯文本文件了。用户可以通过在查询语句或执行脚本中设置这个值为true,来开启输出结果压缩功能

// 1.开启hive最终输出数据压缩功能

hive (default)>set hive.exec.compress.output=true;

// 2.开启mapreduce最终输出数据压缩

hive (default)>set mapreduce.output.fileoutputformat.compress=true;

// 3.设置mapreduce最终数据输出压缩方式

hive (default)> set mapreduce.output.fileoutputformat.compress.codec=org.apache.hadoop.io.compress.SnappyCodec;

// 4.设置mapreduce最终数据输出压缩为块压缩

hive (default)> set mapreduce.output.fileoutputformat.compress.type=BLOCK;

8.5 文件存储格式

Hive支持的存储数的格式主要有:TEXTFILE SEQUENCEFILEORCPARQUET

8.5.1列式存储和行式存储

1.行存储的特点

查询满足条件的一整行数据的时候,列存储则需要去每个聚集的字段找到对应的每个列的值,行存储只需要找到其中一个值,其余的值都在相邻地方,所以此时行存储查询的速度更快。

2.列存储的特点

因为每个字段的数据聚集存储,在查询只需要少数几个字段的时候,能大大减少读取的数据量;每个字段的数据类型一定是相同的,列式存储可以针对性的设计更好的设计压缩算法。

TEXTFILESEQUENCEFILE的存储格式都是基于行存储的;ORC和PARQUET是基于列式存储的

8.5.2 TextFile格式

默认格式,数据不做压缩,磁盘开销大,数据解析开销大。可结合GzipBzip2使用,但使用Gzip这种方式,hive不会对数据进行切分,从而无法对数据进行并行操作。

8.5.3 Orc格式

Orc (Optimized Row Columnar)Hive 0.11版里引入的新的存储格式。

如图所示可以看到每个Orc文件由1个或多个stripe组成,每个stripe250MB大小,这个Stripe实际相当于RowGroup概念,不过大小由4MB->250MB,这样应该能提升顺序读的吞吐率。每个Stripe里有三部分组成,分别是Index DataRow DataStripe Footer

 

      1Index Data:一个轻量级的index,默认是每隔1W行做一个索引。这里做的索引应该只是记录某行的各字段在Row Data中的offset

      2Row Data:存的是具体的数据,先取部分行,然后对这些行按列进行存储。对每个列进行了编码,分成多个Stream来存储。

      3Stripe Footer:存的是各个Stream的类型,长度等信息。

每个文件有一个File Footer,这里面存的是每个Stripe的行数,每个Column的数据类型信息等;每个文件的尾部是一个PostScript,这里面记录了整个文件的压缩类型以及FileFooter的长度信息等。在读取文件时,会seek到文件尾部读PostScript,从里面解析到File Footer长度,再读FileFooter,从里面解析到各个Stripe信息,再读各个Stripe,即从后往前读。

8.5.4 Parquet格式

Parquet是面向分析型业务的列式存储格式,由TwitterCloudera合作开发,20155月从Apache的孵化器里毕业成为Apache顶级项目。

Parquet文件是以二进制方式存储的,所以是不可以直接读取的,文件中包括该文件的数据和元数据,因此Parquet格式文件是自解析的。

通常情况下,在存储Parquet数据的时候会按照Block大小设置行组的大小,由于一般情况下每一个Mapper任务处理数据的最小单位是一个Block,这样可以把每一个行组由一个Mapper任务处理,增大任务执行并行度

                                                    Parquet格式

上图展示了一个Parquet文件的内容,一个文件中可以存储多个行组,文件的首位都是该文件的Magic Code,用于校验它是否是一个Parquet文件,Footer length记录了文件元数据的大小,通过该

值和文件长度可以计算出元数据的偏移量,文件的元数据中包括每一个行组的元数据信息和该文件存储数据的Schema信息。除了文件中每一个行组的元数据,每一页的开始都会存储该页的元数

据,在Parquet中,有三种类型的页:数据页、字典页和索引页。数据页用于存储当前行组中该列的值,字典页存储该列值的编码字典,每一个列块中最多包含一个字典页,索引页用来存储当前行

组下该列的索引,目前Parquet中还不支持索引页

8.5.5 存储方式和压缩总结

在实际的项目开发当中,hive表的数据存储格式一般选择:orcparquet。压缩方式一般选择snappylzo

您可以查看 File Formats and Compression:  RCFileAvroORCParquetCompressionLZO

9.企业级调优

9.1Fetch抓取

Fetch抓取是指,Hive中对某些情况的查询可以不必使用MapReduce计算。例如:SELECT * FROM employees;在这种情况下,Hive可以简单地读取employee对应的存储目录下的文件,然后输

查询结果到控制台。

在hive-default.xml.template文件中hive.fetch.task.conversion默认是more,老版本hive默认是minimal,该属性修改为more以后,在全局查找、字段查找、limit查找等都不走mapreduce

<property>

    <name>hive.fetch.task.conversion</name>

    <value>more</value>

    <description>

      Expects one of [none, minimal, more].

      Some select queries can be converted to single FETCH task minimizing latency.

      Currently the query should be single sourced not having any subquery and should not have

      any aggregations or distincts (which incurs RS), lateral views and joins.

      0. none : disable hive.fetch.task.conversion

      1. minimal : SELECT STAR, FILTER on partition columns, LIMIT only

      2. more  : SELECT, FILTER, LIMIT only (support TABLESAMPLE and virtual columns)

    </description>

  </property>

9.2 本地模式

大多数的Hadoop Job是需要Hadoop提供的完整的可扩展性来处理大数据集的。不过,有时Hive的输入数据量是非常小的。在这种情况下,为查询触发执行任务消耗的时间可能会比实际job的执行

时间要多的多。对于大多数这种情况,Hive可以通过本地模式在单台机器上处理所有的任务。执行时间可以明显被缩短

set hive.exec.mode.local.auto=true;  //开启本地mr

//设置local mr的最大输入数据量,当输入数据量小于这个值时采用local  mr的方式,默认为134217728,即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;

只有当hive.exec.mode.local.auto.inputbytes.max和hive.exec.mode.local.auto.input.files.max同时满足时才能开启本地模式

笔者测试发现,当开启本地模式时mr任务并未提交yarn集群处理,因此速度较快

9.3 表的优化

请参考  hive任务优化

9.4 严格模式

Hive提供了一个严格模式,可以防止用户执行那些可能意想不到的不好的影响的查询。

<property>

    <name>hive.mapred.mode</name>

    <value>strict</value>

    <description>

      The mode in which the Hive operations are being performed.

      In strict mode, some risky queries are not allowed to run. They include:

        Cartesian Product

        No partition being picked up for a query.

        Comparing bigints and strings.

        Comparing bigints and doubles.

        Orderby without limit.

</description>

通过设置属性hive.mapred.mode值为默认是非严格模式nonstrict 。开启严格模式需要修改hive.mapred.mode值为strict,开启严格模式可以禁止3种类型的查询

  1. 对于分区表,除非where语句中含有分区字段过滤条件来限制范围,否则不允许执行
  2. 对于使用了order by语句的查询,要求必须使用limit语句
  3. 限制笛卡尔积的查询。对关系型数据库非常了解的用户可能期望在执行JOIN查询的时候不使用ON语句而是使用where语句,这样关系数据库的执行优化器就可以高效地将WHERE语句转化成那个ON语句。不幸的是,Hive并不会执行这种优化,因此,如果表足够大,那么这个查询就会出现不可控的情况

9.5 JVM重用

JVM重用是Hadoop调优参数的内容,其对Hive的性能具有非常大的影响,特别是对于很难避免小文件的场景或task特别多的场景,这类场景大多数执行时间都很短。

Hadoop的默认配置通常是使用派生JVM来执行map和Reduce任务的。这时JVM的启动过程可能会造成相当大的开销,尤其是执行的job包含有成百上千task任务的情况。JVM重用可以使得JVM实例

在同一个job中重新使用N次。N的值可以在Hadoop的mapred-site.xml文件中进行配置。通常在10-20之间,具体多少需要根据具体业务场景测试得出。

<property>

  <name>mapreduce.job.jvm.numtasks</name>

  <value>10</value>

  <description>How many tasks to run per jvm. If set to -1, there is  no limit.

  </description>

</property>

这个功能的缺点是,开启JVM重用将一直占用使用到的task插槽,以便进行重用,直到任务完成后才能释放。如果某个“不平衡的”job中有某几个reduce task执行的时间要比其他Reduce task消耗的

时间多的多的话,那么保留的插槽就会一直空闲着却无法被其他的job使用,直到所有的task都结束了才会释放

9.6 推测执行

在分布式集群环境下,因为程序Bug(包括Hadoop本身的bug),负载不均衡或者资源分布不均等原因,会造成同一个作业的多个任务之间运行速度不一致,有些任务的运行速度可能明显慢于其他任务(比如一个作业的某个任务进度只有50%,而其他所有任务已经运行完毕),则这些任务会拖慢作业的整体执行进度。为了避免这种情况发生,Hadoop采用了推测执行(Speculative Execution)机制,它根据一定的法则推测出“拖后腿”的任务,并为这样的任务启动一个备份任务,让该任务与原始任务同时处理同一份数据,并最终选用最先成功运行完成任务的计算结果作为最终结果。

设置开启推测执行参数:Hadoop的mapred-site.xml文件中进行配置

<property>

  <name>mapreduce.map.speculative</name>

  <value>true</value>

  <description>If true, then multiple instances of some map tasks may be executed in parallel.</description>

</property>

<property>

  <name>mapreduce.reduce.speculative</name>

  <value>true</value>

  <description>If true, then multiple instances of some reduce tasks may be executed in parallel.</description>

</property>

不过hive本身也提供了配置项来控制reduce-side的推测执行:

  <property>

    <name>hive.mapred.reduce.tasks.speculative.execution</name>

    <value>true</value>

    <description>Whether speculative execution for reducers should be turned on. </description>

  </property>

关于调优这些推测执行变量,还很难给一个具体的建议。如果用户对于运行时的偏差非常敏感的话,那么可以将这些功能关闭掉。如果用户因为输入数据量很大而需要执行长时间的map或者

Reduce task的话,那么启动推测执行造成的浪费是非常巨大大。

9.7 压缩

见第8章

9.8 执行计划(Explain)

explain [extended | dependency | authorization] query

没事多看看执行计划

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值