hive

hive是基于Hadoop的一个数据仓库工具,用来进行数据提取、转化、加载,这是一种可以存储、查询和分析存储在Hadoop中的大规模数据的机制。hive数据仓库工具能将结构化的数据文件映射为一张数据库表,并提供SQL查询功能,能将SQL语句转变成MapReduce任务来执行。

Hive的优点是学习成本低,可以通过类似SQL语句实现快速MapReduce统计,使MapReduce变得更加简单,而不必开发专门的MapReduce应用程序。hive十分适合对数据仓库进行统计分析,使用类SQL 的HiveQL 语言实现数据查询,所有Hive数据都存储在Hadoop 兼容的文件系统中。

定义

hive是基于Hadoop构建的一套数据仓库分析系统,它提供了丰富的SQL查询方式来分析存储在Hadoop分布式文件系统中的数据:可以将结构化的数据文件映射为一张数据库表,并提供完整的SQL查询功能;可以将SQL语句转换为MapReduce任务运行,通过自己的SQL查询分析需要的内容,这套SQL简称Hive SQL,使不熟悉mapreduce的用户可以很方便地利用SQL语言查询、汇总和分析数据。而mapreduce开发人员可以把自己写的mapper和reducer作为插件来支持hive做更复杂的数据分析。它与关系型数据库SQL略有不同,但支持了绝大多数的语句如DDL、DML以及常见的聚合函数、连接查询、条件查询。它还提供了一系列的工具进行数据提取转化加载,用来存储、查询和分析存储在Hadoop中的大规模数据集,并支持UDF(User-Defined 函数)、UDAF(User-Defnes AggregateFunction)和UDTF(User-Defined Table-Generating Function),也可以实现对map和reduce函数的定制,为数据操作提供了良好的伸缩性和可扩展性。

hive不适合用于联机(online)事务处理,也不提供实时查询功能。它最适合应用在基于大量不可变数据的批处理作业。hive的特点包括:可伸缩(在Hadoop的集群上动态添加设备)、可扩展、容错、输入格式的松散耦合

适用场景

Hive 构建在基于静态批处理的Hadoop 之上,Hadoop 通常都有较高的延迟并且在作业提交和调度的时候需要大量的开销。因此,Hive 并不能够在大规模数据集上实现低延迟快速的查询,例如,Hive 在几百MB 的数据集上执行查询一般有分钟级的时间延迟。

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

设计特征

Hive 是一种底层封装了Hadoop 的数据仓库处理工具,使用类SQL 的HiveQL 语言实现数据查询,所有Hive 的数据都存储在Hadoop 兼容的文件系统(例如,Amazon S3、hdfs)中。Hive 在加载数据过程中不会对数据进行任何的修改,只是将数据移动到HDFS 中Hive 设定的目录下,因此,Hive 不支持对数据的改写和添加,所有的数据都是在加载的时候确定的。Hive 的设计特点如下。

● 支持索引,加快数据查询。

● 不同的存储类型,例如,纯文本文件HBase 中的文件。

● 将元数据保存在关系数据库中,大大减少了在查询过程中执行语义检查的时间。

● 可以直接使用存储在Hadoop 文件系统中的数据。

● 内置大量用户函数UDF 来操作时间、字符串和其他的数据挖掘工具,支持用户扩展UDF 函数来完成内置函数无法实现的操作。

● 类SQL 的查询方式,将SQL 查询转换为MapReduce 的job 在Hadoop集群上执行。

体系结构

主要分为以下几个部分:

用户接口

用户接口主要有三个:CLI,Client 和 WUI。其中最常用的是 CLI,Cli 启动的时候,会同时启动一个 Hive 副本。Client 是 Hive 的客户端,用户连接至 Hive Server。在启动 Client 模式的时候,需要指出 Hive Server 所在节点,并且在该节点启动 Hive Server。 WUI 是通过浏览器访问 Hive。

元数据存储

Hive 将元数据存储在数据库中,如 MySQL、derby。Hive 中的元数据包括表的名字,表的列和分区及其属性,表的属性(是否为外部表等),表的数据所在目录等。

解释器、编译器、优化器、执行器

解释器、编译器、优化器完成HQL 查询语句从词法分析、语法分析、编译、优化以及查询计划的生成。生成的查询计划存储在 hdfs 中,并在随后由 MapReduce 调用执行。

Hadoop

Hive 的数据存储在 HDFS 中,大部分的查询由 MapReduce 完成(不包含 * 的查询,比如 select * from tbl 不会生成 MapReduce 任务)。

数据存储

首先,Hive 没有专门的数据存储格式,也没有为数据建立索引,用户可以非常自由地组织 Hive 中的表,只需要在创建表的时候告诉 Hive 数据中的列分隔符和行分隔符,Hive 就可以解析数据。

其次,Hive 中所有的数据都存储在 hdfs 中,Hive 中包含以下数据模型:表(Table),外部表(External Table),分区(Partition),桶(Bucket)。

Hive 中的 Table 和数据库中的 Table 在概念上是类似的,每一个 Table 在 Hive 中都有一个相应的目录存储数据。例如,一个表 pvs,它在 HDFS 中的路径为:/wh/pvs,其中,wh 是在 hive-site.XML 中由 指定的数据仓库的目录,所有的 Table 数据(不包括 External Table)都保存在这个目录中。

Partition 对应于数据库中的 Partition 列的密集索引,但是 Hive 中 Partition 的组织方式和数据库中的很不相同。在 Hive 中,表中的一个 Partition 对应于表下的一个目录,所有的 Partition 的数据都存储在对应的目录中。例如:pvs 表中包含 ds 和 城镇 两个 Partition,则对应于 ds = 20090801, city = US 的 HDFS 子目录为:/wh/pvs/ds=20090801/city=US;对应于 ds = 20090801, city = CA 的 hdfs 子目录为;/wh/pvs/ds=20090801/city=CA

Buckets 对指定列计算 hash,根据 hash 值切分数据,目的是为了并行,每一个 Bucket 对应一个文件。将 user 列分散至 32 个 bucket,首先对 user 列的值计算 hash,对应 hash 值为 0 的 HDFS 目录为:/wh/pvs/ds=20090801/ctry=US/part-00000;hash 值为 20 的 hdfs 目录为:/wh/pvs/ds=20090801/ctry=US/part-00020

External Table 指向已经在 HDFS 中存在的数据,可以创建 Partition。它和 Table 在元数据的组织上是相同的,而实际数据的存储则有较大的差异。

Table 的创建过程和数据加载过程(这两个过程可以在同一个语句中完成),在加载数据的过程中,实际数据会被移动到数据仓库目录中;之后对数据对访问将会直接在数据仓库目录中完成。删除表时,表中的数据和元数据将会被同时删除。

安装配置

可以下载一个已打包好的hive稳定版,也可以下载源码自己build一个版本。

安装需要

安装打包好的hive

需要先到apache下载已打包好的hive镜像,然后解压开该文件

$ tar -xzvf hive-x.y.z.tar.gz

设置hive环境变量

-x.y.z={{pwd}}

设置hive运行路径

=/bin:

编译Hive源码

下载hive源码此处使用maven编译,需要下载安装maven。

以Hive 0.13版为例

运行hive

Hive运行依赖于hadoop,在运行hadoop之前必需先配置好hadoopHome。

export HADOOP_HOME=\u003chadoop-install-dir\u003e

hdfs上为hive创建\tmp目录和/user/hive/warehouse(akahive.metastore.warehouse.dir) 目录,然后你才可以运行hive。

在运行hive之前设置HiveHome。

=\u003chive-install-dir\u003e

在命令行窗口启动hive

/bin/hive

优化方法

1、join连接时的优化:当三个或多个以上的表进行join操作时,如果每个on使用相同的字段连接时只会产生一个mapreduce。

2、join连接时的优化:当多个表进行查询时,从左到右表的大小顺序应该是从小到大。原因:hive在对每行记录操作时会把其他表先CPU缓存起来,直到扫描最后的表进行计算

3、在where字句中增加分区过滤器

4、当可以使用left semi join 语法时不要使用inner join,前者效率更高。原因:对于左表中指定的一条记录,一旦在右表中找到立即停止扫描。

5、如果所有表中有一张表足够小,则可置于内存中,这样在和其他表进行连接的时候就能完成匹配,省略掉reduce过程。设置属性即可实现,set hive.auto.covert.join=true; 用户可以配置希望被优化的小表的大小 set hive.mapjoin.smalltable.开本=2500000; 如果需要使用这两个配置可置入/.hiverc文件中。

6、同一种数据的多种处理:从一个数据源产生的多个数据聚合,无需每次聚合都需要重新扫描一次。

例如:insert overwrite table student select * from employee; insert overwrite table person select * from employee;

可以优化成:from employee insert overwrite table student select * insert overwrite table person select *

7、函数极限调优:limit语句通常是执行整个语句后返回部分结果。set hive.极限optimize.enable=true;

8、开启并发执行。某个job任务中可能包含众多的阶段,其中某些阶段没有依赖关系可以并发执行,开启并发执行后job任务可以更快的完成。设置属性:set hive.exec.纬线=true;

9、hive提供的严格模式,禁止3种情况下的查询模式。

a:当表为分区表时,where字句后没有分区字段和限制时,不允许执行。

b:当使用order by语句时,必须使用limit字段,因为order by 只会产生一个reduce任务。

c:限制笛卡尔积的查询。

10、合理的设置map和reduce数量。

11、JavaOS重用。可在Hadoop的mapred-site.XML中设置jvm被重用的次数。

数据存储模型

hive中包含以下四类数据模型:表(Table)、外部表(External Table)、分区(Partition)、桶(Bucket)。 

(1) hive中的Table和数据库中的Table在概念上是类似的。在hive中每一个Table都有一个相应的目录存储数据。 

(2)外部表是一个已经存储在hdfs中,并具有一定格式的数据。使用外部表意味着hive表内的数据不在hive的数据仓库内,它会到仓库目录以外的位置访问数据。 

外部表和普通表的操作不同,创建普通表的操作分为两个步骤,即表的创建步骤和数据装入步骤(可以分开也可以同时完成)。在数据的装入过程中,实际数据会移动到数据表所在的hive数据仓库文件目录中,其后对该数据表的访问将直接访问装入所对应文件目录中的数据。删除表时,该表的元数据和在数据仓库目录下的实际数据将同时删除。 

外部表的创建只有一个步骤,创建表和装入数据同时完成。外部表的实际数据存储在创建语句。LOCATION参数指定的外部hdfs文件路径中,但这个数据并不会移动到hive数据仓库的文件目录中。删除外部表时,仅删除其元数据,保存在外部HDFS文件目录中的数据不会被删除。 

(3)分区对应于数据库中的分区列的密集索引,但是hive中分区的组织方式和数据库中的很不相同。在hive中,表中的一个分区对应于表下的一个目录,所有的分区的数据都存储在对应的目录中。 

(4)桶对指定列进行哈希(hash)计算,会根据哈希值切分数据,目的是为了并行,每一个桶对应一个文件。

参考资料