Hive基础简介

本文遵循BY-SA版权协议,转载请附上原文出处链接。


本文作者: 黑伴白

本文链接: http://heibanbai.com.cn/posts/cdff83db/

关于Hive

Hive是什么

Hive是一个数据仓库基础工具在Hadoop中用来处理结构化数据。它架构在Hadoop之上,总归为大数据,并使得查询和分析方便。

最初,Hive是由Facebook开发,后来由Apache软件基金会开发,并作为进一步将它作为名义下Apache Hive为一个开源项目。

归纳如下:

  1. 是基于 Hadoop 的一个数据仓库工具;

  2. 可以将结构化的数据映射为一张数据库表;

  3. 并提供 HQL(Hive SQL)查询功能;

  4. 底层数据是存储在 HDFS 上;

  5. Hive的本质是将 SQL 语句转换为 MapReduce、Tez 或者 spark 等任务执行;

  6. 适用于离线的批量数据计算。

image-20220516100734556

为什么要有Hive

前面已经提到,hive可以封装MapReduce、Tez、Spark等这些引擎的处理过程,让使用者在不了解这些计算引擎具体执行细节的情况下就可以处理数据,使用者只需要学会如何写sql即可。

Hive可很好的解决直接使用 MapReduce、Tez、Spark等时所面临的两个主要问题:

  1. 直接使用 MapReduce、Tez、Spark学习成本太高,因为需要了解底层具体执行引擎的处理逻辑,而且需要一定的编码基础;而Hive提供直接使用类sql语言即可进行数据查询和处理的平台或接口,只要使用者熟悉sql语言即可;

  2. MapReduce、Tez、Spark实现复杂查询逻辑开发难度大,因为需要自己写代码实现整个处理逻辑以及完成对数据处理过程的优化,而Hive将很多数据统计逻辑封装成了可直接使用的窗口函数,且支持自定义窗口函数来进行扩展,而且Hive有逻辑和物理优化器,会对执行逻辑进行自动优化。

Hive与关系数据库的区别

Hive 在很多方面与传统关系数据库类似(例如支持 SQL 接口),但是其底层对 HDFS 和 MapReduce 的依赖意味着它的体系结构有别于传统关系数据库,而这些区别又影响着 Hive 所支持的特性,进而影响着 Hive 的使用。

  • Hive 和关系数据库存储文件的系统不同,Hive 使用的是 Hadoop 的HDFS(Hadoop的分布式文件系统),关系数据库则是服务器本地的文件系统;
  • Hive 使用的计算模型是 MapReduce,而关系数据库则是自己设计的计算模型;
  • 关系数据库都是为实时查询的业务进行设计的,而 Hive 则是为海量数据做数据挖掘设计的,实时性很差;实时性的区别导致 Hive 的应用场景和关系数据库有很大的不同;
  • Hive 很容易扩展自己的存储能力和计算能力,这个是继承 Hadoop 的,而关系数据库在这个方面要差很多。

Hive的应用场景

通过对 Hive 与传统关系数据库的比较之后,其实我们不难得出 Hive 可以应用于哪些场景。

Hive 构建在基于静态批处理的 Hadoop 之上,Hadoop 通常都有较高的延迟并且在作业提交和调度的时候需要大量的开销。因此,Hive 不适合在大规模数据集上实现低延迟快速的查询。

Hive 并不适合那些需要低延迟的应用,例如,联机事务处理(OLTP)。Hive 查询操作过程严格遵守 Hadoop MapReduce 的作业执行模型,Hive 将用户的 HiveQL 语句通过解释器转换为 MapReduce 作业提交到 Hadoop 集群上,Hadoop 监控作业执行过程,然后返回作业执行结果给用户。Hive 并非为联机事务处理而设计,Hive 并不提供实时的查询和基于行级的数据更新操作。

Hive 的最佳使用场合是大数据集的批处理作业,例如,网络日志分析。

Hive的数据存储

Hive 的存储是建立在 Hadoop 文件系统之上的。Hive 本身没有专门的数据存储格式,也不能为数据建立索引,因此用户可以非常自由地组织 Hive 中的表,只需要在创建表的时候告诉 Hive 数据中的列分隔符就可以解析数据了。

Hive 中主要包括 4 种数据模型:

  • 表(Table)
  • 外部表(External Table)
  • 分区(Partition)
  • 桶(Bucket)

Hive 的表和数据库中的表在概念上没有什么本质区别,在 Hive 中每个表都有一个对应的存储目录。而外部表指向已经在 HDFS 中存在的数据,也可以创建分区。Hive 中的每个分区都对应数据库中相应分区列的一个索引,但是其对分区的组织方式和传统关系数据库不同。桶在指定列进行 Hash 计算时,会根据哈希值切分数据,使每个桶对应一个文件。

Hive表

Hive 中的表( Table )和关系数据库中的 table 在概念上是类似的,每个 table 在 Hive 中都有一个相应的目录存储数据,如果没有指定表的数据库,那么 Hive 会通过{HIVE_HOME}}/conf/hive-site.xml 配置文件中的 hive.metastore.warehouse.dir 属性来使用默认值(一般是 /user/hive/warehouse ,也可以根据实际的情况来修改这个配置),所有的 table 数据(不包括外部表) 都保存在这个目录中。

Hive 表分为两类,即内部表和外部表。所谓内部表(managed table) 即 Hive 管理的表,Hive 内部表的管理既包含逻辑以及语法上的,也包含实际物理意义上的,即创建 Hive 内部表时,数据将真实存在于表所在的目录内,删除内部表时,物理数据和文件也一并删除。

选择内部表还是外部表?

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

一种常见的模式是使用外部表访问存储的 HDFS (通常由其他工具创建)中的初始数据,然后使用 Hive 转换数据并将其结果放在内部表中。相反,外部表也可以用于将 Hive 的处理结果导出供其他应用使用。

使用外部表的另一种场景是针对一个数据集,关联多个 Schema。

分区

Hive 将表划分为分区(partition),partition 根据分区字段进行。分区可以让数据的部分查询变得更快。

假设日志数据中,每条记录都带有时间戳 。如果根据时间来分区,那么同一天的数据将被划分到同一个分区中。

分区可以通过多个维度来进行。例如,通过日期划分之后,还可以根据国家进一步划分。

分区在创建表的时候使用 PARTITIONED BY 从句定义,该从句接收一个字段列表:

1
2
CREATE TABLE logs (ts BIGINT , line STRING)
PARTITIONED BY (dt STRING,country STRING);

当导入数据到分区表时,分区的值被显式指定:

1
2
3
LOAD DATA INPATH ’/user/root/path’ 
INTO TABLE logs
PARTITION (dt='2001-01-01',country='GB’);

实际 SQL 中,灵活指定分区将大大提高其效率,如下代码将仅会扫描 2001-01-01下的 GB 目录。

1
SELECT ts , dt , line FROM logs WHERE dt=2001-01-01' and country='GB' 

分桶

表或者分区可以进一步被划分为桶( bucket)。桶通常在原始数据中加入一些额外的结构,这些结构可以用于高效查询。

例如,基于用户 ID 的分桶可以使基于用户的查询非常快。

在表或者分区中使用桶通常有两个原因:

  • 一是为了高效查询 。桶在表中加入了特殊的结果, Hive 在查询的时候可以利用这些结构提高效率。例如,如果两个表根据相同的字段进行分桶,则在对这两个表进行关联的时候,可以使用 map-side 关联高效实现,前提是关联的字段在分桶字段中出现。
  • 二是可以高效地进行抽样。在分析大数据集时,经常需要对部分抽样数据进行观察和分析,分桶有利于高效实现抽样。

为了让 Hive 对表进行分桶,通过 CLUSTERED BY 从句在创建表的时候指定:

1
2
CREATE TABLE bucketed users(id INT, name STRING) 
CLUSTERED BY (id) INTO 4 BUCKETS;

指定表根据 id 字段进行分桶,并且分为 4 个桶 。分桶时, Hive 根据字段哈希后取余数来决定数据应该放在哪个桶,因此每个桶都是整体数据的随机抽样。

在 map-side 的关联中,两个表根据相同的宇段进行分桶,因此处理左边表的 bucket 时,可以直接从外表对应的 bucket 中提取数据进行关联操作。map-side 关联的两个表不一定需要完全相同 bucket 数量,只要成倍数即可。

需要注意的是, Hive 并不会对数据是否满足表定义中的分桶进行校验,只有在查询时出现异常才会报错 。因此,一种更好的方式是将分桶的工作交给 Hive 来完成(设 hive.enforce.bucketing 属性为 true 即可)。

Hive的架构

作为Hadoop的一个数据仓库工具,Hive的架构如下:

image-20220516101913969

单元名称 操作
用户接口层 1. cli(Command Line Interface),shell终端命令行,通过命令行与hive进行交互
2. JDBC/ODBC,是 Hive 的基于 JDBC 操作提供的客户端,用户(开发员,运维人员)通过客户端连接至 Hive server 服务
3. Web UI,通过浏览器访问hive
元数据存储系统 1. 元数据 ,通俗的讲,就是存储在 Hive 中的数据的描述信息
2. Hive 中的元数据通常包括:表的名字,表的列和分区及其属性,表的属性(内部表和 外部表),表中数据所在的目录
3. Metastore 默认存在自带的 Derby 数据库或者我们自己创建的 MySQL 库中
4. Hive 和 MySQL或Derby 之间通过 MetaStore 服务交互
跨语言服务 Hive集成了Thrift Server,让用户可以使用多种不同语言来操作Hive
Driver(Compiler/Optimizer/Executor) Driver完成HQL查询语句的词法分析、语法分析、编译、优化以及查询计划的生成。生成的查询计划存储在HDFS上,并由MapReduce调用执行。

工作流程及原理

image-20220516145305618
  1. 用户把查询任务提交给Driver驱动程序
  2. 驱动程序将Hql发送给编译器Compiler
  3. 编译器Compiler根据用户查询任务去MetaStore中获取需要的Hive的元数据信息
  4. 编译器Compiler得到元数据信息,对任务进行编译
  • 依据Antlr语法规则,解析HiveQL并转换为AST抽象语法树
  • 遍历AST抽象语法树,抽象出查询的基本组成单元QueryBlock(查询块)
  • 依据QueryBlock生成逻辑执行计划
  • 优化、重写逻辑执行计划,合并不必要的ReduceSinkOperator,降低shuffle
  • 依据逻辑执行计划生成物理执行计划,也就是Hive Job的Task树(默认是MapReduce Job)
  • 优化、重写物理执行计划
  1. 将最终的执行计划(Hive Job)提交给Driver。到此为止,查询解析和编译完成
  2. Driver将执行计划(Hive Job)转交给ExecutionEngine去执行
  3. 在Yarn上,执行作业的过程默认是一个MapReduce任务
  • 执行引擎发送作业给JobTracker
  • JobTracker将task下发给到TaskTracker执行
  • task读、写HDFS数据

蚂蚁🐜再小也是肉🥩!


Hive基础简介
http://heibanbai.com.cn/posts/cdff83db/
作者
黑伴白
发布于
2022年5月18日
许可协议

“您的支持,我的动力!觉得不错的话,给点打赏吧 ୧(๑•̀⌄•́๑)૭”

微信二维码

微信支付

支付宝二维码

支付宝支付