一、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
- 存储:HDFS
- 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 detpnoselect 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=: P A T H : PATH: 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
- 配置Hive的系统环境变量
-
启动测试
- 先启动hdfs
start-dfs.sh - 启动yarn
start-yarn.s.h - 启动hive
/export/servers/hive-1.1.0-cdh5.14.0
bin/hive
- 先启动hdfs
-
注意: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配置文件:hive-site.xml
- 默认的存储位置:Hive自带的文本型数据库:derby
- Hive与HDFS之间的 存储关系
- Hive数仓在HDFS上的位置:hive.metastore.warehouse.dir=/user/hive/warehouse
- Hive中创建的所有数据库都会在该目录下创建对应一个目录,自动以dbname.db命名
- 这个目录也作为default数据库的目录
- Hive中的所有数据库,都会对应一个hdfs的目录
- Hive中所有的表,都会默认对应一个hdfs的目录,目录在数据库目录的下面
- Hive表中的数据,默认在表的目录下面
- Hive数仓在HDFS上的位置:hive.metastore.warehouse.dir=/user/hive/warehouse
- 查看元数据
- 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
- 修改hive-site.xml
-
注意启动顺序发生改变
-
如果一旦配置了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
输入密码: ******
- 进入beeline
- 第二种用法:
- 一次性进入
bin/beeline -u jdbc:hive2://node-03:10000 -n root -p 123456
- 一次性进入
- 退出beeline
!quit
- 第一种用法
- JDBC:几乎与MySQL的JDBC一致
四、Hive的DDL与DML
1、官网语法手册
- https://cwiki.apache.org/confluence/display/Hive/Home#Home-UserDocumentation
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;
-
-
-
- 第一种方式:普通方式【常用】