一 Hive简介
1.1. Hive的简介
1.1.1 什么是hive
hive是一个构建在Hadoop上的数据仓库工具(框架),可以将结构化的数据文件映射成一张数据表,并可以使用类sql的方式来对这样的数据文件进行读,写以及管理(包括元数据)。这套HIVE SQL 简称HQL。hive的执行引擎可以是MR、spark、tez。
如果执行引擎是MapReduce的话,hive会将Hql翻译成MR进行数据的计算。 用户可以使用命令行工具或JDBC驱动程序来连接到hive。
1.1.2 为什么使用hive
因为直接使用MapReduce,需要面临以下问题:
- 人员学习成本高
- 项目周期要求太短
- MapReduce实现复杂查询逻辑开发难度大
1.1.3 hive的优缺点
1) hive的优点
1.学习成本低
提供了类SQL查询语言HQL(简单,容易上手),避免了直接写MapReduce(适合java语言不好的,sql熟练的人),减少开发人员的学习成本。
2.可扩展性好
为超大数据集设计了计算/扩展能力(MR作为计算引擎,HDFS作为存储系统),Hive可以自由的扩展集群的规模,一般情况下不需要重启服务。
3.适合做离线分析处理(OLAP)
Hive的执行延迟比较高,因此Hive常用于数据分析,对实时性要求不高的场合。
4.延展性好
Hive支持用户自定义函数,用户可以根据自己的需求来实现自己的函数。
5.良好的容错性
某个数据节点出现问题HQL仍可完成执行。
6.统计管理
提供了统一的元数据管理
2) hive的缺点
1. hive的HQL表达能力有限
- 迭代式算法无法表达,比如PageRank(网页排名)
- 数据挖掘方面,比如kmeans(k均值聚类算法)
2. hive的效率比较低
- hive自动生成的mapreduce作业,通常情况下不够智能化
- hive调优比较困难,粒度较粗
1.2. Hive架构和原理
1.2.1 hive的架构简介
从上图可以看出,Hive的体系结构分为以下几部分:
1. 用户连接接口
CLI:是指Shell命令行
JDBC/ODBC:是指Hive的java实现,与传统数据库JDBC类似。
WebUI:是指可通过浏览器访问Hive。
2. thriftserver:
hive的可选组件,此组件是一个软件框架服务,允许客户端使用包括Java、C++、Ruby和其他很多种语言,通过编程的方式远程访问Hive。
3. 元数据
Hive将元数据存储在数据库中,如mysql、derby。Hive中的元数据包括(表名、表所属的数据库名、表的拥有者、列/分区字段、表的类型(是否是外部表)、表的数据所在目录等)
4. 驱动器(Driver)
- 解析器(SQLParser):
将HQL字符串转换成抽象语法树AST,这一步一般都用第三方工具库完成,比如antlr;对AST进行语法
分析,比如表是否存在、字段是否存在、SQL语义是否有误。
- 编译器(Compiler):
对hql语句进行词法、语法、语义的编译(需要跟元数据关联),编译完成后会生成一个执行计划。hive上就
是编译成mapreduce的job。
- 优化器(Optimizer):
将执行计划进行优化,减少不必要的列、使用分区、使用索引等。优化job。
- 执行器(Executer):
将优化后的执行计划提交给hadoop的yarn上执行。提交job。
5. hadoop
Jobtracker是hadoop1.x中的组件,它的功能相当于:Resourcemanager+AppMaster
TaskTracker相当于:Nodemanager + yarnchild
Hive的数据存储在HDFS中,大部分的查询、计算由MapReduce完成
注意:
- 包含*的全表查询,比如select * from table 不会生成MapRedcue任务
- 包含*的limit查询,比如select * from table limit 3 不会生成MapRedcue任务
1.2.2 hive的工作原理
1. 用户提交查询等任务给Driver。
2. 驱动程序将Hql发送编译器,检查语法和生成查询计划。
3. 编译器Compiler根据用户任务去MetaStore中获取需要的Hive的元数据信息。
4. 编译器Compiler得到元数据信息,对任务进行编译,先将HiveQL转换为抽象语法树,然后将抽象语法树转换成查询块,将查询块转化为逻辑的查询计划,重写逻辑查询计划,将逻辑计划转化为物理的计划(MapReduce), 最后选择最佳的策略。
5. 将最终的计划提交给Driver。到此为止,查询解析和编译完成。
6. Driver将计划Plan转交给ExecutionEngine去执行。
7. 在内部,执行作业的过程是一个MapReduce工作。执行引擎发送作业给JobTracker,在名称节点并把它分配作业到TaskTracker,这是在数据节点。在这里,查询执行MapReduce工作。
7.1 与此同时,在执行时,执行引擎可以通过Metastore执行元数据操作。
8. 执行引擎接收来自数据节点的结果。
9. 执行引擎发送这些结果值给驱动程序。
10. 驱动程序将结果发送给Hive接口。
1.2.3 hive和hadoop的关系
- hive本身其实没有多少功能,hive就相当于在hadoop上面包了一个壳子,就是对hadoop进行了一次封装。
- hive的存储是基于hdfs/hbase的,hive的计算是基于mapreduce。
参考下图:
1.3 hive与传统型数据库的区别
1. Hive采用了类SQL的查询语言HQL,因此很容易将Hive理解为数据库。其实从结构上来看,Hive和数据库除了拥有类似的查询语言,再无类似之处。
2. 数据库可以用在OLTP的应用中,但是Hive是为数据仓库而设计的,清楚这一点,有助于从应用角度理解Hive的特性。
3. Hive不适合用于联机事务处理(OLTP),也不提供实时查询功能。它最适合应用在基于大量不可变数据的批处理作业。Hive 的特点是可伸缩(在Hadoop 的集群上动态的添加设备),可扩展、容错、输入格式的松散耦合。Hive 的入口是DRIVER ,执行的SQL语句首先提交到DRIVER驱动,然后调COMPILER解释驱动,最终解释成MapReduce 任务执行,最后将结果返回。
4. MapReduce 开发人员可以把自己写的 Mapper 和 Reducer 作为插件支持 Hive 做更复杂的数据分析。 它与关系型数据库的 SQL 略有不同,但支持了绝大多数的语句(如 DDL、DML)以及常见的聚合函数、连接查询、条件查询等操作。
Hive和数据库的比较如下表:
比较项 | 关系数据库 | Hive |
ANSI SQL | 支持 | 不完全支持 |
更新 | UPDATE INSERT DELETE | INSERT OVERWRITE\ INTO TABLE |
事务 | 支持 | 支持(部分支持) |
模式 | 写模式 | 读模式 |
存储位置 | 块设备、本地文件系统 | HDFS |
延时 | 低 | 高 |
多表插入 | 不支持 | 支持 |
子查询 | 完全支持 | 只能用在From子句中 |
视图 | Updatable | Read-only |
可扩展性 | 低 | 高 |
数据规模 | 小 | 大 |
实时响应 | 毫秒级 | 秒级 |
详情解析
1、**查询语言**:由于SQL被广泛的应用在数据仓库中,因此,专门针对Hive的特性设计了类SQL的查询语言HQL。熟悉SQL开发的开发者可以很方便的使用Hive进行开发。
2、**数据存储位置**:Hive是建立在Hadoop之上的,所有Hive的数据都是存储在HDFS中的。而数据库则可以将数据保存在块设备或者本地文件系统中。
3、**数据格式**:Hive中没有定义专门的数据格式,数据格式可以由用户指定,用户定义数据格式需要指定三个属性:列分隔符(通常为空格、"\t"、"\x001")、行分隔符("\n")以及读取文件数据的方法(Hive中默认有三个文件格式TextFile、SequenceFile以及RCFile)。由于在加载数据的过程中,不需要从用户数据格式到Hive定义的数据格式的转换,因此,Hive在加载的过程中不会对数据本身进行任何修改,而只是将数据内容复制或者移动到相应的HDFS目录中。而在数据库中,不同的数据库有不同的存储引擎,定义了自己的数据格式。所有数据都会按照一定的组织存储,因此,数据库加载数据的过程会比较耗时。
4、**数据更新**:由于Hive是针对数据仓库应用设计的,而数据仓库的内容是读多写少的。因此,Hive中不支持对数据的改写和添加,所有的数据都是在加载的时候中确定好的。而数据库中的数据通常是需要经常进行修改的,因此可以使用INSERT INTO...VALUES添加数据,使用UPDATE...SET修改数据。
5、**索引**:,Hive在加载数据的过程中不会对数据进行任何处理,甚至不会对数据进行扫描,因此也没有对数据中的某些Key建立索引。Hive要访问数据中满足条件的特定值时,需要暴力扫描整个数据,因此访问延迟较高。由于MapReduce的引入,Hive可以并行访问数据,因此即使没有索引,对于大数据量的访问,Hive仍然可以体现出优势。数据库中,通常会针对一个或几个列建立索引,因此对于少量的特定条件的数据的访问,数据库可以有很高的效率,较低的延迟。由于数据的访问延迟较高,决定了Hive不适合在线数据查询。
6、**执行**:Hive中大多数查询的执行是通过Hadoop提供的MapReduce来实现的(类似select * from tbl的查询不需要MapReduce)。而数据库通常有自己的执行引擎。
7、**执行延迟**:之前提到,Hive在查询数据的时候,由于没有索引,需要扫描整个表,因此延迟较高。另外一个导致Hive执行延迟高的因素是MapReduce框架。由于MapReduce本身具有较高的延迟,因此在利用MapReduce执行Hive查询时,也会有较高的延迟。相对的,数据库的执行延迟较低。当然,这个低是有条件的,即数据规模较小,当数据规模大到超过数据库的处理能力的时候,Hive的并行计算显然能体现出优势。
8、**可扩展性**:由于Hive是建立在Hadoop之上的,因此Hive的可扩展性是和Hadoop的可扩展性是一致的。而数据库由于ACID语义的严格限制,扩展性非常有限。目前最先进的并行数据库Oracle在理论上的扩展能力也只有100台左右。
9、**数据规模**:由于Hive建立在集群上并可以利用MapReduce进行并行计算,因此可以支持很大规模的数据;对应的,数据库可以支持的数据规模较小。
Hive和Mysql的比较
- mysql用自己的存储存储引擎,hive使用的hdfs来存储。
- mysql使用自己的执行引擎,而hive使用的是mapreduce来执行。
- mysql使用环境几乎没有限制,hive是基于hadoop的。
- mysql的低延迟,hive是高延迟。
- mysql的handle的数据量较小,而hive的能handle数据量较大。
- mysql的可扩展性较低,而hive的扩展性较高。
- mysql的数据存储格式要求严格,而hive对数据格式不做严格要求。
- mysql可以允许局部数据插入、更新、删除等,而hive不支持局部数据的操作。
二 Hive的安装部署
Hive常用的安装分三种(注意:Hive会自动监测Hadoop的环境变量,如有就必须启动Hadoop)
先从本地上传Hive安装文件apache-hive-2.1.1-bin.tar.gz
到/root/soft
2.1 内嵌模式:
使用hive自带默认元数据库derby来进行存储,通常用于测试
- 优点:使用简单,不用进行配置
- 缺点:只支持单session。
2.1.1 安装步骤:
1)解压hive并配置环境变量
[root@zrclass01 local]# tar -zxvf apache-hive-2.1.1-bin.tar.gz -C /usr/local
#修改hive安装路径名,方便以后使用
[root@zrclass01 local]# mv apache-hive-2.1.1-bin/ hive
[root@zrclass01 local]# vi /etc/profile
# 添加如下内容:
export HIVE_HOME=/usr/local/hive
export PATH=$HIVE_HOME/bin:$PATH
#让profile生效
[root@zrclass01 local]# source /etc/profile
2) 配置hive-env.sh
如果不存在,就用hive.env.sh.template复制一个
export HIVE_CONF_DIR=/usr/local/hive/conf
export JAVA_HOME=/usr/local/jdk
export HADOOP_HOME=/usr/local/hadoop
export HIVE_AUX_JARS_PATH=/usr/local/hive/lib
3) 配置hive-site.xml
hive2.1.1中默认是没有hive-site.xml
,可以把conf/hive-default.xml.template
拷贝过来使用
[root@zrclass01 conf]# cp hive-default.xml.template hive-site.xml
[root@zrclass01 conf]# vi hive-site.xml
把hive-site.xml 中所有包含 ${system:java.io.tmpdir}替换成/usr/local/hive/iotmp.
如果系统默认没有指定系统用户名,那么要把配置${system:user.name}替换成当前用户名root
扩展:hive-site.xml中有两个重要的配置说明
<!-- 解决启动报错问题,去掉文件中所有带system: ,如${system:java.io.tmpdir}改为${java.io.tmpdir} -->
<property>
<name>hive.exec.local.scratchdir</name>
<value>${java.io.tmpdir}/${system:user.name}</value>
<description>Local scratch space for Hive jobs</description>
</property>
<!-- 该参数主要指定Hive的数据存储目录 -->
<property>
<name>hive.metastore.warehouse.dir</name>
<value>/user/hive/warehouse</value>
<description>location of default database for the warehouse</description>
</property>
<!-- 该参数主要指定Hive的临时文件存储目录 -->
<property>
<name>hive.exec.scratchdir</name>
<value>/tmp/hive</value>
<description>HDFS root scratch dir for Hive jobs which gets created with write all (733) permission. For each connecting user, an HDFS scratch dir: ${hive.exec.scratchdir}/<username">> is created, with ${hive.scratch.dir.permission}.</description>
</property>
在linux中新建上面两个目录,并且进行权限赋值(可选操作,hive会自动创建)
[root@zrclass01 hive] # hdfs dfs -mkdir -p /user/hive/warehouse
[root@zrclass01 hive] # hdfs dfs -mkdir -p /tmp/hive/
[root@zrclass01 hive] # hdfs dfs -chmod 750 /user/hive/warehouse
[root@zrclass01 hive] # hdfs dfs -chmod 777 /tmp/hive
- 启动hadoop
[root@zrclass01 hadoop]# start-dfs.sh
[root@zrclass01 hadoop]# start-yarn.sh
- 初始化hive
[root@zrclass01 hive]# schematool --initSchema -dbType derby
- 启动hive
(注:启动之前要启动hdfs sbin/start-dfs.sh 和yarn sbin/start-yarn.sh )
[root@zrclass01 hive]# bin/hive
#进入后可以执行下面命令进行操作:
hive>show dataases; #查看数据库
hive>show tables; #查看表
简单sql演示执行
# 创建表
hive> create table dog(id int,name string);
hive> select * from dog;
hive> insert into dog values(1,"wangcai");
hive> desc dog; #查看表结构
hive> quit # 退出
2.2 本地模式
使用mysql替换derby进行元数据的存储,hive的相关进程都是在同一台机器上,即本地模式。mysql因为是独立的进程,所以mysql可以和hive在同一机器上,也可以在其他机器上。
说明:
通常使用关系型数据库来进行元数据存储(mysql、oracle等执行带jdbc驱动的数据库)
- 优点:支持多session
- 缺点:需要配置、还需要安装mysql等关系型数据库
2.2.1 配置安装mysql
安装MySql服务器
mysql安装的步骤介绍
# 环境准备
# CentOS7中,系统默认采用的数据库是mariadb,这个数据库与MySQL冲突!
# 因此,在安装MySQL之前,需要先将其卸载!
[root@zrclass03 ~]# rpm -qa | grep mariadb # 查询是否已经安装了mariadb
mariadb-libs-5.5.64-1.el7.x86_64 # 查询结果。如果没有这个结果,说明没有安装。
# 强制卸载mariadb
# --nodeps: 强制卸载,RPM卸载程序的时候,如果这个程序被其他的程序依赖,是无法卸载的。
# 此时,就需要使用--nodeps,忽略依赖,强制卸载。
# 下面的卸载命令中,卸载的包是上方查询到的包
[root@zrclass03 ~]# rpm -e mariadb-libs-5.5.64-1.el7.x86_64 --nodeps
# 安装MySQL
# 安装MySQL, 其实就需要安装 mysql-community-server, 但是它依赖其他的包
[root@zrclass03 mysql]# rpm -ivh mysql-community-common-5.7.28-1.el7.x86_64.rpm
[root@zrclass03 mysql]# rpm -ivh mysql-community-libs-5.7.28-1.el7.x86_64.rpm
[root@zrclass03 mysql]# rpm -ivh mysql-community-client-5.7.28-1.el7.x86_64.rpm
[root@zrclass03 mysql]# yum install -y net-tools
[root@zrclass03 mysql]# yum -y install perl
[root@zrclass03 mysql]# rpm -ivh mysql-community-server-5.7.28-1.el7.x86_64.rpm
# 开启MySQL服务
# 查看MySQL服务的运行状态
[root@zrclass03 ~]# systemctl status mysqld
# 如果MySQL服务没有开启,则开启
[root@zrclass03 ~]# systemctl start mysqld
# 登录到MySQL
# 在第一次开启MySQL服务的时候,会自动生成一个随机的密码
[root@zrclass03 ~]# grep password /var/log/mysqld.log # 到mysqld.log文件中查找password
2020-12-16T07:47:14.117739Z 1 [Note] A temporary password is generated for root@localhost: pVLJs6&o(QQe
# 使用这个随机密码登录到MySQL
[root@zrclass01 ~]# mysql -u root -p
pHLSs6&o]GEe # 这里用自己的密码登录
# 修改MySQL安全等级
# 1. 修改MySQL的密码策略(安全等级)
# MySQL默认的密码安全等级有点高,在设置密码的时候,必须同时包含大小写字母、数字、特殊字符,以及对位数有要求
#show variables like '%validate_password%'; # 查看密码策略
set global validate_password_policy=LOW; # 修改密码策略等级为LOW
set global validate_password_length=4; # 密码的最小长度
set global validate_password_mixed_case_count=0; # 设置密码中至少要包含0个大写字母和小写字母
set global validate_password_number_count=0; # 设置密码中至少要包含0个数字
set global validate_password_special_char_count=0; # 设置密码中至少要包含0个特殊字符
# 2. 修改密码
alter user root@localhost identified by 'root';
# 3. 远程授权
grant all privileges on *.* to 'root'@'%' identified by 'root' with grant option;
2.2.2 配置hive的环境
1、解压并配置环境变量
2、配置hive的配置文件
cp hive-env.sh.template hive-env.sh
vi hive-env.sh(可以配置jdk、hive的conf路径)
3、在Hive的conf配置hive的自定义配置文件
vi hive-site.xml:添加如下内容
**注意:**前三步和内嵌模式一样
4、找到下面四个属性进行修改对应的值。
<!--配置mysql的连接字符串-->
<property>
<name>javax.jdo.option.ConnectionURL</name>
<value>jdbc:mysql://zrclass03:3306/hive?createDatabaseIfNotExist=true</value>
<description>JDBC connect string for a JDBC metastore</description>
</property>
<!--配置mysql的连接驱动-->
<property>
<name>javax.jdo.option.ConnectionDriverName</name>
<value>com.mysql.jdbc.Driver</value>
<description>Driver class name for a JDBC metastore</description>
</property>
<!--配置登录mysql的用户-->
<property>
<name>javax.jdo.option.ConnectionUserName</name>
<value>root</value>
<description>username to use against metastore database</description>
</property>
<!--配置登录mysql的密码-->
<property>
<name>javax.jdo.option.ConnectionPassword</name>
<value>root</value>
<description>password to use against metastore database</description>
</property>
注意:hive的元数据在mysql库里创建的数据库hive的编码最好设置成latin1.
show variables like 'character%';
5、将mysql的驱动包mysql-connector-java-5.1.28-bin.jar
上传到$HIVE_HOME/lib下(注意:驱动是jar结尾,不是tar结尾)
6、执行执行先要初始化数据库
[root@zrclass01 hive]# bin/schematool -initSchema -dbType mysql
7、启动hive
[root@zrclass01 hive]# bin/hive
说明:
2.3 远程模式
2.3.1 简介
将hive中的相关进程比如hiveserver2或者metastore这样的进程单独开启,使用客户端工具或者命令行进行远程连接这样的服务,即远程模式。客户端可以在任何机器上,只要连接到这个server,就可以进行操作。客户端可以不需要密码。
2.3.2 服务端的配置
1) 修改 hive-site.xml
<!--hive仓库在hdfs的位置-->
<property>
<name>hive.metastore.warehouse.dir</name>
<value>/user/hive/warehouse</value>
<description>location of default database for the warehouse</description>
</property>
<!-- 该参数主要指定Hive的临时文件存储目录 -->
<property>
<name>hive.exec.scratchdir</name>
<value>/tmp/hive</value>
</property>
<!--连接mysql的url地址-->
<property>
<name>javax.jdo.option.ConnectionURL</name>
<value>jdbc:mysql://zrclass03:3306/hive?createDatabaseIfNotExist=true&characterEncoding=latin1</value>
</property>
<!--mysql的驱动类-->
<property>
<name>javax.jdo.option.ConnectionDriverName</name>
<value>com.mysql.jdbc.Driver</value>
</property>
<!--mysql的用户名-->
<property>
<name>javax.jdo.option.ConnectionUserName</name>
<value>root</value>
</property>
<!--mysql的密码-->
<property>
<name>javax.jdo.option.ConnectionPassword</name>
<value>123456</value>
</property>
<!--hive工作的本地临时存储空间-->
<property>
<name>hive.exec.local.scratchdir</name>
<value>/usr/local/hive/iotmp/root</value>
</property>
<!--如果启用了日志功能,则存储操作日志的顶级目录-->
<property>
<name>hive.server2.logging.operation.log.location</name>
<value>/usr/local/hive/iotmp/root/operation_logs</value>
</property>
<!--Hive运行时结构化日志文件的位置-->
<property>
<name>hive.querylog.location</name>
<value>/usr/local/hive/iotmp/root</value>
</property>
<!--用于在远程文件系统中添加资源的临时本地目录-->
<property>
<name>hive.downloaded.resources.dir</name>
<value>/usr/local/hive/iotmp/${hive.session.id}_resources</value>
</property>
说明:使用远程模式,需要在hadoop的core-site.xml文件中添加一下属性
<property>
<name>hadoop.proxyuser.root.hosts</name>
<value>*</value>
</property>
<property>
<name>hadoop.proxyuser.root.groups</name>
<value>*</value>
</property>
2.3.3 hive的两种服务说明
第一种服务:hiveserver2
1. 该服务端口号默认是10000
2. 可以单独启动此服务进程,供远程客户端连接;此服务内置metastore服务。
3. 启动方式:
方法1:
直接调用hiveserver2。会进入监听状态不退出。
方法2:
hive --service hiveserver2 & 进入后台启动
方法3:
hive --service hiveserver2 >/dev/null 2>&1 &; #信息送入黑洞。
第二种服务:metastore
1. 此服务才是真正连接元数据库的服务进程
2. 也可以让远程客户端连接
3. 启动方式:
方法1:
- hive --service metastore &
方法2:
- hive --service metastore 2>&1 >/dev/null &; #信息送入黑洞。
2.3.4 客户端连接hiveserver2服务
说明:
-1. 连接此服务的hive客户端,只需要配好环境变量即可
-2. 只能使用hive中的beeline连接工具进行连接此服务,beeline是hive的一个轻量级的连接客户端工具。
连接方式:
方式1:
step1. beeline 回车
step2. !connect jdbc:hive2://ip:10000 回车
step3. 输入用户名 回车
step4. 输入密码 回车
方法2(直连):
1. beeline -u jdbc:hive2://ip:10000 -n 用户名
解析:
hive2,是hive的协议名称
ip: hiveserver2服务所在的主机IP。
10000,是hiveserver2的端口号d
2.3.5 客户端连接metastore服务
注意:想要连接metastore服务的客户端必须配置如下属性和属性值
<property>
<name>hive.metastore.uris</name>
<value>thrift://ip:9083</value>
</property>
解析:thrift:是协议名称
ip为metastore服务所在的主机ip地址
9083是默认端口号