一、Hive的介绍及其设计原理
1、Hive的设计目标及诞生
- 设计目标:使用SQL来操作Hadoop
- FaceBook:问题,Hadoop需要给公司的数据分析师来使用
- 数据分析师不会Java
- Java工程不会数据分析
- 让Java工程师基于Hadoop的接口做二次开发,让这个产品使用SQL来操作,底层全部由Hadoop来实现
- 工具:将SQL变成Hadoop的程序
- Hive:一个基于Hadoop之上的中间件
- 存储:HDFS
- insert:写入数据,最终存储在hdfs上
- 计算:YARN
- select:查询计算数据,将SQL转换成MapReduce程序,提交给YARN运行
- Hive的底层支持三种计算:mr【默认】、spark、tez
- Presto:与Impala非常类似的 一个工具,基于内存式计算
- 京东
2、Hive的功能
- 提供SQL接口来操作Hadoop
- 存储:将HDFS上的文件映射成表【目前主要用的功能:数据仓库的构建】
- Hadoop中数据的存储是基于HDFS上的文件
- Hive:SQL操作的数据对象是表
- 计算:将SQL语句转换成MapReduce代码【很少见:MapReduce性能太差了,Presto、Impala、SparkSQL、Flink】
- Hadoop中所有的程序都是通过Java代码开发MapReduce运行的
- Hive:计算用SQL语句
3、Hive的设计原理
- 存储:将HDFS文件映射成表的数据
- metadata:记录所有表与文件的映射关系
- 计算:将SQL变成了MapReduce的程序
- 转换的过程
tbname:emp员工表
empno empname salary detpno
select empno,salary from emp where salary > 200
select deptno,max(salary) from emp group by deptno order by
||
Input:
1-要从Hive的元数据中获取emp这张表所对应的HDFS文件地址
2-读取这个地址对应的所有文件
Map:
1-实现过滤【判断字段个数是否合法行的过滤、列的过滤】
salary > 200
2-分割每一条数据,返回对应的两列,获取元数据中该表的字段个数及分隔符【empno-0,salary-2】
empno,salary
3-输出这两列
Shuffle:
key:deptno
value:salary
分组:deptno
相同部门的所有薪资在一个迭代器中
Reduce:聚合函数
reduce(deptno,values{所有薪资}){
context.write(deptno,max(values))
}
Ouptut:
* 元数据
* 记录着表与文件的映射关系
* 表的信息:有哪些字段、分隔符【本质上还是文件】
* 计算:底层是一个MapReduce模板,将SQL解析以后得到每个参数,通过参数传递给MapReduce程序
4、Hive的架构
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vvGl0xW6-1619417522995)(Day43_20200116_大数据仓库Hive入门.assets/image-20200116114756594.png)]
- 客户端:负责与用户交互,让用户开发SQL,并返回结果显示给用户
- 服务端:负责翻译解析的过程
- 连接器:负责与客户端连接的管理
- 解析器:负责解析整个SQL语句
- 逻辑计划:将SQL语句中的参数进行解析,赋值给底层的MapReduce模板
- 优化器:根据MapReduce的使用,来自动选择最优的方式来实现
- 物理计划:完整的一个MapReduce的程序
- 提交运行:将程序提交给Yarn运行
- 元数据
- 负责存储表与文件的映射关系
- 负责存储所有表的信息:数据库、字段、分隔符
- Hadoop
- HDFS:负责实现真正的存储
- YARN:负责实现真正的计算
- Hive的本质:提供SQL接口的Hadoop的客户端
- 不是分布式的,只是一个介于用户于Hadoop之间的一个工具
- 它的读写分布式由Hadoop实现
## 二、Hive的部署及测试
1、Hive官网
- 地址:hive.apache.org
- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-t0z0T9vH-1619417522999)(Day43_20200116_大数据仓库Hive入门.assets/image-20200116115527133.png)]
2、安装
- 下载解压:由于选择了CDH,只要找到CDH版本对应的Hive版本即可,不用考虑兼容性
- 在第三台安装
cd /export/software/
tar -zxvf hive-1.1.0-cdh5.14.0.tar.gz -C /export/servers/
- 修改配置
/export/servers/hive-1.1.0-cdh5.14.0/conf
- 配置Hive的系统环境变量
#HIVE_HOME
export HIVE_HOME=/export/servers/hive-1.1.0-cdh5.14.0
export PATH=:HIVE_HOME/bin
- 修改环境变量:hive-env.sh
#修改文件名
mv hive-env.sh.template hive-env.sh
#编辑文件
vim hive-env.sh
#修改如下内容
48行:HADOOP_HOME=/export/servers/hadoop-2.6.0-cdh5.14.0
51行:export HIVE_CONF_DIR=/export/servers/hive-1.1.0-cdh5.14.0/conf
- 启动测试
- 先启动hdfs
start-dfs.sh - 启动yarn
start-yarn.s.h - 启动hive
/export/servers/hive-1.1.0-cdh5.14.0
bin/hive
- 注意:Hive或者SparkSQL
- 如果报错,不仅仅看抛Exception的地方,重点看causedBy的地方
- 官方安装文档中注意事项
- https://cwiki.apache.org/confluence/display/Hive/GettingStarted#GettingStarted-RunningHiveCLI
- 启动hive之前提前创建对应的目录,以及赋予权限
$ $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 - 2.1版本开始,要先执行初始化元数据的命令
3、测试
- 将wordcount文件在hdfs中拷贝一份
hdfs dfs -cp /wordcount/input/wordcount.txt /user/root/ - 在hive中创建表
create table wordcount(word string); - 加载数据到Hive中:实现 了hdfs文件与表的关联
load data inpath ‘/user/root/wordcount.txt’ into table wordcount; - 查询测试
select * from wordcount; - 实现词频统计:将每行变成只有一个单词
select explode(split(word," ")) from wordcount;
三、Hive的元数据管理及客户端
1、元数据的功能
- 记录所有表与HDFS上文件的映射关系
- 记录所有表、数据库、字段、表中数据的分割符等信息
2、元数据的管理
- 存储位置
- 默认的存储位置:Hive自带的文本型数据库:derby
- 问题
- 文本数据库数据易丢失
- 文本数据库不能同时启动多个实例
- 生产环境中:配置元数据存储在MySQL中【利用远程Mysql来实现存储】
- 修改Hive配置文件:hive-site.xml
- 将hive-site.xml文件放入hive的配置文件目录 下
- 修改,添加如下配置选项
•
javax.jdo.option.ConnectionURL
jdbc:mysql://node-03:3306/hiveMetadata?createDatabaseIfNotExist=true
javax.jdo.option.ConnectionDriverName
com.mysql.jdbc.Driver
javax.jdo.option.ConnectionUserName
root
javax.jdo.option.ConnectionPassword
123456
- 在第三台机器安装MySQL:参考《附录一:Linux中安装MySQL》
- 添加MySQL的连接驱动包到Hive的lib目录下
cp /export/software/mysql-connector-java-5.1.38.jar lib/ - 直接启动Hive,看MySQL中是否有元数据信息
- Hive与HDFS之间的 存储关系
- Hive数仓在HDFS上的位置:hive.metastore.warehouse.dir=/user/hive/warehouse
- Hive中创建的所有数据库都会在该目录下创建对应一个目录,自动以dbname.db命名
- 这个目录也作为default数据库的目录
- Hive中的所有数据库,都会对应一个hdfs的目录
- Hive中所有的表,都会默认对应一个hdfs的目录,目录在数据库目录的下面
- Hive表中的数据,默认在表的目录下面
- 查看元数据
- DBS:记录了Hive中所有数据库的信息
- TBLS:记录了Hive中所有表的信息
- SDS:记录了所有表与HDFS 的映射关系
3、MetaStore元数据管理服务
- 为什么需要该服务:以后很多SQL的分布式计算工具需要访问元数据,统一化的访问管理
- 配置MetaStore元数据管理服务
- 修改hive-site.xml
hive.metastore.uris
thrift://node-03:9083
hive.cli.print.current.db
true
hive.cli.print.header
true
- 注意启动顺序发生改变
- 如果一旦配置了MetaStore服务,整个Hive一定要先启动MetaStore
bin/hive --service metastore
#检测是否真正启动成功
netstat -atunlp | grep 9083
- 第二个启动Hive服务端
- hiveserver2:这是Hive的服务端
- 启动
bin/hiveserver2
#检测是否真正启动成功
netstat -atunlp | grep 10000
- 第三个启动Hive客户端
启动beeline即可
4、客户端
- Hive shell:一般不用,因为交互性不是很好
- bin/hive
- Beeline:统一的jdbc客户端
- 第一种用法
- 进入beeline
bin/beeline - 连接服务端
beeline> !connect jdbc:hive2://node-03:10000
输入用户名:root
输入密码: ******
- 第二种用法:
- 一次性进入
bin/beeline -u jdbc:hive2://node-03:10000 -n root -p 123456
- 退出beeline
!quit
- JDBC:几乎与MySQL的JDBC一致
四、Hive的DDL与DML
1、官网语法手册
2、DDL
- 数据库管理: https://cwiki.apache.org/confluence/display/Hive/LanguageManual+DDL#LanguageManualDDL-Create/Drop/Alter/UseDatabase
- 查看:show databases;
- 创建
官方:
CREATE (DATABASE|SCHEMA) [IF NOT EXISTS] database_name
[COMMENT database_comment]
[LOCATION hdfs_path]
[WITH DBPROPERTIES (property_name=property_value, …)];
实际:
CREATE DATABASE [IF NOT EXISTS] DB_NAME [LOCATION hdfs_path]
LOCATION:所有Hive中的数据库默认会有一个hdfs对应的目录,如果不存在会自动/user/hive/warehouse目录下创建,该选项可以自定义,手动指定某个hdfs目录作为数据库目录
create database if not exists testdb location '/testdb';
- 删除
DROP DATABASE [IF EXISTS] database_name [CASCADE];
drop database if exists testdb; //只能删除空数据库
drop database if exists testdb cascade; //慎用
- 切换
use db_name; - 描述
desc database wordcount;
- 数据表管理
- 列举:show tables;
- 描述:desc tbname;
desc words;
desc formatted words; - 删除
DROP TABLE [IF EXISTS] table_name ; - 创建
- 第一种方式:普通方式【常用】
官方语法
CREATE [TEMPORARY] [EXTERNAL] TABLE [IF NOT EXISTS] [db_name.]table_name -- (Note: TEMPORARY available in Hive 0.14.0 and later)
[(col_name data_type [column_constraint_specification] [COMMENT col_comment], ... [constraint_specification])]
[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]
[SKEWED BY (col_name, col_name, ...) -- (Note: Available in Hive 0.10.0 and later)]
ON ((col_value, col_value, ...), (col_value, col_value, ...), ...)
[STORED AS DIRECTORIES]
[
[ROW FORMAT row_format]
[STORED AS file_format]
| STORED BY 'storage.handler.class.name' [WITH SERDEPROPERTIES (...)] -- (Note: Available in Hive 0.6.0 and later)
]
[LOCATION hdfs_path]
[TBLPROPERTIES (property_name=property_value, ...)] -- (Note: Available in Hive 0.6.0 and later)
[AS select_statement]; -- (Note: Available in Hive 0.5.0 and later; not supported for external tables)
CREATE [TEMPORARY] [EXTERNAL] TABLE [IF NOT EXISTS] [db_name.]table_name
LIKE existing_table_or_view_name
[LOCATION hdfs_path];
* ```sql
create [EXTERNAL] table [if not exists] tbname(
col1 type1,
col2 type2,
……
)
[PARTITIONED BY col] --按照哪个字段进行分区
[CLUSTERED BY col into N buckets] --按照哪个字段进行分桶
[ROW FORMAT ] --指定行和列的分隔符
lines terminated by '\n' --指定行的分隔符,默认为\n
row format delimited fields terminated by '\001' --指定列的 分隔符,默认为\001
[STORED AS file_format] --指定表中数据文件的类型,默认为textfile,可选:orc/parquet等
[LOCATION hdfs_path] --手动指定表所在的hdfs的目录
注意:Hive中的SQL语句不能包含制表符
```
* 测试:
* 创建数据库
```
create database if not exists db_emp;
use db_emp;
```
* 创建表
* 员工表:tb_emp
```SQL
create table tb_emp(
empno string,
ename string,
job string,
managerno string,
hiredate string,
salary double,
jiangjin double,
deptno string
)
row format delimited fields terminated by '\t';
```
* 部门表:tb_dept
```SQL
create table tb_dept(
deptno string,
dname string,
location string
)
row format delimited fields terminated by ',';
```
* 加载数据
* 员工表:
```SQL
load data local inpath '/export/datas/emp.txt' into table tb_emp;
local:表示加载本地数据,原理实际上是将本地文件上传到了表的目录下
不加local:表示加载hdfs数据,原理实际上将hdfs上的文件移动到表的目录下
```
* 部门表
```SQL
load data local inpath '/export/datas/dept.txt' into table tb_dept;
```
- 第二种方式【常用】:子查询的方式
- 功能:将SQL语句的结果进行保存
- 语法:将select语句的结果保存未一张表
create table if not exists tb_name as select ……
- 测试
create table tb_emp_as as select empno,ename,salary,deptno from tb_emp;
- 查看表的结构
select * from tb_emp_as;
- 第三种方式【很少用】
- 功能:复制一个已存在的表的表结构,不复制数据,构建一张新的表
- 语法
create table tb_emp_like like exists_tb_name;
- 测试
select * from tb_emp_like;