1. Hive 简介
1.1. 什么是 HiveHive
是基于 Hadoop 的一个数据仓库工具,可以将结构化的数据文件映射为一张数据库表,并提供类 SQL 查询功能。
本质是将 SQL 转换为 MapReduce 程序。 可以将hive理解为hadoop的一个客户端,因为是hive去连接hdfs,是hive去提交MapReduce程序到hadoop中的ResourceManager主节点。
主要用途:用来做离线数据分析,比直接用 MapReduce 开发效率更高。
1.2. 为什么使用 Hive直接使用 Hadoop MapReduce 处理数据所面临的问题:
人员学习成本太高
MapReduce 实现复杂查询逻辑开发难度太大
使用 Hive :
操作接口采用类 SQL 语法,提供快速开发的能力
避免了去写 MapReduce,减少开发人员的学习成本
功能扩展很方便
2. Hive 架构
2.1. Hive 架构图
2.2. Hive 组件
用户接口:包括 CLI、JDBC/ODBC、WebGUI。其中,CLI(command line interface)为 shell 命令行;JDBC/ODBC 是 Hive 的 JAVA 实现,与传统数据库JDBC 类似;WebGUI 是通过浏览器访问 Hive。
元数据存储:通常是存储在关系数据库如 mysql/derby 中。Hive 将元数据存储在数据库中。Hive 中的元数据包括表的名字,表的列和分区及其属性,表的属性(是否为外部表等),表的数据所在目录等。
解释器、编译器、优化器、执行器:完成 HQL 查询语句从词法分析、语法分析、编译、优化以及查询计划的生成。生成的查询计划存储在 HDFS 中,并在随MapReduce 调用执行。
2.3. Hive 与 Hadoop 的关系
Hive 利用 HDFS 存储数据,利用 MapReduce 查询分析数据。
3. Hive 与传统数据库对比
hive 用于海量数据的离线数据分析。
hive 具有 sql 数据库的外表,但应用场景完全不同,hive 只适合用来做批
量数据统计分析。
更直观的对比请看下面这幅图:
4. Hive 数据模型
Hive 中所有的数据都存储在 HDFS 中,没有专门的数据存储格式
在创建表时指定数据中的分隔符,Hive 就可以映射成功,解析数据。
Hive 中包含以下数据模型:
db:在 hdfs 中表现为 hive.metastore.warehouse.dir 目录下一个文件夹
table:在 hdfs 中表现所属 db 目录下一个文件夹
external table:数据存放位置可以在 HDFS 任意指定路径
partition:在 hdfs 中表现为 table 目录下的子目录
bucket:在 hdfs 中表现为同一个表目录下根据 hash 散列之后的多个文件
5. Hive 安装部署
安装环境 :首先 安装hive要有jdk(1.7以上 我所安装的为1.8版本64位)
其次要有hadoop集群,hive需要MapReduce和HDFS(hadoop部署可见其他文档)
mysql :虽然hive内嵌了一个关系型数据库derby。但是内置的derby容量小,有些权限受限,不便于管理。所以使用mysql,用来做表的映射等.(mysql安装可见其他文档)
上传文件Apache Hive jar包 并解压(可以去官网下载hive安装包Index of /apache/hive)
首先要保证mysql可以正常使用 提供mysql下载方法
在线安装
mysql yum install mysql mysql-server mysql-devel
配置
1 vi conf/hive-env.sh
hadoop环境变量 在配置文件中找到hadoop_home,linux中安装hadoop的位置
hadoop_home export HADOOP_HOME=/export/server/hadoop-2.7.4(hadoop所在位置)
配置元数据库信息
1 vi hive-site.xml
添加如下内容:
1 <configuration>
2 <property>
3 <name>javax.jdo.option.ConnectionURL</name>
4 <value>jdbc:mysql://localhost:3306/hive?createDatabaseIfNotExist=true</value>
5 <description>JDBC connect string for a JDBC metastore</description>
6 </property>
7
8 <property>
9 <name>javax.jdo.option.ConnectionDriverName</name>
10 <value>com.mysql.jdbc.Driver</value>
11 <description>Driver class name for a JDBC metastore</description>
12 </property>
13
14 <property>
15 <name>javax.jdo.option.ConnectionUserName</name>
16 <value>root</value>
17 <description>username to use against metastore database</description>
18 </property>
19
20 <property>
21 <name>javax.jdo.option.ConnectionPassword</name>
22 <value>root</value>
23 <description>password to use against metastore database</description>
24 </property>
25 </configuration>
安装完成之后 在hive文件夹下启动 bin/hive
Hive几种使用方式:
1.Hive交互shell bin/hive
2.Hive JDBC服务(参考java jdbc连接mysql)
3.hive启动为一个服务器,来对外提供服务
bin/hiveserver2
nohup bin/hiveserver2 1>/var/log/hiveserver.log 2>/var/log/hiveserver.err &
启动成功后,可以在别的节点上用beeline去连接
bin/beeline -u jdbc:hive2://mini1:10000 -n root
或者 先启动主节点
bin/hiveserver2 //在主节点作为服务器启动
bin/beeline //在其他节点上连接
! connect jdbc:hive2://node-1:10000 //node-1为主机名 默认端口号10000
node-1作为主节点启动 node-3做远程连接 连接成功服务器会打印ok
可以看到 hive源数据库一样 不管是本机启动 还是远程访问 使用的都是mysql中的数据
六 hive基本操作
DDL 创建表 分隔符 映射数据文件
建表语法
CREATE [EXTERNAL] TABLE [IF NOT EXISTS] table_name
[(col_name data_type [COMMENT col_comment], ...)]
[COMMENT table_comment]
[PARTITIONED BY (col_name data_type [COMMENT col_comment], ...)]
[CLUSTERED BY (col_name, col_name, ...)
[SORTED BY (col_name [ASC|DESC], ...)] INTO num_buckets BUCKETS]
[ROW FORMAT row_format]
[STORED AS file_format]
[LOCATION hdfs_path]
说明:
1、 CREATE TABLE 创建一个指定名字的表。如果相同名字的表已经存在,则抛出异常;
用户可以用 IF NOT EXISTS 选项来忽略这个异常。
2、 EXTERNAL 关键字可以让用户创建一个外部表,在建表的同时指定一个指向实际数据的路径(LOCATION) 。
Hive 创建内部表时,会将数据移动到数据仓库指向的路径;若创建外部表,仅记录数据所在的路径,不对数据的位置做任何改变。在删除表的时候,内部表的元数据和数据会被一起删除,而外部表只删除元数据,不删除数据。
3、 LIKE 允许用户复制现有的表结构,但是不复制数据。
CREATE [EXTERNAL] TABLE [IF NOT EXISTS] [db_name.]table_name LIKE existing_table;
4、
ROW FORMAT DELIMITED
[FIELDS TERMINATED BY char]
[COLLECTION ITEMS TERMINATED BY char]
[MAP KEYS TERMINATED BY char]
[LINES TERMINATED BY char] | SERDE serde_name
[WITH SERDEPROPERTIES
(property_name=property_value, property_name=property_value,...)]
hive 建表的时候默认的分割符是'\001',若在建表的时候没有指明分隔符,load 文件的时候文件的分隔符需要是'\001';若文件分隔符不是'001',程序不会报错,但表查询的结果会全部为'null';
用 vi 编辑器 Ctrl+v 然后 Ctrl+a 即可输入'\001' -----------> ^A
SerDe 是 Serialize/Deserilize 的简称,目的是用于序列化和反序列化。
Hive 读取文件机制:首先调用 InputFormat(默认 TextInputFormat),返回一条一条记录(默认是一行对应一条记录)。然后调用SerDe(默认LazySimpleSerDe)的 Deserializer,将一条记录切分为各个字段(默认'\001') 。
Hive 写文件机制:将 Row 写入文件时,主要调用 OutputFormat、SerDe 的Seriliazer,顺序与读取相反。
可通过 desc formatted 表名;进行相关信息查看。
当我们的数据格式比较特殊的时候,可以自定义 SerDe。
5、 PARTITIONED BY
在 hive Select 查询中一般会扫描整个表内容,会消耗很多时间做没必要的工作。有时候只需要扫描表中关心的一部分数据,因此建表时引入了 partition 分区
概念。
分区表指的是在创建表时指定的 partition 的分区空间。一个表可以拥有一个或者多个分区,每个分区以文件夹的形式单独存在表文件夹的目录下。表和列名不区分大小写。分区是以字段的形式在表结构中存在,通过 describe table 命令可以查看到字段存在,但是该字段不存放实际的数据内容,仅仅是分区的表示。
6、 STORED AS SEQUENCEFILE|TEXTFILE|RCFILE
如果文件数据是纯文本,可以使用 STORED AS TEXTFILE。如果数据需要压缩,使用 STORED AS SEQUENCEFILE。
TEXTFILE 是默认的文件格式,使用 DELIMITED 子句来读取分隔的文件。
6、CLUSTERED BY INTO num_buckets BUCKETS
对于每一个表(table)或者分,Hive 可以进一步组织成桶,也就是说桶是更为细粒度的数据范围划分。Hive 也是针对某一列进行桶的组织。Hive 采用对列值哈希,然后除以桶的个数求余的方式决定该条记录存放在哪个桶当中。
把表(或者分区)组织成桶(Bucket)有两个理由:
(1)获得更高的查询处理效率。桶为表加上了额外的结构,Hive 在处理有些查询时能利用这个结构。具体而言,连接两个在(包含连接列的)相同列上划分了桶的表,可以使用 Map 端连接 (Map-side join)高效的实现。比如 JOIN 操作。对于 JOIN 操作两个表有一个相同的列,如果对这两个表都进行了桶操作。那么将保存相同列值的桶进行 JOIN 操作就可以,可以大大较少 JOIN 的数据量。
(2)使取样(sampling)更高效。在处理大规模数据集时,在开发和修改查询的阶
段,如果能在数据集的一小部分数据上试运行查询,会带来很多方便。
SQL语言共分为四大类:
数据查询语言DQL,
数据操纵语言DML,
数据定义语言DDL,
数据控制语言DCL。
与传统sql保持一致
[可加可不加]
| 只选其一
支持传统sql数据类型 与java数据类型
建表的时候要根据表的数据特征 指定分隔符
复杂类型的数据表指定分隔符
默认分隔符
Ctrl v Ctrl a
指定分隔符(逗号分隔符):
create table db1 (id int,name string, age int) row format delimited fields terminated by ',';
复杂类型的数据表指定分隔符:
create table complex_array(name string,work_locations array<string>) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' COLLECTION ITEMS TERMINATED BY ',';
下面为具体操作:
表的mysql中 表的映射
结构化的文件 映射为一张表
例如 1,ali
2,anqila
首先上传到hdfs上 hive用hdfs做数据存储
copy文件:
hadoop fs -cp /hivedata/db1.txt /user/hive/warehouse/db.db/db1
分区表
分区表字段 不能在表中已经存在
分区字段的数据来自于装在分区表数据的时候指定的
分区表的字符 在hdfs上的效果就是 建立表的文件夹下面 又创建了子文件夹
这样把数据划分更细致 提高效率
单分区建表语句:
create table db3 (id int, name string) partitioned by (country string) row format delimited fields terminated by ',';
单分区导入数据语句:
create table db3 (id int, name string) partitioned by (country string) row format delimited fields terminated by ',';
分桶表:
创建之前 首先开启分桶功能
#指定开启分桶
set hive.enforce.bucketing = true;
set mapreduce.job.reduces=4;
TRUNCATE TABLE stu_buck;
删除表:
drop table stu_buck;
创建表:
create table stu_buck(Sno int,Sname string,Sex string,Sage int,Sdept string)
clustered by(Sno)
sorted by(Sno DESC)
into 4 buckets
row format delimited
fields terminated by ',';
创建一个临时表: 将临时表中的数据导入到分桶表中
分桶表导入数据
insert overwrite table stu_buck
select * from student cluster by(Sno);
分桶表的数据 采用 insert+select 插入的数据来自于查询结果(查询的时候执行了mr程序)
对应mr当中的partitioner
分桶表(分簇表)创建的时候 分桶表字段 必须是表中已经存在的字段
也就是说 要按照表中的某个字段进行分桶
建立外部表:
create external table student_ext(Sno int,Sname string,Sex string,Sage int,Sdept string) row format delimited fields terminated by ',' location '/stu';
(location'/****'要有相对应的格式化文件)
修改表
增加分区:
ALTER TABLE table_name ADD PARTITION (dt='20170101') location '/user/hadoop/warehouse/table_name/dt=20170101'; //一次添加一个分区
ALTER TABLE table_name ADD PARTITION (dt='2008-08-08', country='us') location
'/path/to/us/part080808' PARTITION (dt='2008-08-09', country='us') location '/path/to/us/part080809'; //一次添加多个分区
删除分区:
ALTER TABLE table_name DROP IF EXISTS PARTITION (dt='2008-08-08');
ALTER TABLE table_name DROP IF EXISTS PARTITION (dt='2008-08-08', country='us');
修改分区
ALTER TABLE table_name PARTITION (dt='2008-08-08') RENAME TO PARTITION (dt='20080808');
添加列
ALTER TABLE table_name ADD|REPLACE COLUMNS (col_name STRING); 注: ADD 是代表新增一 个 字段, 新增 字段位置在所有列后面 (partition列前 )
REPLACE则是表示 替换表中所有字段 。
修改列
test_change (a int, b int, c int);
ALTER TABLE test_change CHANGE a a1 INT; //修改 a 字段名// will change column a's name to a1, a's data type to string, and put it after column b. The new table's structure is: b int, a1 string, c int
ALTER TABLE test_change CHANGE a a1 STRING AFTER b;
// will change column b's name to b1, and put it as the first column. The new table's structure is: b1 int, a ints, c int ALTER TABLE test_change CHANGE b b1 INT FIRST;
表重命名
ALTER TABLE table_name RENAME TO new_table_name
show tables; //显示当前数据库所有表
show databases |schemas; //显示所有数据库
show partitions table_name; //显示表分区信息,不是分区表执行报错
show functions; //显示当前版本 hive 支持的所有方法
desc extended table_name; //查看表信息
desc formatted table_name; //查看表信息(格式化美观)
describe database database_name; //查看数据库相关信息