Hive使用入门
Hive简介
hive是基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张数据库表,并提供简单的sql查询功能,可以将sql语句转换为MapReduce任务进行运行。 其优点是学习成本低,可以通过类SQL语句快速实现简单的MapReduce统计,不必开发专门的MapReduce应用,十分适合数据仓库的统计分析。
建立Hive表
hive中创建表时,默认情况下hive负责管理数据,这就是所谓的“托管表”。建立托管表的语法比较简单,和写SQL建表也比较类似:
DROP TABLE example_table; CREATE TABLE if not exists example_table(example_id STRING, example_name STRING ) row format delimited fields terminated by ',';
需要注意的是,建立字段的定义,以及row的delimeter,这里指定为”,”。
托管表建立完成后,表中并无数据,这就需要我们向表中插入一些数据。但Hive中并不可以通过insert一条数据的方式向表中插入数据,可以通过下面的方式从本地文件中加载(当然也可以从HDFS中加载,语法稍微不同):
LOAD DATA LOCAL INPATH 'LocalFile' OVERWRITE INTO TABLE region_table;
由于在第一步中我们已经设定行分隔符为’,’,这里的LocalFile的每一行都要由,进行分隔,并在加载完成后,对应到定义的字段中去。
但在我们的实际应用场景下,Hive中使用的数据大部分都是从外部文件中得到的,这时候就需要创建“外部表”。
drop table task_table; create external table if not exists task_table ( doc string ) stored as inputformat 'Hive进行的InputFormat转换' outputformat 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat' location '/数据所在的HDFS文件夹/';
使用external关键字之后,Hive就知道数据并不是托管的,不会将数据移到自己的数据仓库目录中;而且在drop外部表时,也不会碰数据,只会删除hive中的元数据。
InputFormat
和Hadoop中的InputFormat类似,我们在定义外部表时,需要指定特定的InputFormat以将HDFS上的文件按行映射到对应的数据上去。但是,我们在CREATE外部表语句中定义的InputFormat与Hadoop中Map使用的InputFormat有所不同,外部表中的定义的InputFormat并不能决定map分片数量。
在hive中运行“select * from example_table”时直接返回当前所有值,并不会启动mapreduce任务,而当构建一些复杂的特殊的HQL语句时,就会启动一个mapreduce任务来进行处理。
hive中运行参数的设置可以通过hive命令中的“--hive-conf 参数名=参数值”来定义,在hive启动的mapreduce任务中,使用的默认是org.apache.hadoop.hive.ql.io.CombineHiveInputFormat类,与table中定义的InputFormat根本无关,了解hadoop的应该知道,Combine表示可能会合并多个小文件一起处理,与我们当前需求并不符合。而如果需要设置每个文件只能由一个map任务来处理时,原来的继承FileInputFormat并重写isSplittable方法并不起作用,抛出异常。这是因为Hive中启动的mapreduce任务的InputFormat必须是org.apache.hadoop.hive.ql.io.HiveInputFormat的子类,可以通过设置mapred.input.format.class=org.apache.hadoop.hive.ql.io.HiveInputFormat,并将参数mapreduce.input.fileinputformat.split.minsize设置(单位是字节)的非常大来达到目的。
也可以在hive配置文件中进行整体的调整:
<property> <name>mapreduce.input.fileinputformat.split.minsize</name> <value>1099511627776</value> </property> <property> <name>hive.input.format</name> <value>org.apache.hadoop.hive.ql.io.HiveInputFormat</value> </property>
UDF函数
Hive中有很多的内置函数,如果可以通过内置函数来解决,就不需要编写UDF来完成任务。
可以通过下面的命令来显示出hive中的所有内置函数:
hive -e "show functions";
比如可以使用from_unixtime,cast, hour三个函数的组合来完成将时间转换成小时的工作:
hour(from_unixtime(cast(raw['ti'] as bigint),'yyyy-MM-dd HH:mm:ss'))
如何在hive中自定义UDF(User Define Function)?这里说明一下如何在java中定义UDF。
首先,需要继承类:org.apache.hadoop.hive.ql.exec.UDF,并写一个名称为evaluate的函数,由于Hive使用的是反射的方式来进行调用的,并不强调参数以及返回值,可以随便写,在使用时注意就可以了(甚至可以在UDF函数中重载多个evaludate方法)。
编写完成后,需要在HQL脚本中使用下面的方式来进行调用:
add jar “对应的jar包路径” create temporary function function_name as 'UDF类名称';
之后,就可以在sql中使用function_name进行操作,注意其输入参数以及返回值。
HQL语句
hive中可以执行HQL语句,其基本格式与SQL语句非常类似。可以通过hive shell的方式执行,也可以通过hive –e “hql语句”或hive –f “hql文件”的方式执行。
示例:
select example_udf_function(doc) raw from example_table;
此外,HQL语句还支持嵌套。这部分只是个入门教程,因此,后续深入研究。