一、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 in 原理 简述hive ha原理_大数据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的地方
  • 官方安装文档中注意事项

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;