大数据之 Hadoop-12-1-Hive 基础

一、Hive简介

Hive是一个基于Hadoop 的数据仓库架构,使用 SQL 语句读、写和管理大型分布式数据集。Hive可以将SQL 语句转化为 MapReduce(或 Apache Spark和 Apache Tez) 任务执行,大大降低了Hadoop的使用门槛,减少了开发MapReduce程序的时间成本。

我们可以将Hive理解为一个客户端工具,其提供了一种类SQL查询语言,称为 HiveQL。这使得Hive十分适合数据仓库的统计分析,能够轻松使用HiveQL开启数据仓库任务,如提取/转换/加载(ETL)、分析报告和数据分析。Hive不仅可以分析HDFS文件系统中的数据也可以分析其他存储系统,例如 HBase。

file

  • hive执行程序在yarn上
  • hive分析数据底层在MapReduce上
  • hive的数据存储在hdfs上

架构

本质就是存储了Hdfs文件表、数据库之间的映射关系(元数据), 然后提供了以 SQL 的方式去访问文件数据, 就跟访问表结构化数据一样。它通过翻译SQL然后通过计算引擎去计算得到查询结果。

file

  • 元数据MetaStore: 就是Hdfs文件和表、数据库之间的映射关系数据. 默认存储在自带的 derby 数据库中,一般配置存储到 MySQL中
  • Driver:
    SQL 解析器: 将 SQL 字符串转换成抽象语法树 AST, 然后对 AST 进行语法分析
    Physical Plan编译器: 将 AST 编译生成逻辑执行计划。
    Query Optimizer查询优化器: 对逻辑执行计划进行优化.
    Execution执行器: 把逻辑执行计划转换成可以运行的物理计划(比如MapReduce或者Spark
  • 客户端: 提供了各种个样访问Hive的方式, 比如 CLI(hive shell)、JDBC/ODBC(java访问hive), beeline

Metastore Server
由于Hive的元数据经常面临读取、修改和更新操作,因此不适合存储在HDFS中,通常将其存储在关系型数据库中,例如Derby或者MySQL。而 Metastore Server是Hive中的一个元数据服务,所有客户端都需要通过Metastore Server来访问存储在关系型数据库中的元数据。即客户端将访问请求发送给Metastore Server,由Metastore Server访问关系型数据库进行元数据的存取。

优缺点

优点

  • 操作接口采用类SQL语法,提供快速开发的能力(简单、容易上手),不用写复杂的MapReduce
  • Hive的执行延迟比较高,适合用于数据分析,对实时性要求不高的场合。
  • Hive优势在于处理大数据,对于处理小数据没有优势,因为Hive的执行延迟比较高(创建job耗时)。
  • Hive支持用户自定义函数,用户可以根据自己的需求来实现自己的函数

    缺点

  • Hive的HQL表达能力有限,迭代式算法无法表达,数据挖掘方面不擅长
  • Hive的效率比较低,Hive自动生成的MapReduce作业,通常情况下不够智能化,Hive调优比较困难,粒度较

Hive和数据库比较

 由于 Hive 采用了类似SQL 的查询语言 HQL(Hive Query Language),因此很容易将 Hive 理解为数据库。其实从结构上来看,Hive 和数据库除了拥有类似的查询语言,其他不一样了

1、数据存储位置

Hive 是建立在 Hadoop 之上的,所有 Hive 的数据都是存储在 HDFS 中的。而数据库则可以将数据保存在块设备或者本地文件系统中。

2、数据更新

由于Hive是针对数据仓库应用设计的,而数据仓库的内容是读多写少的。因此,Hive中不建议对数据的改写,所有的数据都是在加载的时候确定好的。
而数据库中的数据通常是需要经常进行修改的,因此可以使用 INSERT INTO … VALUES 添加数据,使用 UPDATE … SET修改数据。

3、索引

 Hive在加载数据的过程中不会对数据进行任何处理,甚至不会对数据进行扫描,因此也没有对数据中的某些Key建立索引。Hive要访问数据中满足条件的特定值时,需要暴力扫描整个数据,因此访问延迟较高。由于 MapReduce 的引入, Hive 可以并行访问数据,因此即使没有索引,对于大数据量的访问,Hive 仍然可以体现出优势。
数据库中,通常会针对一个或者几个列建立索引,因此对于少量的特定条件的数据的访问,数据库可以有很高的效率,较低的延迟。由于数据的访问延迟较高,决定了 Hive 不适合在线数据查询

4、执行

hive大多数查询用Hadoop的madpreduce执行
数据库用字节的执行引擎

5、执行延迟

Hive 在查询数据的时候,由于没有索引,需要扫描整个表,因此延迟较高。另外一个导致 Hive 执行延迟高的因素是 MapReduce框架。由于MapReduce 本身具有较高的延迟,因此在利用MapReduce 执行Hive查询时,也会有较高的延迟。
数据库的执行延迟较低。当然,这个低是有条件的,即数据规模较小,当数据规模大到超过数据库的处理能力的时候,Hive的并行计算显然能体现出优势。

6、可扩展性

Hive是建立在Hadoop之上的,因此Hive的可扩展性是和Hadoop的可扩展性是一致的
数据库由于ACID语义的严格限制,扩展性有限

7、数据规模

 Hive建立在集群上并可以利用MapReduce进行并行计算,因此可以支持很大规模的数据;
数据库可以支持的数据规模较小。

二、Hive三种运行模式

Hive根据 Metastore Server 的位置不同可以分为三种运行模式:内嵌模式、本地模式和远程模式

内嵌模式

内嵌模式是Hive入门的最简单方法,是Hive默认的启动模式,使用Hive内嵌的Derby数据库存储元数据,并将数据存储于本地磁盘上。在这种模式下,Metastore Server、Hive服务、Derby三者运行于同一个JVM进程中,这就意味着每次只能允许一个会话对Derby中的数据进行访问。若开启第二个会话进行访问,Hive将提示报错。因此,内嵌模式常用于测试,不建议用于生产环境

本地模式

本地模式需要使用其他关系型数据库来存储Hive元数据信息,最常用的为 MySQL。在这种模式下,Metastore Server 与 Hive服务仍然运行于同一个JVM进程中,但是MySQL 数据库可以独立运行在另一个进程中,可以是同一台计算机也可以是远程的计算机。因此,本地模式支持多会话以及多用户对 Hive 数据的访问,每当开启一个连接会话,Hive将开启一个JVM进程。

远程模式

远程模式将Metastore Server分离了出来,作为一个单独的进程,并且可以部署多个,运行于不同的计算机上。这样的模式,将数据库层完全置于防火墙后,使客户端访问时不需要数据库凭据(用户名和密码),提高了可管理性和安全性。

三、Hive安装与基础配置

由于 Hive基于Hadoop,因此在安装Hive之前需要先安装好Hadoop。Hive只需要在Hadoop集群的其中一个节点安装即可,而不需要搭建Hive集群。

由于内嵌模式不能用于生产环境,所以,这里不讲,直接使用本地模式来演示安装。

1、下载Hive

从Apache官网 下载 Hive 的稳定版本,这里使用的是 apache-hive-2.3.9-bin.tar.gz

下载地址:https://dlcdn.apache.org/hive/

由于官网的资源下载比较慢,可以使用国内的镜像资源快速下载:
mirrors.bfsu.edu.cn
mirrors.tuna.tsinghua.edu.cn

清华的镜像源下载地址:https://mirrors.tuna.tsinghua.edu.cn/apache/hive/hive-2.3.9/apache-hive-2.3.9-bin.tar.gz

可以看到,清华的镜像源下载速度飞快:
file

2、安装Hive

(1)将下载 Hive 安装文件上传到 centos01 服务器的 /opt/softwares 目录并将其解压到目录/opt/modules/

$ cd /opt/softwares
$ wget https://mirrors.tuna.tsinghua.edu.cn/apache/hive/hive-2.3.9/apache-hive-2.3.9-bin.tar.gz
$ tar -zxvf apache-hive-2.3.9-bin.tar.gz -C /opt/modules/

(2) 查看

$ cd /opt/modules/apache-hive-2.3.9-bin
[root@centos01 apache-hive-2.3.9-bin]# ls -l
总用量 56
drwxr-xr-x. 3 root root   133 9月  13 08:09 bin
drwxr-xr-x. 2 root root  4096 9月  13 08:09 binary-package-licenses
drwxr-xr-x. 2 root root  4096 9月  13 08:09 conf
drwxr-xr-x. 4 root root    34 9月  13 08:09 examples
drwxr-xr-x. 7 root root    68 9月  13 08:09 hcatalog
drwxr-xr-x. 2 root root    44 9月  13 08:09 jdbc
drwxr-xr-x. 4 root root 12288 9月  13 08:09 lib
-rw-r--r--. 1 root root 20798 6月   2 04:43 LICENSE
-rw-r--r--. 1 root root   230 6月   2 04:43 NOTICE
-rw-r--r--. 1 root root   667 6月   2 04:52 RELEASE_NOTES.txt
drwxr-xr-x. 4 root root    35 9月  13 08:09 scripts

3.配置环境变量

为了后续能在任意目录下执行Hive相关命令,需要配置Hive环境变量。修改系统环境变量文件 /etc/profile:

$ sudo vi /etc/profile

在末尾加入以下内容:

export HIVE_HOME=/opt/modules/apache-hive-2.3.9-bin
export PATH=$PATH:$HIVE_HOME/bin

修改完毕后,刷新profile文件使修改生效:

$source /etc/profile

环境变量配置完成后,执行以下命令,若能成功输出当前Hive版本信息,则说明Hive环境变量配置成功。

[root@centos01 apache-hive-2.3.9-bin]# hive --version
Hive 2.3.9
Git git://chaos-mbp.lan/Users/chao/git/hive -r 92dd0159f440ca7863be3232f3a683a510a62b9d
Compiled by chao on Tue Jun 1 14:02:14 PDT 2021
From source with checksum 6715a3ba850b746eefbb0ec20d5a0187

4.关联Hadoop

Hive依赖于Hadoop,因此需要在Hive中指定Hadoop的安装目录。
复制 Hive安装目录下的 conf/hive-env.sh.template 文件为 hive-env.sh,然后修改 hive-env.sh ,添加以下内容,指定Hadoop的安装目录。

$ cd /opt/modules/apache-hive-2.3.9-bin/conf
[root@centos01 conf]# cp hive-env.sh.template hive-env.sh
vi hive-env.sh

修改的内容:

#HADOOP_HOME
export HADOOP_HOME=/opt/modules/hadoop-3.1.3

5.创建数据仓库目录

执行以下HDFS命令(需要先启动hadoop服务),在 HDFS中创建两个目录,并设置同组用户具有可写权限,便于同组其他用户进行访问:

$ hadoop fs -mkdir /tmp
$ hadoop fs -mkdir -p /user/hive/warehouse
$ hadoop fs -chmod g+w /tmp
$ hadoop fs -chmod g+w /user/hive/warehouse

上述创建的两个目录的作用如下:

  • /tmp: Hive 任务在 HDFS 中的缓存目录。
  • /user/hive/warehouse: Hive数据仓库目录,用于存储Hive创建的数据库。

Hive 默认会向这两个目录写入数据,当然也可以在配置文件中更改为其他目录。如果希望任意用户对这两个目录拥有可写权限,只需要将上述命令中的g+w改为a+w即可。

四.配置MySQL

本地模式的安装,还需要修改配置文件,设置MySQL数据库的连接信息。

1、配置MySQL

使用root 身份登录MySQL,创建名为“hive_db”的数据库,用于存放Hive元数据信息。然后创建用户 hive(密码同为hive),并为其赋予全局外部访问权限。整个过程使用的SQL 命令如

create database hive_ db;
create user hive IDENTIFIED by 'hive';
grant all privileges on hive_db.*  to hive@'%' identified by 'hive';
flush privileges;

2、配置Hive

(1)上传驱动包。
上传 Java连接MySQL的驱动包 mysql-connector-java-5.1.34-bin.jar$HIVE_HOME/lib 中。
(2)修改配置文件。
复制配置文件$HIVE_HOME/conf/hive-default.xmI.template为 hive-site.xml,然后修改 hive-site.xml 中的如下属性(或者将hive-site.xml中的默认配置信息清空,添加以下配置属性):

[root@centos01 apache-hive-2.3.9-bin]# cd conf
[root@centos01 conf]# ls -l
总用量 292
-rw-r--r--. 1 root root   1596 6月   2 04:43 beeline-log4j2.properties.template
-rw-r--r--. 1 root root 257574 6月   2 04:54 hive-default.xml.template
-rw-r--r--. 1 root root   2369 9月  13 08:30 hive-env.sh
-rw-r--r--. 1 root root   2365 6月   2 04:43 hive-env.sh.template
-rw-r--r--. 1 root root   2274 6月   2 04:43 hive-exec-log4j2.properties.template
-rw-r--r--. 1 root root   2925 6月   2 04:43 hive-log4j2.properties.template
-rw-r--r--. 1 root root   2060 6月   2 04:43 ivysettings.xml
-rw-r--r--. 1 root root   2719 6月   2 04:43 llap-cli-log4j2.properties.template
-rw-r--r--. 1 root root   7041 6月   2 04:43 llap-daemon-log4j2.properties.template
-rw-r--r--. 1 root root   2662 6月   2 04:43 parquet-logging.properties
[root@centos01 conf]# cp hive-default.xml.template hive-site.xml
[root@centos01 conf]# vi hive-site.xml

修改内容:

<configuration>
<!-- Mysql数据库连接信息 -->
<property> <!-- 连接Mysql的驱动类 -->
    <name>javax.jdo.option.ConnectionDriverName</name>
    <value>com.mysql.jdbc.Driver</value>
    <description>Driver class name for a JDBC metastore</description>
  </property>
    <property> <!-- Mysql连接地址 -->
    <name>javax.jdo.option.ConnectionURL</name>
    <value>jdbc:mysql://98.12.14.145:3306/hive_db?createDatabaseIfNotExist=true</value>
    <description>
      JDBC connect string for a JDBC metastore.
      To use SSL to encrypt/authenticate the connection, provide database-specific SSL flag in the connection URL.
      For example, jdbc:postgresql://myhost/db?ssl=true for postgres database.
    </description>
  </property>
    <property><!--MySQL用户名-->
    <name>javax.jdo.option.ConnectionUserName</name>
    <value>hive</value>
</property>
 <property><!--MySQL密码-->
    <name>javax.jdo.option.ConnectionPassword</name>
    <value>hive</value>
  </property>
    </configuration>

若需要配置其他日志等存储目录,可以添加以下配置属性:

<property><!--Hive数据库在 HDFS中的存放地址-->
<name>hive.metastore.warehouse.dir</name>
<value>/user/hive/warehouse</value>
</property>
<property><!--Hive本地缓存目录-->
<name>hive.exec.local.scratchdir</name>
<value>/tmp/hive</value>
</property>
<property><!--Hive在 HDFS中的缓存目录-->
<name>hive.exec.scratchdir</name>
<value>/tmp/hive</value>
</property>
<property><!--从远程文件系统中添加资源的本地临时目录-->
<name>hive.downloaded.resources.dir</name>
<value>/tmp/hive</value>
</property>
<property><!--Hive运行时的结构化日志目录-->
<name>hive.querylog.location</name>
<value>/tmp/hive</value>
</property>
<property><!--日志功能开启时,存储操作日志的最高级目录-->
<name>hive.server2.logging.operation.log.location</name>
<value>/tmp/hive</value>
</property>

Hive日志存储的默认目录为 /tmp/${username}${username}为当前系统用户名,注意:这里需要配置为上边的 /tmp/hive 绝对路径,防止后边报错。

需要注意的是,hive-site.xml 文件不可缺少,Hive启动时将读取文件 hive-site.xml中的配置属性,且hive-site.xml中的配置将覆盖Hive的默认配置文件 hive-default.xml.template中的相同配置。

3、初始化元数据

初始化hive在MySQL中的元数据信息(需要启动Hadoop):

# 切换到hadoop账户
# $ su hadoop 

# 进入到hadoop安装目录并启动
# [hadoop@centos01 sbin]$ cd /opt/modules/hadoop-3.1.3/sbin
# [hadoop@centos01 sbin]$ start-all.sh

$ schematool -dbType mysql -initSchema

在初始化的时候报这样的错误:

...
Exception in thread "main" java.lang.NoSuchMethodError: com.google.common.base.Preconditions.checkArgument(ZLjava/lang/String;Ljava/lang/Object;)V
    at org.apache.hadoop.conf.Configuration.set(Configuration.java:1357)
    at org.apache.hadoop.conf.Configuration.set(Configuration.java:1338)
    at org.apache.hadoop.mapred.JobConf.setJar(JobConf.java:518)
    at org.apache.hadoop.mapred.JobConf.setJarByClass(JobConf.java:536)
    at org.apache.hadoop.mapred.JobConf.<init>(JobConf.java:430)
    at org.apache.hadoop.hive.conf.HiveConf.initialize(HiveConf.java:4051)

原因:
hadoop和hive的两个guava.jar版本不一致
两个位置分别位于下面两个目录:

# apache-hive-2.3.9-bin
- /opt/modules/apache-hive-2.3.9-bin/lib  (guava-14.0.1.jar)

# hadoop-3.1.3
- /opt/modules/hadoop-3.1.3/share/hadoop/common/lib (guava-27.0-jre.jar)

解决办法:
删除低版本的那个,将高版本的复制到低版本目录下,即可以看到 hadoop的比 hive里边的 guava.jar 版本高,则需要删掉hive里边的,然后将hadoop里边的 guava-27.0-jre.jar 拷贝到hive对应的目录即可。

然后重新执行,可以看到已经初始化完成:

[hadoop@centos01 lib]$ schematool -dbType mysql -initSchema
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/opt/modules/apache-hive-2.3.9-bin/lib/log4j-slf4j-impl-2.6.2.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/opt/modules/hadoop-3.1.3/share/hadoop/common/lib/slf4j-log4j12-1.7.25.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [org.apache.logging.slf4j.Log4jLoggerFactory]
Metastore connection URL:    jdbc:mysql://98.12.14.145:3306/hive_db?createDatabaseIfNotExist=true
Metastore Connection Driver :    com.mysql.jdbc.Driver
Metastore connection User:   hive
Starting metastore schema initialization to 2.3.0
Initialization script hive-schema-2.3.0.mysql.sql
Initialization script completed
schemaTool completed
[hadoop@centos01 lib]$ 

查看数据库可以看到生成了很多存放元数据的表:
file

需要注意的是,若需要重新初始化,则重新初始化之前需要删除元数据库hive_db中的所有表,否则初始化将失败。

4、启动命令行

[hadoop@centos01 conf]$ hive
which: no hbase in (/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/opt/modules/jdk1.8.0_211/bin:/opt/modules/hadoop-3.1.3/bin:/opt/modules/hadoop-3.1.3/sbin:/opt/modules/sqoop-1.4.7/bin:/opt/modules/apache-hive-2.3.9-bin/bin:/root/bin)
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/opt/modules/apache-hive-2.3.9-bin/lib/log4j-slf4j-impl-2.6.2.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/opt/modules/hadoop-3.1.3/share/hadoop/common/lib/slf4j-log4j12-1.7.25.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [org.apache.logging.slf4j.Log4jLoggerFactory]

Logging initialized using configuration in jar:file:/opt/modules/apache-hive-2.3.9-bin/lib/hive-common-2.3.9.jar!/hive-log4j2.properties Async: true
Hive-on-MR is deprecated in Hive 2 and may not be available in the future versions. Consider using a different execution engine (i.e. spark, tez) or using Hive 1.X releases.
hive> 

可以看到已经启动成功了 ^_^

五、Hive数据库操作

hive> create database db_hive2 LOCATION '/input/db_hive.db';
hive> show databases;
OK
db_hive2
default
Time taken: 1.626 seconds, Fetched: 2 row(s)
hive> 

对应元数据库数据表的信息:
file

为者常成,行者常至