目录
Hive最初是Facebook为了满足对海量社交网络数据的管理和机器学习的需求而产生和发展的。互联网现在进入了大数据时代,大数据是现在互联网的趋势,而hadoop就是大数据时代里的核心技术,但是hadoop的mapreduce操作专业性太强,所以facebook在这些基础上开发了hive框架。
Hive是基于 Hadoop 的一个数据仓库工具,可以将结构化的数据映射为一张数据库表,并提供 HQL(Hive SQL)查询功能,其底层数据是存储在 HDFS 上。Hive的本质是将 SQL 语句转换为 MapReduce 任务运行,使不熟悉 MapReduce 的用户很方便地利用 HQL 处理和计算 HDFS 上的结构化的数据,适用于离线的批量数据计算。Hive 依赖于 HDFS 存储数据,Hive 将 HQL 转换成 MapReduce 执行,所以说 Hive 是基于 Hadoop 的一个数据仓库工具,实质就是一款基于 HDFS 的 MapReduce 计算框架,对存储在 HDFS 中的数据进行分析和管理。
Hive常见的应用场景:
(1)日志分析:大部分互联网公司使用hive进行日志分析,包括百度、淘宝等。
1)统计网站一个时间段内的pv、uv
2)多维度数据分析
(2)海量结构化数据离线分析
1 Hive架构
下面的组件图描绘了Hive的结构:
从图中可以看到Hive主要由用户接口/界面、元存储、HiveQL处理引擎、执行引擎、HDFS等组件单元组成,下面描述每个单元:
单元名称 | 操作 |
用户接口/界面 | Hive是一个数据仓库基础工具软件,可以创建用户和HDFS之间互动。用户界面,Hive支持是Hive的Web UI,Hive命令行,HiveHD洞察(在Windows服务器)。 |
元存储 | Hive选择各自的数据库服务器,用以储存表,数据库,列模式或元数据表,它们的数据类型和HDFS映射。 |
HiveQL处理引擎 | HiveQL类似于SQL的查询上Metastore模式信息。这是传统的方式进行MapReduce程序的替代品之一。相反,使用Java编写的MapReduce程序,可以编写为MapReduce工作,并处理它的查询。 |
执行引擎 | HiveQL处理引擎和MapReduce的结合部分是由Hive执行引擎。执行引擎处理查询并产生结果和MapReduce的结果一样。它采用MapReduce方法。 |
HDFS 或 HBASE | Hadoop的分布式文件系统或者HBASE数据存储技术是用于将数据存储到文件系统。 |
2 Hive工作原理
Hive工作原理如下图7-2所示:
Hive查询流程大致步骤为:
1. 用户提交查询等任务给Driver。
2. 编译器获得该用户的任务Plan。
3. 编译器Compiler根据用户任务去MetaStore中获取需要的Hive的元数据信息。
4. 编译器Compiler得到元数据信息,对任务进行编译,先将HiveQL转换为抽象语法树,然后将抽象语法树转换成查询块,将查询块转化为逻辑的查询计划,重写逻辑查询计划,将逻辑计划转化为物理的计划(MapReduce), 最后选择最佳的策略。
5. 将最终的计划提交给Driver。
6. Driver将计划Plan转交给ExecutionEngine去执行,获取元数据信息,提交给JobTracker或者SourceManager执行该任务,任务会直接读取HDFS中文件进行相应的操作。
7. 获取执行的结果。
8. 取得并返回执行结果。
3 Hive特点
优点:
1、简单容易上手:提供了类SQL查询语言HQL
2、可扩展性,横向扩展,Hive 可以自由的扩展集群的规模,一般情况下不需要重启服务
3、延展性,Hive 支持自定义函数,用户可以根据自己的需求来实现自己的函数
4、良好的容错性,可以保障即使有节点出现问题,SQL 语句仍可完成执行
缺点:
1、Hive的HQL表达能力有限,迭代式算法及数据挖掘算法无法表达
2、Hive 的查询延时很严重,因为 MapReduce Job 的启动过程消耗很长时间,所以不能用在交互查询系统中。
3、Hive 不支持事务。
4 Hive与RDBMS的对比
Hive与RDBMS的对比如下图所示:
5 Hive部署
Hive的搭建依赖于Java和Hadoop,在搭建Hive的时首先要搭建Java和Hadoop,此处不再讲解Java和Hadoop的搭建。
第一步:下载Hive
我们在本教程中使用hive-0.14.0。可以通过访问以下链接下载 http://apache.petsads.us/hive/hive-0.14.0/. 假设它下载到/Downloads目录。在这里,我们下载一个名为“apache-hive-0.14.0-bin.tar.gz”的Hive存档。
第二步:安装Hive
需要执行以下步骤在系统上安装配置单元。假设Hive存档下载到/Downloads目录。提取和验证Hive存档 下面的命令来验证下载并解压hive存档:
$ tar zxvf apache-hive-0.14.0-bin.tar.gz
将文件复制到/usr/local/hive目录
$ mv apache-hive-0.14.0-bin /usr/local/hive
设置Hive环境
可以设置Hive环境,通过附加以下行到〜/.bashrc文件中:
export HIVE_HOME=/usr/local/hive
export PATH=$PATH:$HIVE_HOME/bin
export CLASSPATH=$CLASSPATH:/usr/local/Hadoop/lib/*:.
export CLASSPATH=$CLASSPATH:/usr/local/hive/lib/*:.
下面的命令是用来执行〜/.bashrc文件。
$ source ~/.bashrc
第三步:配置Hive
配置Hive用于Hadoop环境中,需要编辑hive-env.sh文件,该文件放置在 $HIVE_HOME/conf目录。下面的命令重定向到Hive config文件夹并复制模板文件:
$ cd $HIVE_HOME/conf
$ cp hive-env.sh.template hive-env.sh
通过编辑hive-env.sh文件添加以下行:
export HADOOP_HOME=/usr/local/Hadoop
Hive安装成功完成。现在,需要一个外部数据库服务器配置Metastore。我们使用Apache Derby数据库。
第四步:下载并安装Apache Derby
按照下面的步骤来下载和安装Apache Derby:
下载 Apache Derby 下面的命令用于下载Apache Derby。它下载需要一定的时间。
$ wget http://archive.apache.org/dist/db/derby/db-derby-10.4.2.0/db-derby-10.4.2.0-bin.tar.gz
解压Derby
下面的命令用于解压Derby:
$ tar zxvf db-derby-10.4.2.0-bin.tar.gz
将文件复制到/usr/local/derby 目录
$ mv db-derby-10.4.2.0-bin /usr/local/derby
设置Derby环境
可以通过附加以下行到〜/.bashrc文件设置Derby环境:
export DERBY_HOME=/usr/local/derby
export PATH=$PATH:$DERBY_HOME/bin
Apache Hive
18
export CLASSPATH=$CLASSPATH:$DERBY_HOME/lib/derby.jar:$DERBY_HOME/lib/derbytools.jar
下面的命令是用来执行〜/.bashrc文件:
$ source ~/.bashrc
创建一个目录来存放Metastore
创建一个名为data目录在$DERBY_HOME目录中,用于存储Metastore数据。
$ mkdir $DERBY_HOME/data
Derby安装和环境设置完成。
第五步:配置Hive的Metastore
配置Metastore意味着,指定要Hive的数据库存储。可以通过编辑hive-site.xml 文件,在$HIVE_HOME/conf目录下可以做到这一点。首先,使用以下命令复制模板文件:
$ cd $HIVE_HOME/conf
$ cp hive-default.xml.template hive-site.xml
编辑hive-site.xml并在<configuration>和</configuration>标记之间追加以下行:
<property>
<name>javax.jdo.option.ConnectionURL</name>
<value>jdbc:derby://localhost:1527/metastore_db;create=true </value>
<description>JDBC connect string for a JDBC metastore </description>
</property>
创建一个文件名为 jpox.properties 并添加以下行:
$ cd $HIVE_HOME/conf
$ vim jpox.properties
javax.jdo.PersistenceManagerFactoryClass =org.jpox.PersistenceManagerFactoryImpl
org.jpox.autoCreateSchema = false
org.jpox.validateTables = false
org.jpox.validateColumns = false
org.jpox.validateConstraints = false
org.jpox.storeManagerType = rdbms
org.jpox.autoCreateSchema = true
org.jpox.autoStartMechanismMode = checked
org.jpox.transactionIsolation = read_committed
javax.jdo.option.DetachAllOnCommit = true
javax.jdo.option.NontransactionalRead = true
javax.jdo.option.ConnectionDriverName = org.apache.derby.jdbc.ClientDriver
javax.jdo.option.ConnectionURL = jdbc:derby://hadoop1:1527/metastore_db;create = true
javax.jdo.option.ConnectionUserName = APP
javax.jdo.option.ConnectionPassword = mine
第六步:验证Hive安装
运行Hive之前,需要创建/tmp文件夹在HDFS独立的Hive文件夹。在这里使用/user/hive/warehouse文件夹。需要给这些新创建的文件夹写权限,如下图所示:
$ $HADOOP_HOME/bin/hadoop fs -mkdir /tmp
$ $HADOOP_HOME/bin/hadoop fs -mkdir /user/hive/warehouse
$ $HADOOP_HOME/bin/hadoop fs -chmod g+w /tmp
$ $HADOOP_HOME/bin/hadoop fs -chmod g+w /user/hive/warehouse
下面的命令来验证配置单元安装:
$ cd $HIVE_HOME
$ bin/hive
在成功安装Hive后,能看到以下回应:
Logging initialized using configuration in jar:file:/home/hadoop/hive-0.9.0/lib/hive-common-0.9.0.jar!/hive-log4j.properties
Hive history file=/tmp/hadoop/hive_job_log_hadoop_201312121621_1494929084.txt
………………….
hive>
下面的示例命令以显示所有表:
hive> show tables;
OK
Time taken: 2.798 seconds
hive>
6 Hive数据类型
Hive数据类型分为四种,分别是:列类型、文字、Null值、复杂类型。
6.1 列类型
列类型被用作Hive的列数据类型。它们如下:
1 整型。整型数据可以指定使用整型数据类型,整型数据类型有四种:INT、 SMALLINT、TINYINT、SMALLINT。
2 字符串类型。字符串类型的数据类型可以使用单引号('')或双引号(“”)来指定。它包含两个数据类型:VARCHAR和CHAR。Hive遵循C-类型的转义字符。
3 时间戳。它支持传统的UNIX时间戳可选纳秒的精度。它支持的java.sql.Timestamp格式“YYYY-MM-DD HH:MM:SS.fffffffff”和格式“YYYY-MM-DD HH:MM:ss.ffffffffff”。
4 日期。DATE值在年/月/日的格式形式描述 {{YYYY-MM-DD}}。
5 小数类型。在Hive 小数类型与Java大十进制格式相同。它是用于表示不可改变任意精度。语法和示例如下:
DECIMAL(precision, scale)
decimal(10,0)
6 联合类型。联合类型是异类的数据类型的集合。可以使用联合创建的一个实例,语法和示例如下:
UNIONTYPE<int, double, array<string>, struct<a:int,b:string>>
{0:1}
{1:2.0}
{2:["three","four"]}
{3:{"a":5,"b":"five"}}
{2:["six","seven"]}
{3:{"a":8,"b":"eight"}}
{0:9}
{1:10.0}
6.2 文字类型
1 浮点类型。浮点类型是只不过有小数点的数字。通常,这种类型的数据组成DOUBLE数据类型。
2 十进制类型。十进制数据类型是只不过浮点值范围比DOUBLE数据类型更大。十进制类型的范围大约是 -10的308次幂到 10的308次幂。
6.3 NULL类型
缺少值通过特殊值NULL表示。
6.4 复杂类型
1 数组。在Hive 数组与在Java中使用的方法相同。
Syntax: ARRAY<data_type>
2 映射。映射在Hive类似于Java的映射。
Syntax: MAP<primitive_type, data_type>
3 结构体。在Hive结构体类似于使用复杂的数据。
Syntax: STRUCT<col_name : data_type [COMMENT col_comment], ...>
7 HQL与代码实例
Hive提供 HQL(Hive SQL)查询功能,同时也支持Java API对Hive进行操作,我们将分别以创建数据库、创建表及查询数据为例进行说明。
7.1 创建数据库
1 HQL创建数据库
在HQL中,创建数据库的语法声明如下:
CREATE DATABASE|SCHEMA [IF NOT EXISTS] <database name>
IF NOT EXISTS是一个可选子句,通知用户已经存在相同名称的数据库。下面的查询执行创建一个名为userdb数据库:
hive> CREATE DATABASE [IF NOT EXISTS] userdb;
或
hive> CREATE SCHEMA userdb;
下面的查询用于验证数据库列表:
hive> SHOW DATABASES;
default
userdb
2 代码创建数据库
import java.sql.SQLException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.sql.DriverManager;
public class HiveCreateDb {
private static String driverName = "org.apache.hadoop.hive.jdbc.HiveDriver";
public static void main(String[] args) throws SQLException {
// Register driver and create driver instance
Class.forName(driverName);
// get connection
Connection con = DriverManager.getConnection("jdbc:hive://localhost:10000/default", "", "");
Statement stmt = con.createStatement();
stmt.executeQuery("CREATE DATABASE userdb");
System.out.println(“Database userdb created successfully.”);
con.close();
}
}
7.2 创建表
1 HQL创建表
Hive中建表语句如下:
CREATE [TEMPORARY] [EXTERNAL] TABLE [IF NOT EXISTS] [db_name.] table_name
[(col_name data_type [COMMENT col_comment], ...)]
[COMMENT table_comment]
[ROW FORMAT row_format]
[STORED AS file_format]
假设需要使用CREATE TABLE语句创建一个名为employee表。下表列出了employee表中的字段和数据类型:
下面创建employe表:
hive> CREATE TABLE IF NOT EXISTS employee ( eid int, name String,
> salary String, destination String)
> COMMENT ‘Employee details’
> ROW FORMAT DELIMITED
> FIELDS TERMINATED BY ‘\t’
> LINES TERMINATED BY ‘\n’
> STORED AS TEXTFILE;
OK
Time taken: 5.905 seconds
hive>
2 代码创建表
import java.sql.SQLException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.sql.DriverManager;
public class HiveCreateTable {
private static String driverName = "org.apache.hadoop.hive.jdbc.HiveDriver";
public static void main(String[] args) throws SQLException {
// Register driver and create driver instance
Class.forName(driverName);
// get connection
Connection con = DriverManager.getConnection("jdbc:hive://localhost:10000/userdb", "", "");
// create statement
Statement stmt = con.createStatement();
// execute statement
stmt.executeQuery("CREATE TABLE IF NOT EXISTS "
+" employee ( eid int, name String, "
+" salary String, destignation String)"
+" COMMENT ‘Employee details’"
+" ROW FORMAT DELIMITED"
+" FIELDS TERMINATED BY ‘\t’"
+" LINES TERMINATED BY ‘\n’"
+" STORED AS TEXTFILE;");
System.out.println(“ Table employee created.”);
con.close();
}
}
7.3 加载数据
1 HQL加载数据
在Hive中,可以使用LOAD DATA语句加载数据,最好是使用LOAD DATA批量存储记录。有两种方法用来加载数据:一种是从本地文件系统,第二种是从Hadoop文件系统。
加载数据的语法如下:
LOAD DATA [LOCAL] INPATH 'filepath' [OVERWRITE] INTO TABLE tablename
[PARTITION (partcol1=val1, partcol2=val2 ...)]
LOCAL是标识符指定本地路径,它是可选的。OVERWRITE 是可选的,覆盖表中的数据。PARTITION 这是可选的。
/home/user目录中sample.txt文件内容如下:
1201 Gopal 45000 Technical manager
1202 Manisha 45000 Proof reader
1203 Masthanvali 40000 Technical writer
1204 Kiran 40000 Hr Admin
1205 Kranthi 30000 Op Admin
我们以加载/home/user目录中sample.txt文件至Hive为例:
hive> LOAD DATA LOCAL INPATH '/home/user/sample.txt'
> OVERWRITE INTO TABLE employee;
OK
Time taken: 15.905 seconds
hive>
2 代码加载数据
import java.sql.SQLException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.sql.DriverManager;
public class HiveLoadData {
private static String driverName = "org.apache.hadoop.hive.jdbc.HiveDriver";
public static void main(String[] args) throws SQLException {
// Register driver and create driver instance
Class.forName(driverName);
// get connection
Connection con = DriverManager.getConnection("jdbc:hive://localhost:10000/userdb", "", "");
// create statement
Statement stmt = con.createStatement();
// execute statement
stmt.executeQuery("LOAD DATA LOCAL INPATH '/home/user/sample.txt'" + "OVERWRITE INTO TABLE employee;");
System.out.println("Load Data into employee successful");
con.close();
}
}
7.4 数据查询
1 HQL数据查询
下面给出的是SELECT查询的语法:
SELECT [ALL | DISTINCT] select_expr, select_expr, ...
FROM table_reference
[WHERE where_condition]
[GROUP BY col_list]
[HAVING having_condition]
[CLUSTER BY col_list | [DISTRIBUTE BY col_list] [SORT BY col_list]]
[LIMIT number];
我们以查询工资大于30000的员工信息为例:
hive> SELECT * FROM employee WHERE salary>30000;
+------+--------------+-------------+-------------------+--------+
| ID | Name | Salary | Designation | Dept |
+------+--------------+-------------+-------------------+--------+
|1201 | Gopal | 45000 | Technical manager | TP |
|1202 | Manisha | 45000 | Proofreader | PR |
|1203 | Masthanvali | 40000 | Technical writer | TP |
|1204 | Krian | 40000 | Hr Admin | HR |
+------+--------------+-------------+-------------------+--------+
2 代码数据查询
import java.sql.SQLException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.sql.DriverManager;
public class HiveQLWhere {
private static String driverName = "org.apache.hadoop.hive.jdbc.HiveDriver";
public static void main(String[] args) throws SQLException {
// Register driver and create driver instance
Class.forName(driverName);
// get connection
Connection con = DriverManager.getConnection("jdbc:hive://localhost:10000/userdb", "", "");
// create statement
Statement stmt = con.createStatement();
// execute statement
Resultset res = stmt.executeQuery("SELECT * FROM employee WHERE salary>30000;");
System.out.println("Result:");
System.out.println(" ID \t Name \t Salary \t Designation \t Dept ");
while (res.next()) {
System.out.println(res.getInt(1) + " " + res.getString(2) + " " + res.getDouble(3) + " " + res.getString(4) + " " + res.getString(5));
}
con.close();
}
}
8 Hive小结
Hive 具有 SQL 数据库的外表,但应用场景与RDBMS完全不同,Hive 适合用来做海量离线数据统计分析以及日志分析,常常被用作数据仓库。
1234567