Hive介绍
什么是数据仓库?
数据仓库之父比尔•恩门(Bill Inmon)在1991年出版的"Building the Data Warehouse"(《建立数据仓库》)一书中所提出的定义被广泛接受。
数据仓库(Data Warehouse)是一个面向主题的(Subject Oriented)、集成的(Integrated)、相对稳定的(Non-Volatile)、反映历史变化(Time Variant)的数据集合,用于支持管理决策(Decision Making Support)。
管理多个不同主题的数据(一个主题就可以理解成是一个mysql表中的一张表) 仓库:存储数据,不在乎数据是什么格式(为了能写SQL执行计算,最好都是普通的文本文件) 相对稳定:一般来说,往数据仓库hive中存储的数据,都是不会再去做修改的数据 支持管理决策:查询分析得到的结果具有很大的价值
数据仓库有两种类型:离线数仓(hive) 实时数仓
什么是Hive
The Apache Hive ™ data warehouse software facilitates reading, writing, and managing large datasets residing in distributed storage using SQL. Structure can be projected onto data already in storage. A command line tool and JDBC driver are provided to connect users to Hive.
Hive是什么:Apache Hive™数据仓库软件支持使用SQL读取、写入和管理分布存储中的大型数据集。 Hive怎么做的:结构可以映射到存储中的数据。 Hive怎么用:提供了一个命令行工具和JDBC驱动程序来将用户连接到Hive。
Hive官网:http://hive.apache.org/
Hive的概念
为了帮助清楚的知晓什么是Hive,我们总结了7句话,你理解这7句话,就能知道hive到底是什么玩意,是怎么工作的了。最最重要的7句话
1、Hive由Facebook实现并开源
2、Hive是基于Hadoop的一个数据仓库工具
3、Hive存储的数据其实底层存储在HDFS上
4、Hive将HDFS上的结构化的数据映射为一张数据库表,类似于Excel和mysql的表。
5、Hive提供HQL(Hive SQL)查询功能
6、Hive的本质是将SQL语句转换为MapReduce任务运行,使不熟悉MapReduce的用户很方便地利用HQL处理和计算HDFS上的结构化的数据,适用于离线的批量数据计算
7、Hive使用户可以极大简化分布式计算程序的编写,而将精力集中于业务逻辑
Hive依赖于HDFS存储数据,Hive将HQL转换成MapReduce执行,所以说Hive是基于Hadoop的一个数据仓库工具,实质就是一款基于HDFS的MapReduce计算框架,对存储在HDFS中的数据进行分析和管理。
为什么使用Hive
不用Hive而直接使用MapReduce的弊端:
人员学习成本太高
MapReduce开发效率低,项目周期要求太短不适用
MapReduce实现复杂查询逻辑开发难度太大
为什么要学习使用Hive:
更友好的接口:操作接口采用类SQL的语法,提供快速开发的能力
更低的学习成本:避免了写MapReduce,减少开发人员的学习成本
更好的扩展性:可自由扩展集群规模而无需重启服务,还支持用户自定义函数
Hive特点
优点:
1、可扩展性,横向扩展,Hive可以自由的扩展集群的规模,一般情况下不需要重启服务 横向扩展:通过分担压力的方式扩展集群的规模 纵向扩展: 一台服务器cpu i7-6700k 4核心8线程,8核心16线程,内存64G => 128G 2、延展性,Hive支持自定义函数,用户可以根据自己的需求来实现自己的函数 3、良好的容错性,可以保障即使有节点出现问题,SQL语句仍可完成执行
缺点:
1、Hive不支持记录级别的增删改操作,但是用户可以通过查询生成新表或者将查询结果导入到文件中。新版本支持insert语法。 2、Hive的查询延时很严重,因为MapReduce Job的启动过程消耗很长时间,所以不能用在交互查询系统中。 3、Hive不支持事务(因为没有增删改,所以主要用来做OLAP(联机分析处理),而不是OLTP(联机事务处理),这就是数据处理的两大级别)。
思考一个问题:Hive不支持删除和修改操作,请问为什么?是语法没法实现,还是没有必要?不支持delete和update
Hive和RDBMS区别
对比项 | Hive | RDBMS |
---|---|---|
查询语言 | HQL | SQL |
数据存储 | HDFS | Raw Device or Local FS |
执行器 | MapReduce | Executor |
数据插入 | 支持批量导入/单条插入 | 支持单条或者批量导入 |
数据操作 | 覆盖追加 | 行级更新删除 |
处理数据规模 | 大 | 小 |
执行延迟 | 高 | 低 |
分区 | 支持 | 支持 |
索引 | 0.8版本之后加入简单索引 | 支持复杂的索引 |
扩展性 | 高(好) | 有限(差) |
数据加载模式 | 读时模式(快) | 写时模式(慢) |
应用场景 | 海量数据查询 | 实时查询 |
总结:Hive具有SQL数据库的外表,但应用场景完全不同,Hive只适合用来做海量离线数据统计分析,也就是数据仓库。
Hive和HBase的区别
Hive | HBase |
---|---|
Hive是建立在Hadoop之上为了降低MapReduce编程复杂度的ETL工具 | HBase是为了弥补Hadoop对实时操作的缺陷 |
Hive表是纯逻辑表,因为Hive的本身并不能做数据存储和计算,而是完全依赖Hadoop | HBase是物理表,提供了一张超大的内存Hash表来存储索引,方便查询 |
Hive是数据仓库工具,需要全表扫描,就用Hive,因为Hive是文件存储 | HBase是数据库,需要索引访问,则用HBase,因为HBase是面向列的NoSQL数据库 |
Hive表中存入数据(文件)时不做校验,属于读模式存储系统 | HBase表插入数据时,会和RDBMS一样做Schema校验,所以属于写模式存储系统 |
Hive不支持单行记录操作,数据处理依靠MapReduce,操作延时高 | HBase支持单行记录的CRUD,并且是实时处理,效率比Hive高得多 |
Hive架构
基本组成
1、用户接口
2、ThriftServer
3、元数据存储
4、核心四大组件
用户接口
CLI,Shell终端命令行(Command Line Interface),采用交互形式使用Hive命令行与Hive进行交互,最常用(学习,调试,生产) JDBC/ODBC,是Hive的基于JDBC操作提供的客户端,用户(开发员,运维人员)通过这连接至Hive server服务 Web UI,通过浏览器访问Hive,基本是鸡肋,有其他替代品
Thrift Server(跨语言服务)
Thrift是Facebook开发的一个软件框架,可以用来进行可扩展且跨语言的服务的开发,Hive集成了该服务,能让不同的编程语言调用Hive的接口
元数据存储
元数据,通俗的讲,就是存储在Hive中的数据的描述信息。 Hive中的元数据通常包括:表的名字,表的列的定义和分区定义及其属性,表的属性(内部表和外部表),表的数据所在目录,行列分隔符等 Metastore默认存在自带的Derby数据库中。缺点就是不适合多用户操作,并且数据存储目录不固定。数据库跟着Hive走,极度不方便管理。解决方案:通常存我们自己创建的MySQL库(本地 或 远程)。 Hive和MySQL之间通过MetaStore服务交互
核心四大组件
Hive内部四大组件:Driver驱动器:编译器Compiler,优化器Optimizer,执行器Executor
Driver组件完成HQL查询语句从词法分析,语法分析,编译,优化,以及生成逻辑执行计划的生成。生成的逻辑执行计划存储在HDFS中,并随后由MapReduce调用执行。
Hive 的核心是驱动引擎, 驱动引擎由四部分组成: (1) 解释器:解释器的作用是将HiveSQL语句转换为抽象语法树(AST) (2) 编译器:编译器是将语法树编译为逻辑执行计划 (3) 优化器:优化器是对逻辑执行计划进行优化 (4) 执行器:执行器是调用底层的运行框架执行逻辑执行计划
工作原理
HiveQL通过命令行或者客户端提交,经过Compiler编译器,运用MetaStore中的元数据进行类型检测和语法分析,生成一个逻辑方案(Logical Plan),然后通过优化处理,产生一个MapReduce任务。
Hive的数据存储
Hive的存储结构包括数据库、表、视图、分区和表数据等。数据库,表,分区等等都对应HDFS上的一个目录。表数据对应HDFS对应目录下的文件。
数据格式
Hive中所有的数据都存储在HDFS中,没有专门的数据存储格式,因为Hive是读模式(Schema On Read),可支持TextFile,SequenceFile,RCFile,ParquetFile或者自定义格式等
分隔符
要在创建表的时候告诉Hive数据中的列分隔符和行分隔符,Hive就可以解析数据。 Hive的默认列分隔符:控制符 Ctrl + A,\x01 Hive的默认行分隔符:换行符 \n
一般情况 在创建表时候制定分隔符
Hive中数据模型
database:在HDFS中表现为${hive.metastore.warehouse.dir}目录下一个文件夹
table:在HDFS中表现所属database目录下一个文件夹
external table:与table类似,不过其数据存放位置可以指定任意HDFS目录路径
partition:在HDFS中表现为table目录下的子目录
bucket:在HDFS中表现为同一个表目录或者分区目录下根据某个字段的值进行hash散列之后的多个文件
view:与传统数据库类似,只读,基于基本表创建
Hive的元数据存储在RDBMS中,除元数据外的其它所有数据都基于HDFS存储。默认情况下,Hive元数据保存在内嵌的Derby 数据库中,只能允许一个会话连接,只适合简单的测试。实际生产环境中不适用,为了支持多用户会话,则需要一个独立的元数据库,使用 MySQL作为元数据库,Hive内部对MySQL提供了很好的支持。
Hive表的类型
Hive中的表分为 managed内部表、external外部表、partition分区表 和 bucket分桶表
内部表和外部表的区别:
删除内部表,删除表元数据和数据 删除外部表,删除元数据,不删除数据
内部表和外部表的使用选择:
大多数情况,他们的区别不明显,如果数据的所有处理都在Hive中进行,那么倾向于选择内部表,但是如果Hive和其他工具要针对相同的数据集进行处理,外部表更合适。
使用外部表访问存储在HDFS上的初始数据,然后通过Hive转换数据并存到内部表中,使用外部表的场景是针对一个数据集有多个不同的Schema
通过外部表和内部表的区别和使用选择的对比可以看出来,hive其实仅仅只是对存储在HDFS上的数据提供了一种新的抽象。而不是管理存储在HDFS上的数据。所以不管创建内部表还是外部表,都可以对hive表的数据存储目录中的数据进行增删操作。
分区表和分桶表的区别:
Hive数据表可以根据某些字段进行分区操作,细化数据管理,可以让部分查询更快。同时表和分区也可以进一步被划分为Buckets,分桶表的原理和MapReduce编程中的HashPartitioner的原理类似
分区和分桶都是细化数据管理,但是分区表是手动添加区分,由于Hive是读模式,所以对添加进分区的数据不做模式校验,分桶表中的数据是按照某些分桶字段进行hash散列形成的多个文件,所以数据的准确性也高很多
Hive环境搭建
版本选择
当前hive的主流版本有两个
hive-1.x,其中使用比较多的是hive-1.2.x的版本,最后一个稳定版本是hive-1.2.2,如果使用这个版本,你的hive将来没法集成spark。
hive-2.x,现行主流的hive使用版本,现行稳定的hive-2.x版本中的,我们选择使用hive-2.3.6
自带Derby版本
1、上传安装包
put -r apache-hive-2.3.6-bin.tar.gz
2、解压安装包
[bigdata@bigdata05 ~]$ tar -zxvf ~/soft/apache-hive-2.3.6-bin.tar.gz -C ~/apps/
3、进入到bin目录,运行hive脚本
[bigdata@bigdata05 ~] ./hive
4、就可以直接使用了。
show databases;
create database testdb;
use testdb;
create table student(id int, name string);
insert into table student values ('1','huangbo'), ('2','xuzheng'), ('3','wangbaoqiang');
select * from student;
外置MySQL版本
第一步:准备好MySQL
请参考官网安装,或者自行安装MySQL,或者一个可用的MySQL。不管你的MySQL在哪里,只要Hive能连接上即可。如果Hive和MySQL没有安装在同一个服务器节点中,通常企业环境也都不是安装在同一个节点,一定要记得给Hive开启MySQL的远程链接权限。
要点:
1、有一个能用的MySQL就行
2、给这个MySQL配置远程连接权限
第二步:上传安装包
将apache-hive-2.3.6-bin.tar.gz
到安装Hive的服务器节点中。
使用你知道的方式上传这个安装包到你的服务器上。或者使用wget命令直接现在去下载也可。
第三步:解压安装包到对应的Hive安装目录中
[bigdata@bigdata05 ~]$ tar -zxvf ~/soft/apache-hive-2.3.6-bin.tar.gz -C ~/apps/
第四步:修改配置文件
[bigdata@bigdata05 ~] touch hive-site.xml
注意:该文件默认是没有的。一般自己创建。当然也可以从hive-default.xml更改而来,不推荐。
[bigdata@bigdata05 ~]$ vi hive-site.xml
在这个新创建的配置文件中加入如下截图中的内容即可:
<configuration>
<property>
<name>javax.jdo.option.ConnectionURL</name>
<value>jdbc:mysql://bigdata02:3306/hivemetadb?createDatabaseIfNotExist=true&verifyServerCertificate=false&useSSL=false</value>
<description>JDBC connect string for a JDBC metastore</description>
</property>
<property>
<name>javax.jdo.option.ConnectionDriverName</name>
<value>com.mysql.jdbc.Driver</value>
<!-- SQL的驱动类名称,不用更改 -->
<description>Driver class name for a JDBC metastore</description>
</property>
<property>
<name>javax.jdo.option.ConnectionUserName</name>
<value>root</value>
<!-- 连接MySQL的用户账户名 -->
<description>username to use against metastore database</description>
</property>
<property>
<name>javax.jdo.option.ConnectionPassword</name>
<value>QWer_1234</value>
<!-- 连接MySQL的用户的登录密码 -->
<description>password to use against metastore database</description>
</property>
<property>
<name>hive.metastore.warehouse.dir</name>
<value>/user/hive/warehouse</value>
<description>hive default warehouse, if nessecory, change it</description>
<!-- 可选配置,该配置信息用来指定Hive数据仓库的数据存储在HDFS上的目录 -->
</property>
</configuration>
第五步:加入MySQL驱动
一定要记得加入MySQL驱动包 mysql-connector-java-5.1.40-bin.jar
该jar包放置在hive的安装根路径下的lib目录中,毕竟hive要读写MySQL。
[bigdata@bigdata05 ~]$ cp ~/soft/mysql-connector-java-5.1.40-bin.jar ~/apps/apache-hive-2.3.6-bin/lib
第六步:复制Hadoop集群的配置文件
一定要记得把Hadoop集群中的core-site.xml和hdfs-site.xml两个配置文件都放置在Hive安装目录下conf目录中。
[bigdata@bigdata05 ~]HADOOP_HOME/etc/hadoop/core-site.xml ~/apps/apache-hive-2.3.6-bin/conf
[bigdata@bigdata05 ~]HADOOP_HOME/etc/hadoop/hdfs-site.xml ~/apps/apache-hive-2.3.6-bin/conf
第七步: 安装完成,配置环境变量
vi ~/.bashrc
添加以下两行内容:
export HIVE_HOME=/home/bigdata/apps/apache-hive-2.3.6-bin
export PATH=HIVE_HOME/bin
最后不要忘记让环境变量配置生效:
[bigdata@bigdata05 ~]$ source ~/.bashrc
第八步:验证Hive安装
[bigdata@bigdata05 ~]$ hive --help
第九步:初始化元数据库 注意:当使用的hive是1.x之前的版本,不做初始化也是OK的,当Hive第一次启动的时候会自动进行初始化,只不过会不会生成足够多的元数据库中的表。在使用过程中会慢慢生成。但最后进行初始化。如果使用的2.x版本的Hive,那么就必须手动初始化元数据库。使用命令:
[bigdata@bigdata05 ~]$ schematool -dbType mysql -initSchema
切记:初始化操作只需要做一次。如果你使用了一段时间,再次执行了这个命令,那么你就又得到了一个全新的Hive。
第十步:启动Hive 客户端
[bigdata@bigdata05 ~] hive --service cli
第十一步:退出Hive
hive> quit;
hive> exit;
Hive使用方式
第一种:CLI
执行hive命令之后进入hive交互式命令行界面:
进入到 bin 目录下,直接输入命令:启动成功的话如上图所示,接下来便可以做 hive 相关操作
[bigdata@bigdata05 ~]$ hive
补充: 1、上面的hive命令相当于在启动的时候执行:hive --service cli
2、使用 hive --help
,可以查看hive命令可以启动那些服务 3、通过 hive --service serviceName --help
可以查看某个具体命令的使用方式,具体看命令提示。
使用hive命令来提交和执行HQL语句:
hive -e "select * from mydb.student"
这种方式,一般用来执行某个单个 SQL 或者单个任务,这样就不用进入 Hive 交互式命令行中进行执行。省事。通常企业提交hive任务的方式也会使用这种。具体的使用方式后续再详细介绍。
第二种:HiveServer2/beeline
在现在使用的最新的 hive-2.3.6 版本中:都需要对 hadoop 集群做如下改变,否则无法使用
[图片上传失败...(image-ee25d7-1593531967295)]
各位看官仔细瞧一瞧可以发现,上述日志中有一个Error对吧,这个Error提示的是授权的问题。也就是说HDFS不让Hive去访问。
解决方法如下:
第一:修改hadoop集群的hdfs-site.xml配置文件:加入一条配置信息,表示启用webhdfs
<property>
<name>dfs.webhdfs.enabled</name>
<value>true</value>
</property>
第二:修改hadoop集群的core-site.xml配置文件:加入两条配置信息:表示设置hadoop集群的代理用户
<property>
<name>hadoop.proxyuser.bigdata.hosts</name>
<value></value>
</property>
<property>
<name>hadoop.proxyuser.bigdata.groups</name>
<value></value>
</property>
配置解析:
hadoop.proxyuser.bigdata.hosts
配置成*的意义,表示任意节点使用hadoop集群的代理用户bigdata都能访问hdfs集群
hadoop.proxyuser.bigdata.groups
表示代理用户的组所属
以上操作做好了之后,请继续做如下两步:
第一步:先启动hiveserver2服务
启动为前台,直接执行hiveserver2命令即可:
[bigdata@bigdata05 ~]$ hiveserver2
启动为后台:
[bigdata@bigdata05 ~]$ nohup hiveserver2 1>/home/bigdata/logs/hiveserver.log 2>/home/bigdata/logs/hiveserver.err &
或者:
[bigdata@bigdata05 ~] nohup hiveserver2 >/dev/null 2>&1 &
以上3个启动命令是等价的,第一个语句表示记录日志,后面连个语句表示不记录日志。
命令解释:
nohup命令:如果你正在运行一个进程,而且你觉得在退出帐户时该进程还不会结束,那么可以使用nohup命令。该命令可以在你退出帐户/关闭终端之后继续运行相应的进程。nohup就是不挂起的意思(no hang up)。该命令的一般形式为:nohup command &
1:表示标准日志输出,2:表示错误日志输出
如果我没有配置日志的输出路径,日志会生成在当前工作目录,默认的日志名称叫做:nohup.xxx
第二步:然后启动beeline客户端去连接
执行命令:
[bigdata@bigdata05 ~]$ beeline -u jdbc:hive2://bigdata05:10000 -n bigdata
参数解释:
-u : 指定元数据库的链接信息
-n : 指定用户名和密码
另外还有一种方式也可以去连接:
1、先执行 beeline
2、然后按图所示输入:!connect jdbc:hive2://bigdata05:10000
按回车,然后输入用户名,这个用户名就是安装bigdata集群的用户名
第三种:Web UI
记住:这只是告诉大家,可以使用这种方式来搭建Hive web UI,但是基本上没人在生产环境中使用。所以你知道Hive他有这个组件就可以了。
1、下载对应版本的src包:
apache-hive-2.3.6-src.tar.gz
2、上传,解压
tar -zxvf apache-hive-2.3.6-src.tar.gz
3、然后进入目录${HIVE_SRC_HOME}/hwi/web,执行打包命令:
jar -cvf hive-hwi-2.3.6.war *
在当前目录会生成一个hive-hwi-2.3.6.war
4、得到hive-hwi-2.3.6.war文件,复制到hive下的lib目录中
cp hive-hwi-2.3.6.war ${HIVE_HOME}/lib/
5、修改配置文件hive-site.xml
<property>
<name>hive.hwi.listen.host</name>
<value>0.0.0.0</value>
<description>监听的地址</description>
</property>
<property>
<name>hive.hwi.listen.port</name>
<value>9999</value>
<description>监听的端口号</description>
</property>
<property>
<name>hive.hwi.war.file</name>
<value>lib/hive-hwi-2.3.6.war</value>
<description>war包所在的地址</description>
</property>
6、 复制所需jar包
cp {HIVE_HOME}/lib
再寻找三个jar包,都放入${HIVE_HOME}/lib目录:
commons-el-1.0.jar
jasper-compiler-5.5.23.jar
jasper-runtime-5.5.23.jar
7、安装ant
上传安装并解压缩安装:
tar -zxvf apache-ant-1.9.4-bin.tar.gz -C ~/apps/
配置环境变量:
tar -zxvf apache-ant-1.9.4-bin.tar.gz -C ~/apps/
追加如下内容:
export ANT_HOME=/home/bigdata/apps/apache-ant-1.9.4
export PATH=$PATH:$ANT_HOME/bin
执行命令使配置的环境变量生效:
source ~/.bashrc
检测安装是否成功:
ant -version
8、上面的步骤都配置完,基本就大功告成了。进入${HIVE_HOME}/bin目录:
${HIVE_HOME}/bin/hive --service hwi
或者让在后台运行:
nohup bin/hive --service hwi > /dev/null 2> /dev/null &
9、前面配置了端口号为9999,所以这里直接在浏览器中输入:http://bigdata05:9999/hwi
10、看到web界面大功告成。
Hive基本使用
1、创建库:
create database if not exists mydb;
2、查看库:
show databases;
3、切换数据库:
use mydb;
4、创建表:
create table if not exists t_user(id string, name string);
create table t_user(id string, name string) row format delimited fields terminated by ',';
5、查看表列表:
show tables;
6、查看表的详细信息:
desc formatted t_user;
7、插入数据:
insert into table t_user values ('1','huangbo'), ('2','xuzheng'), ('3','wangbaoqiang');
8、查询数据:
select * from t_user;
9、导入数据:准备一个数据文件user.txt放在/home/bigdata/test/目录下,该文件中的数据为:
4,liudehua
5,wuyanzu
6,liangchaowei
然后使用命令导入数据:
load data local inpath '/home/bigdata/test/user.txt' into table t_user;
10、再次查询数据:
select * from t_user;