Hive总结

一、什么是Hive

1、Hive 由 Facebook 实现并开源

2、是基于 Hadoop 的一个数据仓库

3、可以将结构化的数据映射为一张数据库表

4、并提供 HQL(Hive SQL)查询功能

5、底层数据是存储在 HDFS 上

6、Hive的本质是将SQL语句转换为 MapReduce 任务运行

7、使不熟悉 MapReduce 的用户很方便地利用 HQL 处理和计算 HDFS 上的结构化的数据,适用于离线的批量数据计算。

二、为什么使用Hive

简化复杂的MapReduce实现过程,只需构造合适的HiveQL查询语句,实现数据的离线分析功能。

直接使用 MapReduce 所面临的问题:

  1、人员学习成本太高

  2、项目周期要求太短

  3、MapReduce实现复杂查询逻辑开发难度太大

使用 Hive:

  1、更友好的接口:操作接口采用类 SQL 的语法,提供快速开发的能力

  2、更低的学习成本:避免了写 MapReduce,减少开发人员的学习成本

  3、更好的扩展性:可自由扩展集群规模而无需重启服务,还支持用户自定义函数

Hive应用场景:

  1、数据挖掘:用户行为分析;兴趣分区;区域展示;

  2、非实时分析:日志分析;文本分析。

  3、数据汇总:每天/每周用户点击数,流量统计。

  4、数据仓库:数据抽取,加载,转换(ETL)。

三、Hive的特点

优点:

  1、 可扩展性:Hive 可以自由的扩展集群的规模,一般情况下不需要重启服务

  2、延展性:支持自定义函数,用户可以根据自己的需求来实现自己的函数

  3、良好的容错性:可以保障即使有节点出现问题,SQL语句仍可完成执行

缺点:

  1、不支持记录级别的增删改操作:但是用户可以通过查询生成新表或者将查询结果导入到文件中(INSERT INTO 在version 0.8以后支持,INSERT INTO|OVERWRITE就是在表或分区中追加数据,并不是经典数据库中的insert into操作,只是insert into单词一样。)

  2、Hive 的查询延时很严重:因为MapReduce Job 的启动过程消耗很长时间,所以不能用在交互查询系统中。

  3、Hive 不支持事务:因为没有增删改,所以主要用来做 OLAP(联机分析处理),而 不是 OLTP(联机事务处理)。

Hive 和 RDBMS 的对比

 

四、Hive的架构

 

执行流程

HiveQL 通过命令行或者客户端提交,经过 Compiler 编译器,运用 MetaStore 中的元数据进行类型检测和语法分析,生成一个逻辑方案(Logical Plan),然后通过的优化处理,产生一个 MapReduce 任务。

 

Hive的内部架构由四部分组成:

 

1、用户接口: shell/CLI, jdbc/odbc, webui

(1)CLI,Shell 终端命令行(Command Line Interface),采用交互形式使用 Hive 命令行与 Hive 进行交互,最常用(学习,调试,生产)

  (2)JDBC/ODBC,是 Hive 的基于 JDBC 操作提供的客户端,用户(开发员,运维人员)通过 这连接至 Hive server 服务

(3)Web UI,通过浏览器访问 Hive

 

2、跨语言服务

thrift server 提供了一种能力,让用户可以使用多种不同的语言来操纵hive

  Thrift 是 Facebook 开发的一个软件框架,可以用来进行可扩展且跨语言的服务的开发, Hive 集成了该服务,能让不同的编程语言调用 Hive 的接口

 

3、底层的Driver

驱动器Driver,编译器Compiler,优化器Optimizer,执行器Executor

Driver 组件完成 HQL 查询语句从词法分析,语法分析,编译,优化,以及生成逻辑执行 计划的生成。生成的逻辑执行计划存储在 HDFS 中,并随后由 MapReduce 调用执行

  Hive 的核心是驱动引擎, 驱动引擎由四部分组成:

    (1) 解释器:解释器的作用是将 HiveSQL 语句转换为抽象语法树(AST)

    (2) 编译器:编译器是将语法树编译为逻辑执行计划

    (3) 优化器:优化器是对逻辑执行计划进行优化

    (4) 执行器:执行器是调用底层的运行框架执行逻辑执行计划

 

4、元数据存储系统 : RDBMS (MySQL)

  元数据,通俗的讲,就是存储在 Hive 中的数据的描述信息。

  Hive 中的元数据通常包括:表的名字,表的列和分区及其属性,表的属性(内部表和 外部表),表的数据所在目录

  Metastore 默认存在自带的 Derby 数据库中。缺点就是不适合多用户操作,并且数据存 储目录不固定。数据库跟着 Hive 走,极度不方便管理

  解决方案:通常存我们自己创建的 MySQL 库(本地 或 远程)

Hive 和 MySQL 之间通过 MetaStore 服务交互

Hive的四种数据导入方式:

(1)从本地文件系统中导入数据到Hive表;

              load data local inpath 'xxx.txt' into table xxx;

(2)从HDFS上导入数据到Hive表;

              load data inpath '/tmp/xxx.txt' into table xxx

(3)从别的表中查询出相应的数据并导入到Hive表中。

              Insert overwrite table db.log_v2 partition(dt='18-09-26') select uid,model,key,value,

              time from db.log where dt='18-09-26';

(4)在创建表的时候通过从别的表中查询出相应的记录并插入到所创建的表中;

              create table test4 as select id, name, tel from xxx;

insert into 与 insert overwrite 都可以向hive表中插入数据,但是insert into直接追加到表中数据的尾部,而insert overwrite会重写数据,既先进行删除,再写入。如果存在分区的情况,insert overwrite会只重写当前分区数据。

文件加载格式示例:

 

Hive目前支持的SQL数据类型:

INT

TINYINT/SMALLINT/BIGINT

BOOLEAN

FLOAT

DOUBLE

STRING

BINARY

TIMESTAMP

ARRAY, MAP, STRUCT, UNION

DECIMAL

Hive中的表分为内部表、外部表、分区表和分桶表

 内部表(managed table)

  • 默认创建的是内部表(managed table),存储位置在hive.metastore.warehouse.dir设置,默认位置是/user/hive/warehouse
  • 导入数据的时候是将文件剪切(移动)到指定位置,即原有路径下文件不再存在
  • 删除表的时候,数据和元数据都将被删除
  • 默认创建的就是内部表create table xxx (xx xxx)

 

 外部表(external table)

 

  • 外部表文件可以在外部系统上,只要有访问权限就可以
  • 外部表导入文件时不移动文件,仅仅是添加一个metadata
  • 删除外部表时源数据不会被删除
  • 分辨外部表内部表可以使用DESCRIBE FORMATTED table_name命令查看
  • 创建外部表命令添加一个external即可,即create external table xxx (xxx)
  • 外部表指向的数据发生变化的时候会自动更新,不用特殊处理

 

 分区表(partioned)

 

  • 有些时候数据是有组织的,比方按日期/类型等分类,而查询数据的时候也经常只关心部分数据,比方说我只想查2017年8月8号,此时可以创建分区,查询具体某一天的数据时,不需要扫描全部目录,所以会明显优化性能
  • 一个Hive表在HDFS上是有一个对应的目录来存储数据,普通表的数据直接存储在这个目录下,而分区表数据存储时,是再划分子目录来存储的
  • 使用partioned by (xxx)来创建表的分区

 分桶表(clustered)

  • 分桶是相对分区进行更细粒度的划分。分桶将整个数据内容安装某列属性值得hash值进行区分,按照取模结果对数据分桶。如取模结果相同的数据记录存放到一个文件。
  • 桶表也是一种用于优化查询而设计的表类型。创建通表时,指定桶的个数、分桶的依据字段,hive就可以自动将数据分桶存储。查询时只需要遍历一个桶里的数据,或者遍历部分桶,这样就提高了查询效率。

具体说明分桶:

clustered by (user_id) sorted by(leads_id) into 10 buckets

clustered by是指根据user_id的值进行哈希后模除分桶个数,根据得到的结果,确定这行数据分入哪个桶中,这样的分法,可以确保相同user_id的数据放入同一个桶中。

sorted by 是指定桶中的数据以哪个字段进行排序,排序的好处是,在join操作时能获得很高的效率。

into 10 buckets是指定一共分10个桶。

在HDFS上存储时,一个桶存入一个文件中,这样根据user_id进行查询时,可以快速确定数据存在于哪个桶中,而只遍历一个桶可以提供查询效率。

内部表和外部表的区别:

       删除内部表,删除表元数据和数据

  删除外部表,删除元数据,不删除数据

内部表和外部表的使用选择:

  大多数情况,他们的区别不明显,如果数据的所有处理都在 Hive 中进行,那么倾向于 选择内部表,但是如果 Hive 和其他工具要针对相同的数据集进行处理,外部表更合适。

  使用外部表访问存储在 HDFS 上的初始数据,然后通过 Hive 转换数据并存到内部表中

  使用外部表的场景是针对一个数据集有多个不同的 Schema

  通过外部表和内部表的区别和使用选择的对比可以看出来,hive其实仅仅只是对存储在 HDFS上的数据提供了一种新的抽象。而不是管理存储在 HDFS上的数据。所以不管创建内部 表还是外部表,都可以对 hive 表的数据存储目录中的数据进行增删操作。

分区表和分桶表的区别:

  Hive 数据表可以根据某些字段进行分区操作,细化数据管理,可以让部分查询更快。同时表和分区也可以进一步被划分为 Buckets,分桶表的原理和 MapReduce 编程中的 HashPartitioner 的原理类似。

分区和分桶都是细化数据管理,但是分区表是手动添加区分,由于 Hive 是读模式,所 以对添加进分区的数据不做模式校验,分桶表中的数据是按照某些分桶字段进行 hash 散列 形成的多个文件,所以数据的准确性也高很多

Hive文件存储格式:

TEXTFILE

SEQUENCEFILE

RCFILE

ORCFILE(0.11以后出现)

其中TEXTFILE为默认格式,建表时不指定默认为这个格式,导入数据时会直接把数据文件拷贝到hdfs上不进行处理;SEQUENCEFILE,RCFILE,ORCFILE格式的表不能直接从本地文件导入数据,数据要先导入到textfile格式的表中, 然后再从表中用insert导入SequenceFile,RCFile,ORCFile表中。

TEXTFILE

默认格式,数据不做压缩,磁盘开销大,数据解析开销大。

可结合Gzip、Bzip2使用(系统自动检查,执行查询时自动解压),但使用这种方式,hive不会对数据进行切分,从而无法对数据进行并行操作。

SEQUENCEFILE

SequenceFile是Hadoop API提供的一种二进制文件支持,其具有使用方便、可分割、可压缩的特点。

SequenceFile支持三种压缩选择:NONE,RECORD,BLOCK。Record压缩率低,一般建议使用BLOCK压缩。

RCFILE

RCFILE是一种行列存储相结合的存储方式。首先,其将数据按行分块,保证同一个record在一个块上,避免读一个记录需要读取多个block。其次,块数据列式存储,有利于数据压缩和快速的列存取。

RCFile保证同一的数据位于同一节点,因此元组重构代价较低(需要将分散的数据重新组织,比如一列数据散落在不同集群,查询的时候,需要将各个节点的数据重新组织;但是如果数据都在一个机器上,那就没有必要重新组织)

RCFile通过列进行数据压缩,因为同一列都是相同的数据类型,所以压缩比比较好

RCFile可以跳过不必要的列读取

 

从以上几点也可以看出它是兼顾了行式和列式存储的部分优点。

ORC File

ORCFile存储格式,就是Optimized RC File的缩写。意指优化的RCFile存储格式。

ORC File 和 RC File比较:

每一个任务只输出单个文件,这样可以减少NameNode的负载

支持各种复杂的数据类型,比如datetime,decimal,以及复杂的struct,List,map等

在文件中存储了轻量级的索引数据

基于数据类型的块模式压缩:比如Integer类型使用RLE(RunLength Encoding)算法,而字符串使用字典编码(DictionaryEncoding)

使用单独的RecordReader并行读相同的文件

无需扫描标记就能分割文件

绑定读写所需要的内存

元数据存储使用PB,允许添加和删除字段

Hive中SQL查询转换成MapReduce作用的过程:

当用户向Hive输入一段命令或查询时,Hive需要与Hadoop交互工作来完成该操作:

1.驱动模块接收该命令或查询编译器

2.对该命令或查询进行解析编译

3.由优化器对该命令或查询进行优化计算

4.该命令或查询通过执行器进行执行

详细过程如下:

 

第1步:由Hive驱动模块中的编译器对用户输入的SQL语言进行词法和语法解析,将SQL语句转化为抽象语法树的形式。

第2步:抽象语法树的结构仍很复杂,不方便直接翻译为MapReduce算法程序,因此,把抽象语法书转化为查询块。

第3步:把查询块转换成逻辑查询计划,里面包含了许多逻辑操作符。

第4步:重写逻辑查询计划,进行优化,合并多余操作,减少MapReduce任务数量。

第5步:将逻辑操作符转换成需要执行的具体MapReduce任务。

第6步:对生成的MapReduce任务进行优化,生成最终的MapReduce任务执行计划。

第7步:由Hive驱动模块中的执行器,对最终的MapReduce任务进行执行输出。

几点说明:

当启动MapReduce程序时,Hive本身是不会生成MapReduce算法程序的。

需要通过一个表示“Job执行计划”的XML文件驱动执行内置的、原生的Mapper和Reducer模块。

Hive通过和JobTracker通信来初始化MapReduce任务,不必直接部署在JobTracker所在的管理节点上执行。

通常在大型集群上,会有专门的网关机来部署Hive工具。网关机的作用主要是远程操作和管理节点上的JobTracker通信来执行任务。

数据文件通常存储在HDFS上,HDFS由名称节点管理。

五、总结

Hive是建立在hadoop基础上的数据仓库,它使用MapReduce对存储在HDFS上的数据进行分析,将数据映射成数据库和一张张的表,它定义了一种被称为HiveQL的类SQL的查询语言,简化了MapReduce实现过程,只需要通过构造HiveQL查询语句即可实现数据分析功能。Hive在操作层面还存在一些限制,存在执行效率低等问题。

 

posted @ 2019-04-18 16:03  上下求索suo  阅读(541)  评论(0编辑  收藏  举报