• 介绍

Apache Hive是一个构建于Hadoop的数据仓库,注意不是数据库。Hive可以看成是用户编程接口或者数据库的逻辑层,它本身并不存储和计算数据,它依赖于基于数据库(基于HDFS)和Mapreduce,也就是说Hive本身并不存储数据。其对数据操作的语言类似于SQL,名为HQL。

Hive可以基于mysql和hbase,其自带了一个数据库Derby(坑爹的数据库)。下面的介绍搭建中onHDFS就是采用默认数据库。

  • 搭建onHDFS

采用hive-0.13,可以与hadoop2.2兼容。

直接解压就好,在/etc/profile上添加Hive的路径:

export HIVE_HOME=/usr/hive-0.13.0-bin/
export PATH=$PATH:/usr/hive-0.13.0-bin/bin

其它的都不用更改就可以运行了。(采用了默认)

默认情况下(可以更改的,参数自己查文档):

hive在hdfs上的存储是:/user/hive/warehouse

hive的日志文件默认存储地址为:/tmp/root/下(以root用户运行时)

PS:

以derby方式存储时,运行hive后会在当前目录下(你的shell输入hive时所在的目录,我以root用户在根目录下输入hive,则就在/root文件夹下)生成一个derby文件和一个

metastore_db目录。切换到不同的目录时会再生成,不会保留原有数据。并且同一目录下只有一个hive客户端能使用数据(采用javaAPI时的一个bug与此有关。)所以,不建议采用derby存储数据。


搭建好后我们shell端输入hive就可以进入hive的操作目录了。

操作语言和sql差不多show databases; use xxx;show tables;select * from xxx where xxx = xxx;


  • 搭建onHBASE

采用hive-0.13,可以与hbase-0.96.0-hadoop2兼容

hive和hbase关联主要和一些jar文件关联。我们需要hive下的conf文件夹中加入:

hive-env.sh(由hive-env.sh.template改来):

加入

export HADOOP_HOME=/usr/hadoop-2.2.0
export HIVE_AUX_JARS_PATH=/usr/hbase-0.96.0-hadoop2/lib

hive-site.xml(由hive-default.xml.template改来):

加入:

<property>
  <name>hive.aux.jars.path</name>
  <value>file:///usr/hive-0.13.0-bin/lib/hive-hbase-handler-0.13.0.jar,file:///usr/hive-0.13.0-bin/lib/protobuf-java-2.5.0.jar,file:///usr/hive-0.13.0-bin/lib/hbase-client-0.96.0-hadoop2.jar,file:///usr/hive-0.13.0-bin/lib/hbase-common-0.96.0-hadoop2.jar,file:///usr/hive-0.13.0-bin/lib/zookeeper-3.4.5.jar,file:///usr/hive-0.13.0-bin/lib/guava-11.0.2.jar</value>
</property>

注意这些jar包Hbase中若有同名的需要拷入hive中,并删除hive中原有的(保证兼容)。如果没有则用hive的。

至此,配置完成。


  • shell操作

纯hive的操作很简单,可以看下HDFS&HIVE 操作命令。注意hive中可以批量load数据:

load data inpath '/dataImport/HbaseTable-1.cvs' into table person1;

数据要在HDFS上,而且load后原来的数据就没有了。

基于hbase的操作:

在hive中穿件表考虑hbase的映射情况,因为hbase中有列和列簇的分类,参看文章Hive与Hbase映射中关于列的映射部分。

在当前版本配置下,基于HBASE操作中的表结构,需要用下面的语句进行创建和关联:

CREATE TABLE hivetable1(rowid string,username string,userid string,birth string,phone string,sex string,height string,weight string,country string,city string,street string,company string,description string) STORED BY 'org.apache.hadoop.hive.hbase.HBaseStorageHandler' WITH SERDEPROPERTIES ("hbase.columns.mapping" = ":key,cf:username,cf:userid,cf:birth,cf:phone,cf:sex,cf:height,cf:weight,cf:country,cf:city,cf:street,cf:company,cf:description") TBLPROPERTIES ("hbase.table.name" = "hbasetable1");

其中粗体的分别是hive中的表名和hbase中的表名。斜体的分别是hive中的表结构和hbase中的表结构。

其中hbase的表结构第一个必须是rowid,后面的选项必须要有列簇和列名。(我全部用一个列簇cf)。

穿件完表后,可以分别在hive和hbase中进行操作。(hive中无法load数据)

  • JavaAPI操作

在hiveOnhdfs和hiveOnhbase中应该都可以,毕竟是面向hive的接口,而hive关联了hbase。

注意要想使用java访问,需要在hive中开出来一个端口:

hive --service hiveserver -p 10000

并用jdbc连接:

conn = DriverManager.getConnection("jdbc:hive://192.168.70.28:10000/default","","");

后连个参数是用户名和密码。

下面直接上源代码,主要是查询操作:

import java.sql.SQLException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.sql.DriverManager;

public class HiveAPI {
	private static String driverName = "org.apache.hadoop.hive.jdbc.HiveDriver";
	public static Connection conn = null;

	public static void init() {
		try {
			Class.forName(driverName);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
			System.exit(1);
		}
		try {
			conn = DriverManager.getConnection("jdbc:hive://192.168.70.28:10000/default","","");
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public static void close(){
		try {
			conn.close();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public static void queryByCondition(String tableNmae,String columnName,String value) throws SQLException{
		Statement stmt = conn.createStatement();
		String sql = "select * from "+tableNmae+" where "+ columnName + " ="+'"'+value+'"';
		System.out.println(sql);
		long start = System.currentTimeMillis();
		ResultSet res = stmt.executeQuery(sql);
		
		int num = 0;
		while(res.next()){
			num++;
		}
		long end = System.currentTimeMillis();
		System.out.println("rowNum: "+num);
		System.out.println(end-start);
	}
	
	public static void main(String[] args) throws SQLException {
		HiveAPI.init();
		HiveAPI.queryByCondition("hivetable1", "sex", "0");
		HiveAPI.close();
	}
}

注意要有HiveDriver这个类,负责无法访问。

依赖包要有:

hadoop-2.2.0/share/hadoop/common/hadoop-common-2.2.0.jar
$HIVE_HOME/lib/hive-exec-0.11.0.jar 
$HIVE_HOME/lib/hive-jdbc-0.11.0.jar 
$HIVE_HOME/lib/hive-metastore-0.11.0.jar  
$HIVE_HOME/lib/hive-service-0.11.0.jar   
$HIVE_HOME/lib/libfb303-0.9.0.jar   
$HIVE_HOME/lib/commons-logging-1.0.4.jar  
$HIVE_HOME/lib/slf4j-api-1.6.1.jar

如果是maven要有:

<dependency>
        <groupId>org.apache.hive</groupId>
        <artifactId>hive-jdbc</artifactId>
        <version>0.11.0</version>
</dependency>
 
<dependency>
        <groupId>org.apache.hadoop</groupId>
        <artifactId>hadoop-common</artifactId>
        <version>2.2.0</version>
</dependency>

上文提到有一个bug,就是在开启hiveserver时再进入一个hive shell,java访问就会出错。