本指南介绍了Hive,并详细指引读者安装Hive。前面第几章学习指南已经指导大家安装Linux操作系统,并安装配置了Hadoop,但是这只表明我们已经安装好了Hadoop分布式文件系统,而Hive需要另外下载安装,本指南就是详细指导大家安装并配置Hive,完成后大家可以结合厦门大学林子雨开设的《大数据技术原理与应用》课程第14章节进行深入学习。
Hive是Facebook开发的构建于Hadoop集群之上的数据仓库应用,可以将结构化的数据文件映射为一张数据库表,并提供完整的SQL查询功能,可以将SQL语句转换为MapReduce任务进行运行。
Hive提供了一系列的工具,可以用来进行数据提取转化加载(ETL),其中,ETL是一种可以存储、查询和分析存储在Hadoop中的大规模数据的机制。因此,Hive是最适合数据仓库应用程序的,它可以维护海量数据,而且可以对数据进行挖掘,然后形成意见和报告等。
因为大多数的数据仓库应用程序是基于SQL的关系数据库现实的,所以,Hive降低了将这些应用程序移植到Hadoop上的障碍。如果用户懂得SQL,那么学习使用Hive会很容易。因为Hive定义了简单的类SQL查询语言——HiveQL,这里值得一提的是,与SQLServer、Oracle相比,HiveQL和MySQL提供的SQL语言更接近。同样的,相对于其他的Hadoop语言和工具来说,Hive也使得开发者将基于SQL的应用程序移植到Hadoop变得更加容易。
下面开始安装Hive。
cd~/下载sudotar-zxvf./apache-hive-1.2.1-bin.tar.gz-C/usr/local#解压到/usr/local中cd/usr/local/sudomv./apache-hive-1.2.1-bin/./hive#将文件夹名改为hivesudochown-Rhadoop:hadoop./hive#修改文件权限mkdir-p/usr/local/hive/warehouse#创建元数据存储文件夹sudochmoda+rwx/usr/local/hive/warehouse#修改文件权限为了方便使用,我们把hive命令加入到环境变量中去,需要使用以下命令编辑.bashrc文件:
vim~/.bashrc#设置环境变量进入.bashrc编辑状态以后,需要在文件最前面添加如下几行:
exportHIVE_HOME=/usr/local/hiveexportPATH=$PATH:$HIVE_HOME/bin完成上述操作后,需要运行以下命令让配置生效:
source~/.bashrc#使配置立即生效然后运行hive命令启动Hive,命令如下:
hive#启动Hive当出现以下界面即为启动成功。
Hive启动失败:若启动不成功,则会出现以下错误:
则需要进入到hadoop安装目录下的share/hadoop/yarn/lib下删除jline-0.9.94.jar文件,再启动hive即可(因为高版本的Hadoop对Hive有捆绑)。
通过Hadoop的学习我们已经知道,Hadoop的运行模式有三种:本地模式、伪分布式模式和分布式模式。这里我们以介绍本地模式为主,其他模式只进行简单介绍。因为,本地模式是Hadoop的默认模式,所以,Hadoop不需要进行其他配置,我们只需对Hive进行相应配置。这里只需修改hive-site.xml文件,如果该文件不存在,用户需要自己新建一个。(注意:在$HIVE_HOME/conf目录下我们可能会看到hive-default.xml.template这个大文件,这个文件中包含了Hive提供的配置属性以及默认的属性值,这些属性中的绝大多数,用户可以忽略不管)。
在安装Hive时,默认情况下,元数据存储在Derby数据库中。Derby是一个完全用Java编写的数据库,所以可以跨平台,但需要在JVM中运行。因为多用户和系统可能需要并发访问元数据存储,所以默认的内置数据库并不适用于生产环境。任何一个适用于JDBC进行连接的数据库都可用作元数据库存储,这里我们把MySQL作为存储元数据的数据库。接下来,我们分别对这两种方式进行介绍,即使用Derby数据库的方式和使用MySQL数据库的方式。
本地模式中,用户的“表”等元数据信息,都默认存储在file://user/hive/warehouse,对于其他模式默认存储路径是hdfs://namenode_server/user/hive/warehouse。使用如下命令编辑hive-site.xml文件:
vim/usr/local/hive/conf/hive-site.xml在hive-site.xml文件添加以下内容:
Hive配置完成后,下面来启动它,并使用简单的HiveQL命令进行相应测试。我们先新建了一个表x,它有1个int型属性a,然后查找表x中的所有属性,最后删除表x,然后退出。HiveQL命令与SQL命令很相似,所以,读者如果有SQL基础的话,会很快上手。关于HiveQL命令的使用方法会在第4节详细介绍。
注意,命令最后需要以分号“;”结束。
sudorpm-e--nodepsmysql-libs-xxxxxxb.安装MySQL,命令如下:
sudoapt-getinstallmysql-serverc.启动设置MySQL,命令如下:
insertintomysql.user(Host,User,Password)values("localhost","hive",password("hive"));#创建hive用户createdatabasehive;#创建hive数据库grantallonhive.*tohive@'%'identifiedby'hive';grantallonhive.*tohive@'localhost'identifiedby'hive';flushprivileges;exit#退出mysqlmysql-uhive-phive#验证hive用户showdatabases;看到以下信息,则说明创建成功。
2)配置Hive,修改hive-site.xml文件,修改后的结果如下:
mv~/下载/mysql-connector-java-5.1.30-bin.jar/usr/local/hive/lib/#拷贝mysql-connector-java-5.1.30-bin.jar到hive的lib下cp/usr/local/hive/lib/jline-2.12.jar/usr/local/hadoop/share/hadoop/yarn/lib#把jline-2.12.jar拷贝到hadoop相应目录下mkdir-p/usr/local/hive/tmp#创建hive临时文件夹sudochmoda+rwx/usr/local/hive/tmp#修改文件权限接下来,启动测试Hive。首先启动Hadoop后,执行Hive命令hive,并输入showdatabases;进行测试。
hiveclient常用命令可以通过hive--help查看。下面再介绍一些hiveclient常用命令,用户可以自行测试:
showtables;#查看所有表名showtables'ad*';#查看以'ad'开头的表名set命令#设置变量与查看变量set–v;#查看所有的变量sethive.stats.atomic;#查看hive.stats.atomic变量sethive.stats.atomic=false;#设置hive.stats.atomic变量hadoopdfs-ls/;#查看hadoop所有文件路径dfs-ls/usr/local/hive/warehouse/;#查看hive所有用戶dfs-ls/tmp;#查看dfs中內容sourcefile
首先,我们简单叙述一下HiveQL的基本数据类型。
Hive支持基本数据类型和复杂类型,基本数据类型主要有数值类型(INT、FLOAT、DOUBLE)、布尔型和字符串,复杂类型有三种:ARRAY、MAP和STRUCT。
a.基本数据类型
b.复杂数据类型
2)常用的HiveQL操作命令
Hive常用的HiveQL操作命令主要包括:数据定义、数据操作。接下来详细介绍一下这些命令即用法(想要了解更多请参照《Hive编程指南》一书)。
a.数据定义:主要用于创建修改和删除数据库、表、视图、函数和索引。
创建、修改和删除数据库
createdatabaseifnotexistshive;#创建数据库showdatabases;#查看Hive中包含数据库showdatabaseslike'h.*';#查看Hive中以h开头数据库describedatabases;#查看hive数据库位置等信息alterdatabasehivesetdbproperties;#为hive设置键值对属性usehive;#切换到hive数据库下dropdatabaseifexistshive;#删除不含表的数据库dropdatabaseifexistshivecascade;#删除数据库和它中的表注意,除dbproperties属性外,数据库的元数据信息都是不可更改的,包括数据库名和数据库所在的目录位置,没有办法删除或重置数据库属性。
创建、修改和删除表
主要语法如下,用户可自行实现。
createviewview_nameas....;#创建视图alterviewview_namesettblproperties(…);#修改视图因为视图是只读的,所以对于视图只允许改变元数据中的tblproperties属性。
#删除视图dropviewifexistsview_name;#创建索引createindexindex_nameontabletable_name(partition_name/column_name)as'org.apache.hadoop.hive.ql.index.compact.CompactIndexHandler'withdeferredrebuild....;这里'org.apache.hadoop.hive.ql.index.compact.CompactIndexHandler'是一个索引处理器,即一个实现了索引接口的Java类,另外Hive还有其他的索引实现。
alterindexindex_nameontabletable_namepartition(...)rebulid;#重建索引如果使用deferredrebuild,那么新索引成空白状态,任何时候可以进行第一次索引创建或重建。
showformattedindexontable_name;#显示索引dropindexifexistsindex_nameontabletable_name;#删除索引用户自定义函数
在新建用户自定义函数(UDF)方法前,先了解一下Hive自带的那些函数。showfunctions;命令会显示Hive中所有的函数名称:
若想要查看具体函数使用方法可使用describefunction函数名:
首先编写自己的UDF前需要继承UDF类并实现evaluate()函数,或是继承GenericUDF类实现initialize()函数、evaluate()函数和getDisplayString()函数,还有其他的实现方法,感兴趣的用户可以自行学习。
另外,如果用户想在Hive中使用该UDF需要将我们编写的Java代码进行编译,然后将编译后的UDF二进制类文件(.class文件)打包成一个JAR文件,然后在Hive会话中将这个JAR文件加入到类路径下,在通过createfunction语句定义好使用这个Java类的函数。
addjar
主要实现的是将数据装载到表中(或是从表中导出),并进行相应查询操作,对熟悉SQL语言的用户应该不会陌生。
向表中装载数据
这里我们以只有两个属性的简单表为例来介绍。首先创建表stu和course,stu有两个属性id与name,course有两个属性cid与sid。
createtableifnotexistshive.stu(idint,namestring)rowformatdelimitedfieldsterminatedby'\t';createtableifnotexistshive.course(cidint,sidint)rowformatdelimitedfieldsterminatedby'\t';向表中装载数据有两种方法:从文件中导入和通过查询语句插入。
a.从文件中导入
假如这个表中的记录存储于文件stu.txt中,该文件的存储路径为usr/local/hadoop/examples/stu.txt,内容如下。
stu.txt:
1xiapi2xiaoxue3qingqing下面我们把这个文件中的数据装载到表stu中,操作如下:
loaddatalocalinpath'/usr/local/hadoop/examples/stu.txt'overwriteintotablestu;如果stu.txt文件存储在HDFS上,则不需要local关键字。
b.通过查询语句插入
使用如下命令,创建stu1表,它和stu表属性相同,我们要把从stu表中查询得到的数据插入到stu1中:
createtablestu1asselectid,namefromstu;上面是创建表,并直接向新表插入数据;若表已经存在,向表中插入数据需执行以下命令:
insertoverwritetablestu1selectid,namefromstuwhere(条件);这里关键字overwrite的作用是替换掉表(或分区)中原有数据,换成into关键字,直接追加到原有内容后。
从表中导出数据
a.可以简单拷贝文件或文件夹
命令如下:
hadoopfs-cpsource_pathtarget_path;b.写入临时文件
insertoverwritelocaldirectory'/usr/local/hadoop/tmp/stu'selectid,namefromstu;查询操作
和SQL的查询完全一样,这里不再赘述。主要使用select...from...where...等语句,再结合关键字groupby、having、like、rlike等操作。这里我们简单介绍一下SQL中没有的case...when...then...句式、join操作和子查询操作。
case...when...then...句式和if条件语句类似,用于处理单个列的查询结果,语句如下:
selectid,name,casewhenid=1then'first'whenid=2then'second'else'third'结果如下:
连接连接(join)是将两个表中在共同数据项上相互匹配的那些行合并起来,HiveQL的连接分为内连接、左向外连接、右向外连接、全外连接和半连接5种。
a.内连接(等值连接)内连接使用比较运算符根据每个表共有的列的值匹配两个表中的行。
首先,我们先把以下内容插入到course表中(自行完成)。
132131下面,查询stu和course表中学号相同的所有行,命令如下:
selectstu.*,course.*fromstujoincourseon(stu.id=course.sid);执行结果如下:
selectstu.*,course.*fromstuleftouterjoincourseon(stu.id=course.sid);执行结果如下:
c.右连接右连接是左向外连接的反向连接,将返回右表的所有行。如果右表的某行在左表中没有匹配行,则将为左表返回空值。命令如下:
selectstu.*,course.*fromsturightouterjoincourseon(stu.id=course.sid);执行结果如下:
d.全连接全连接返回左表和右表中的所有行。当某行在另一表中没有匹配行时,则另一个表的选择列表包含空值。如果表之间有匹配行,则整个结果集包含基表的数据值。命令如下:
selectstu.*,course.*fromstufullouterjoincourseon(stu.id=course.sid);执行结果如下:
e.半连接半连接是Hive所特有的,Hive不支持in操作,但是拥有替代的方案;leftsemijoin,称为半连接,需要注意的是连接的表不能在查询的列中,只能出现在on子句中。命令如下:
selectstu.*fromstuleftsemijoincourseon(stu.id=course.sid);执行结果如下:
子查询标准SQL的子查询支持嵌套的select子句,HiveQL对子查询的支持很有限,只能在from引导的子句中出现子查询。
注意,在定义或是操作表时,不要忘记指定所需数据库。
下面我们以词频统计算法为例,来介绍怎么在具体应用中使用Hive。词频统计算法又是最能体现MapReduce思想的算法之一,这里我们可以对比它在MapReduce中的实现,来说明使用Hive后的优势。
MapReduce实现词频统计的代码可以通过下载Hadoop源码后,在$HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-examples-2.7.1.jar包中找到(wordcount类),wordcount类由63行Java代码编写而成。下面首先简单介绍一下怎么使用MapReduce中wordcount类来统计单词出现的次数,具体步骤如下:
1)创建input目录,output目录会自动生成。其中input为输入目录,output目录为输出目录。命令如下:
cd/usr/local/hadoopmkdirinput2)然后,在input文件夹中创建两个测试文件file1.txt和file2.txt,命令如下:
cd/usr/local/hadoop/inputecho"helloworld">file1.txtecho"hellohadoop">file2.txt3)执行如下hadoop命令:
cd..hadoopjarshare/hadoop/mapreduce/hadoop-mapreduce-examples-2.4.1.jarwordcountinputoutput4)我们可以到output文件夹中查看结果,结果如下:
下面我们通过HiveQL实现词频统计功能,此时只要编写下面7行代码,而且不需要进行编译生成jar来执行。HiveQL实现命令如下:
createtabledocs(linestring);loaddatainpath'input'overwriteintotabledocs;createtableword_countasselectword,count(1)ascountfrom(selectexplode(split(line,''))aswordfromdocs)wgroupbywordorderbyword;执行后,用select语句查看,结果如下:
由上可知,采用Hive实现最大的优势是,对于非程序员,不用学习编写JavaMapReduce代码了,只需要用户学习使用HiveQL就可以了,而这对于有SQL基础的用户而言是非常容易的。