Hive基本原理(修订版)
Hive的本质是一个翻译器。它的任务就是将一种类SQL(HQL)的语句翻译成Mapreduce任务,通过执行Mapreduce任务来对海量数据仓库进行处理。从表面上来看它就是一个数据仓库能够查询与分析数据。它与Hadoop的关系如下图所示:
与传统数据库相比Hive的主要特点为:
①分析离线存储数据,不具有实时性
②不支持事务,由于是历史数据所以没有必要去增删改。
③不支持修改,由于是历史数据所以没有必要去增删改。
④有很多的数据冗余保障了系统的健壮性。
关于Hive的5条重要的结论
默认环境是Linux+Hadoop
- Hive中的数据库实际上是HDFS文件系统中的一个[库名].db的文件夹。
- Hive中数据库下的表,是库文件夹下的一个子文件夹。
- Hive中一个表中的数据就是在对应表文件夹下的一个或者是一些子文件。
- Hive的HQL会转化成Mapreduce任务来执行。
- Hive中维护着一个默认的文件库就是HDFS中的/user/hive/warehouse目录。
Hive转化成Mapreduce的流程
- 根据SQL语法规则完成SQL语法与词法解析,将SQL转换为SQL语法树。
- 遍历语法树找出基本的查询单元QueryBlock。
- 遍历QueryBlock翻译为执行操作树。
- 逻辑层优化器进行执行树变换减少Shuffle数据量进而达到优化。
- 遍历执行树翻译为MR任务。
- 物理优化器进行MR任务变换生成最终的执行计划。
Hive的元数据库
前面我们知道Hive的本质是一个翻译器,它的真实数据都存放在HDFS上,与此同时我们知道Hive并不是文件的胡乱堆放而是一个有逻辑结构的整体,那么这个逻辑结构是如何呈现出来的呢?这里就引出了元数据库。Hive的元数据库(本质上是一个关系型数据库)存储着Hive的元数据信息具体就是指库、表、列等数据之间关系的描述。默认情况下Hive的元数据存放在derby数据库当中。这个数据库有以下信息:
- 它是一个单用户的数据库。
- 每当在一个新的文件夹下启动Hive的时候就会新建一个存储元数据的文件夹出来。这就造成了很大的不便。
所以在实务上我们一般使用MySQL来存储Hive的元数据信息。下面简要介绍元数据库中一些重要的表:
①DBS:存储了Hive库相关的信息,包括库编号、库名称、以及库所对应的HDFS文件的存储位置。
②TBLS,存储了Hive表中相关的信息,表编号、所属库的编号、表名称、表所有者、表类型。
- COLUMNS_V2:这里面存储着列相关的信息:所属表的编号,列名称,列的位置。
- SDS:Hive表对应着表的编号,HDFS中文件的位置。
总结:通过这些信息我们就可以把这些文件从逻辑上组织在一起这也就是我们最后看到的Hive。
Hive中的内部表与外部表
前面我们知道一个表就会对应一个文件。当我们创建内部表的时候我们会将会将其关联的文件拷贝到Hive所对应的文件夹中,同时为这个新创建的表添加元数据(注意是拷贝)。当我们要创建一个外部表的时候就只是将Hive与这个表关联起来,并创建元数据(注意是关联)。外部表与内部表最大的区别就是在删除表的时候外部表只是删除数据,而内部表会将对应文件夹下的数据域元数据都删除。实务上,内部表与外部表在生产环境下都是用。
Hive中的分区表
Hive分区表的出现时为了提高查询效率。它的思想与Mysql中的BTree索引很像,如果我们要查询一个分区内的数据我们就可以提前过滤掉很大一批的数据进而将我们的查询由全表遍历变成选择性的遍历。分区表的具体实现就是在一个表对应的文件夹下面再建立对应的子文件夹,最后在子文件夹下再存放真实的数据。这就让我们想到子文件夹事实上就是一种树的结构。这也就是Hive分区为这么快的原因。比如说在书籍下面有小说、杂志、名著等分区,那么Hive的做法就是在书籍对应的子文件夹下再建立小说、杂志、名著等子文件夹。然后再在小说下面的文件夹中存放小说对应的子文件,以此类推。现在如果我们要查找一个数据下面的一个对应的子类时我们会直接遍历某个子文件夹下面的数据(提前过滤掉了大部分的数据,而不是以前的全表遍历)。
Hive中的分桶
在解释分桶之前先让我们回想一下统计学中的抽样,抽样的目的就是得到样本然后通过研究样本的规律然后对整体做出估计的一种方法。什么是好的样本——独立同分布的。Hive中的分桶是为了采样而做准备的,所以与Hive分区相比,Hive中的分桶是一种更加细粒度的划分。比如说我们现在要在上述的小说、杂志、名著中取样然后我们就会在小说的分区中抽取一点,杂志的分区中抽取一点、名著的分区中抽取一点。这样的话就能够得到一个样本。而Hive中把这抽取的一点打包在一个桶中,现在的场景就是在小说的分区中抽取一桶,杂志的分区中抽取一桶、名著的分区中抽取一桶。这样就会得到样本。又,我们需要的是独立同分布的样本所以我们使用Hash算法来讲分区中的数据随机分桶。这就是Hive中的分桶。
Hive中的函数
Hive中也有一些内置的函数,这些函数与MySQL中的内置函数比较相似。比如说最普通的加减乘除、取余、乘方、逻辑运算等等。当然除了这些内置函数之外Hive中还能够实现自定义函数UDF。(以Java语言为例)具体来说定义一个自定义的函数如下步骤所示:
- 创建一个普通的java工程,导入hive相关包
2.创建一个类继承UDF
3.在类中编写一个公有的evaluate方法,方法名必须是evaluate,但返回值和参数列表任意。
4.将写好的工程打成jar包,上传到linux中
5.在hive中注册jar
1 | add jar /home/software/myUDF.jar |
6.注册自定义函数
1 | create temporary function urlEncode as ‘cn.tedu.hive.udf.URLEncoderUDF’; |
7.调用临时函数
最后
Hive还可以使用JDBC来连接但是这种做法通常比较少见。Hive还有很多的特性没有特性没有介绍到,由于笔者刚刚入门欢迎大家批评。
还没有评论,来说两句吧...