Hive 的官网:http://hive.apache.org/
Hive versions 1.2 onward require Java 1.7 or newer.
上一篇提到的 MapRedue 虽然简化了分布式应用的实现方式,但还是离不开写代码。
Hive 简介
Hive 是基于 Hadoop 的一个【数据仓库工具】,可以将结构化的数据文件映射为一张 hive 数据库表,并提供简单的 sql 查询功能,可以将 sql 语句转换为 MapReduce 任务进行运行。
非 Java 编程者对 HDFS 的数据做 mapreduce 操作。
好处:使用 SQL 来快速实现简单的 MapReduce 统计,不必开发专门的 MapReduce 应用,学习成本低,十分适合数据仓库的统计分析。
数据仓库简介
Hive 是一个数据仓库工具,那么数据仓库是什么呢?相信大家对数据库并不陌生,翻译成英文是 DataBase , 而数据仓库的英文翻译是 Data Warehouse,可以简写成 DW 或 DWH。不同于数据库,数据仓库是面向主题的,为了支持决策创建的,主要理解这四个特点就可以了:面向主题、数据集成、历史数据、有时间维度的。
OLTP & OLAP
联机事务处理 on-line transaction processing
OLTP 是传统关系数据库的主要应用,主要是基本的事务处理,例如交易系统。
它强调数据库内存效率,强调各种指标的命令率,强调绑定变量,强调并发操作。
联机分析处理 on-line analytical processing
OLAP 是数据仓库的主要应用,支持复杂的分析操作,侧重决策支持,并且提供直观易懂的查询结果。
它强调数据分析,强调 SQL 执行市场,强调磁盘 I/O,强调分区。
下表是 OLTP 和 OLAP 的区别(用户,功能,DB 设计,数据,存取,工作单位,用户数,DB 大小,时间要求,主要应用)
OLTPOLAP用户初级的决策者、高级的功能基本查询分析决策DB 设计面向应用面向主题数据当前的。最新的细节,二维分立的历史的,多数据源的(聚集的,多维的)存取读取 10 条记录读上百万条记录工作单位简单的事务复杂的查询用户数上千个上百万个DB 大小MB-GBGB、TB、PB、EB时间要求实时对实时要求不严格主要应用数据库数据仓库
综上。数据仓库支持很复杂的查询,就是用来做数据分析的数据库。基本不用来做插入,修改,删除操作。
Hive 运行时,元数据存储在关系型数据库中。
还需要明确两点:
Hive 的真实数据是在 HDFS 上的。
Hive 的计算是通过 Yarn 和 MR 的。
Hive 架构
用户接口主要有三个:Cli, Client 和 WUI 。见图 1-1,图 1-2
![8e0c27da3d714d40d1b3d791a5a5ffc4.png](https://i-blog.csdnimg.cn/blog_migrate/4abd50fa194da3ea1581962576403557.jpeg)
图 1-1
![b072767246967f4f556c8ca7108c185f.png](https://i-blog.csdnimg.cn/blog_migrate/358c975389e5b2e5ab9b957c774145bf.jpeg)
图 1-2
从图中可以看到,有三种连接方式:
1.cli 是最常用的,cli 启动时,会同时创建一个 Hive 副本。
安装好之后,直接使用 hive 命令,进入 hive> ,如下图 1-3
![d8990da49cc7f9cb5999f6057299f1d9.png](https://i-blog.csdnimg.cn/blog_migrate/9ac3efd45ae5b19070c379db44c5c348.jpeg)
图 1-3
这种方式,也可以使用命令: hive --service cli
2.使用 Client 方式,需要在编写 JDBC 程序,需要指定 HIve Server。 所指定的节点需要开启 Hive Server。
Plain Text
1
$ $HIVE_HOME/bin/hiveserver2
2
$ $HIVE_HOME/bin/beeline -u jdbc:hive2://$HS2_HOST:$HS2_PORT
当然也可以使用 hive --service hivesrver2 的方式开启。
注:使用 hiveServer2 的方式和使用 metastore 方式不同的地方在于前者还可以提供 JDBC 等连接。
3.WUI ,使用浏览器使用 Hive。(这个很少用)
![dcac8ce6a9c4b2e8eae1a084042d3108.png](https://i-blog.csdnimg.cn/blog_migrate/ee45e17f4ed052bc014a9ad8ad627b93.jpeg)
数据仓库 Hive 的元数据存储在关系型数据库中,如 mysql,derby等。元数据包括表的名字,表的列,属性,数据所在目录等信息。
解释器,编译器,优化器成 HQL 查询语句从词法分析、语法分析、编译、优化以及查询计划的生成。生成的查询计划存储在HDFS中,并在随后有MapReduce调用执行。
Hive 的数据存储在 HDFS 中。计算由 Yarn 和 mapReduce 来完成。值得注意的是,SELECT * from XXX;这样的操作,不会提交 MapReduce 任务。
总结:
Hive 是一个基于 Hadoop 文件系统之上的数据仓库架构,存储用 hdfs,计算用 mapreduce。
Hive 可以理解为一个工具,不存在主从架构,不需要安装在每台服务器上,只需要安装几台就行了。
Hive 还支持类 sql 语言,它可以将结构化的数据文件映射为一张数据库表,并提供简单的SQL查询功能。
Hive 有个默认数据库:derby,默认存储元数据--->一般企业使用关系型数据库存储 mysql 元数据
。
三种部署方式
前提
下载安装包:apache-hive-1.2.1-bin.tar.gz ,解压。
准备 mysql 环境,用来保存元数据的。
有Hadoop 集群环境,Hive 存储要使用 HDFS 的。
内嵌模式
这种模式,使用的是内嵌的数据库 derby 来保存元数据,但是只允许一个会话连接。
配置很简单,只需要一个 hive-site.xml 文件。(注:使用 derby 存储方式时,运行 hive 会在当前目录生成一个 derby 文件和一个 metastore_db)
XML
1
<?xml version="1.0"?>
2
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
3
4
5
javax.jdo.option.ConnectionURL
6
jdbc:derby:;databaseName=metastore_db;create=true
7
8
9
javax.jdo.option.ConnectionDriverName
10
org.apache.derby.jdbc.EmbeddedDriver
11
12
13
hive.metastore.local
14
true
15
16
17
hive.metastore.warehouse.dir
18
/user/hive/warehouse
19
20
本地模式(测试用)
本地模式就是把元数据的存储介质由 derby 换成了 mysql 。
需要:
把 mysql 的驱动添加到 $HIVE_HOME 目录下的 lib 下。
配置文件:hive-site.xml, 注意这种方式 mysql 的账户密码就明文写在配置文件里面了。
XML
1
<?xml version="1.0"?>
2
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
3
4
5
hive.metastore.warehouse.dir
6
/user/hive_rlocal/warehouse
7
8
9
hive.metastore.local
10
true
11
12
13
javax.jdo.option.ConnectionURL
14
jdbc:mysql://node01/hive_local?createDatabaseIfNotExist=t
15
rue
16
17
18
javax.jdo.option.ConnectionDriverName
19
com.mysql.jdbc.Driver
20
21
22
javax.jdo.option.ConnectionUserName
23
root
24
25
26
javax.jdo.option.ConnectionPassword
27
123456
28
29
这里要说明一点的是,hive 和 MySQL 不用做 HA,单节点就可以。通过设置其他节点可以访问得到数据库。
远程模式(重要)
这种模式需要在远端的服务器运行一个 mysql 服务器,并且需要在 Hive 服务器开启 meta 服务。
hive-site.xml 文件。
XML
1
<?xml version="1.0"?>
2
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
3
4
5
hive.metastore.warehouse.dir
6
/user/hive/warehouse2
7
8
9
javax.jdo.option.ConnectionURL
10
jdbc:mysql://node03:3306/hive?createDatabaseIfNotExist=true
11
12
13
javax.jdo.option.ConnectionDriverName
14
com.mysql.jdbc.Driver
15
16
javax.jdo.option.ConnectionUserName
17
root
18
19
20
javax.jdo.option.ConnectionPassword
21
123456
22
23
24
hive.metastore.local
25
false
26
27
28
hive.metastore.uris
29
thrift://node01:9083
30
31
32
这里把 hive 的服务端和客户端都放在同一台服务器上了。服务端和客户端可以拆开,
远程模式(分开,企业常用)
服务端配置:
XML
1
<?xml version="1.0"?>
2
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
3
4
5
hive.metastore.warehouse.dir
6
/user/hive/warehouse-server
7
8
javax.jdo.option.ConnectionURL
9
jdbc:mysql://node03:3306/hive?createDatabaseIfNotExist=true
10
11
12
javax.jdo.option.ConnectionDriverName
13
com.mysql.jdbc.Driver
14
15
javax.jdo.option.ConnectionUserName
16
root
17
18
19
javax.jdo.option.ConnectionPassword
20
123456
21
22
启动:hive --service metastore
客户端配置
XML
1
2
<?xml version="1.0"?>
3
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
4
5
6
hive.metastore.warehouse.dir
7
/user/hive/warehouse-server
8
9
10
hive.metastore.local
11
false
12
13
14
hive.metastore.uris
15
thrift://node01:9083
16
17
Hive常见问题总汇: 链接
HSQL 详解
可以查看官网更加详细的案例:https://cwiki.apache.org/confluence/display/Hive/LanguageManual
DDL 语句:详情看这里 https://cwiki.apache.org/confluence/display/Hive/LanguageManual+DDL
下面,记录的是一些常用的操作,重要的是建表语句和分区。
下面只展示几个例子,以供大家参考
创建数据库:
create database if not exists foo; 创建数据库,不存在则创建。
create database foo comment 'this is a database for test '; 创建数据库,并指定描述信息
数据库的位置默认是在 HDFS 上的 /user/hive/warehouse/ 目录下的,可以通过 show create database foo会打印出,创建数据库的信息。
Hive 会为每一个数据库创建一个目录,该数据库的每张表都会存在该目录的子目录里面。
删除数据库:使用 DROP 命令
修改数据库:使用 ALTER 命令
查看数据库描述:使用 describe 命令
切换数据库:使用 use 命令
创建表:
先来看一下数据类型
数据类型:
data_type:标蓝色的是常用的
| primitive_type 原始数据类型
| array_type 数组
**
| map_type map键值对**
| struct_type
| union_type -- (Note: Available in Hive 0.7.0 and later)
primitive_type
: TINYINT
| SMALLINT
| INT
| BIGINT
| BOOLEAN
| FLOAT
| DOUBLE
| DOUBLE PRECISION
| STRING 基本可以搞定一切
BINARY
| TIMESTAMP
| DECIMAL
| DECIMAL(precision, scale) | DATE
| VARCHAR
| CHAR
**
array_type
: ARRAY < data_type > **
map_type
: MAP < primitive_type, data_type > struct_type
: STRUCT < col_name : data_type [COMMENT col_comment], ...>
union_type
: UNIONTYPE < data_type, data_type, ... >
![578d33c25d9a7e95e4b77a7f4f61075b.png](https://i-blog.csdnimg.cn/blog_migrate/cb614b1b552c835779700f53e85d12f4.jpeg)
例子:
SQL
1
create table foo(
2
id int,
3
name string,
4
age int,
5
likes array,
6
address map
7
)
8
row format delimited fields terminated by ','
9
COLLECTION ITEMS TERMINATED by '-'
10
map keys terminated by ':'
11
lines terminated by '';
准备如下测试数据,字段
Bash
1
1,lily,18,game-girl-book,stu_addr:beijing-work_addr:shanghai
2
2,tom,16,shop-swimming-book,stu_addr:hunan-work_addr:shanghai
3
3,bob,20,read-run,stu_addr:shanghai-work_addr:USA
准备好数据之后,开始导入数据:
语法:
LOAD DATA [LOCAL] INPATH 'filepath' [OVERWRITE] INTO TABLE tablename [PARTITION (partcol1=val1, partcol2=val2 ...)]
操作:
load data local inpath '/opt/datas/hive_test.txt' into table foo;
说明:local 指定的是系统的本地路径,如果不加 local,就要指定 hdfs 上的路径。
导入数据之后,可以看到 mysql 数据库中有一些元数据信息,如下:
![5610296aeda3f343eb60c1c55a4103c9.png](https://i-blog.csdnimg.cn/blog_migrate/28d648f3ed36abf57008d33a6734489b.jpeg)
分区表
使用关键词 PARTITIONED BY 来指定分区字段,一张表可以有一个或者多个分区,数据按照分区字段分别存储到不同的目录下。简单的分区表如下:
SQL
1
create table table_name (
2
id int,
3
dtDontQuery string,
4
name string
5
)
6
partitioned by (date string)
更多关于分区表的内容,下面会介绍的。
上面是 DDL 的一些操作,重点是建表语句和分区语句。下面简单总结一下,
- Managed and External Tables:内表和外表的区别,建立外表需要加上额外的关键词 external ,外表的数据可以指向任何 HDFS 的位置,而不一定是默认的位置。删除外表的时候,不会删除数据,只会删除元数据。
- 为了健壮性,建表的时候最好加上 IF NOT EXISTS 来避免发生异常。
- Hive 的存储格式:textFile 、SEQUENCEFILE、ORC 等。
DML
具体可以参考:https://cwiki.apache.org/confluence/display/Hive/LanguageManual+DML
Hive 不能很好的支持用 insert 语句一条一条的进行插入操作,不支持 update 操作。数据是以 load 的方式加载到建立好的表中。数据一旦导入就不可以修改。
插入数据
第一种:
LOAD DATA [LOCAL] INPATH 'filepath' [OVERWRITE] INTO TABLEtablename [PARTITION (partcol1=val1, partcol2=val2 ...)]
可选项:local 、overwrite 、partition
第二种:
创建表的时候,通过 select 或者 insert 或者 location 加载数据。注意通过 insert 这种方式个非常耗时,尽量避免使用这种方式。
参考:https://www.2cto.com/kf/201609/545560.html
本地 load 数据和从 HDFS 上 load 加载数据的过程有什么区别?
本地: local 会自动复制到 HDFS 上的 hive 的**目录下
查询数据并保存
第一种,保存到本地:insert overwrite local directory '/opt/date/xxx.txt' ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' select * from table_name;
第二种,保存到 HDFS 上的某个路径上:insert overwrite directory '/opt/date/xxx.txt' ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' select * from table_name;
第三种,可以在 hive客户端执行 hive -e "select * from table_name " > "/opt/data/xxx.txt" 重定向到文件。
备份或还原数据
使用 export table db_2019.emp to '/xx/xx' 备份数据
使用 import from '/xx/xx' 还原数据
常见的查询,如 group by、 having、join 、sort by、order by等,与 mysql 类似。
Hive SerDe 用于对做序列化和反序列化,构建在数据存储和计算引擎之间,实现两者的解耦。下面是官网的几个例子:
SQL
1
CREATE TABLE apachelog (
2
host STRING,
3
identity STRING,
4
user STRING,
5
time STRING,
6
request STRING,
7
status STRING,
8
size STRING,
9
referer STRING,
10
agent STRING)
11
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.RegexSerDe'
12
WITH SERDEPROPERTIES (
13
"input.regex" = "([^]*) ([^]*) ([^]*) (-|[^]*]) ([^ "]*|"[^"]*") (-|[0-9]*) (-|[0-9]*)(?: ([^ "]*|".*") ([^ "]*|".*"))?"
14
)
15
STORED AS TEXTFILE;
SQL
1
CREATE TABLE my_table(a string, b bigint, ...)
2
ROW FORMAT SERDE 'org.apache.hive.hcatalog.data.JsonSerDe'
3
STORED AS TEXTFILE;
Beeline & Hiveserver2
官网的描述:
Beeline is started with the JDBC URL of the HiveServer2, which depends on the address and port where HiveServer2 was started.
By default, it will be (localhost:10000), so the address will look like jdbc:hive2://localhost:10000.
Beeline 和 cli 的区别:CliDriver是 SQL 本地直接编译,然后访问 MetaStore,提交作业,是重客户端。
BeeLine 是把 SQL 提交给 HiveServer2,由 HiveServer2 编译,然后访问 MetaStore,提交作业,是轻客户端。
这种模式下经常用来使用 JDBC 来查询数据,下面是一个官网的示例代码:
Java
1
import java.sql.SQLException;
2
import java.sql.Connection;
3
import java.sql.ResultSet;
4
import java.sql.Statement;
5
import java.sql.DriverManager;
6
7
public class HiveJdbcClient {
8
private static String driverName = "org.apache.hive.jdbc.HiveDriver";
9
10
/**
11
* @param args
12
* @throws SQLException
13
*/
14
public static void main(String[] args) throws SQLException {
15
try {
16
Class.forName(driverName);
17
} catch (ClassNotFoundException e) {
18
// TODO Auto-generated catch block
19
e.printStackTrace();
20
System.exit(1);
21
}
22
//replace "hive" here with the name of the user the queries should run as
23
Connection con = DriverManager.getConnection("jdbc:hive2://localhost:10000/default