Hive详解

发布时间 2023-05-30 22:36:19作者: strongmore

什么是Hive

Hive是建立在Hadoop上的数据仓库基础构架。它提供了一系列的工具,可以用来进行数据提取转化加载,可以简称为ETL。

Hive 定义了简单的类SQL查询语言,称为HQL,它允许熟悉SQL的用户直接查询Hadoop中的数据,同时,这个语言也允许熟悉MapReduce的开发者开发自定义的mapreduce任务来处理内建的SQL函数无法完成的复杂的分析任务。

Hive中包含的有SQL解析引擎,它会将SQL语句转译成M/R Job,然后在Hadoop中执行。

通过这里的分析我们可以了解到Hive可以通过sql查询Hadoop中的数据,并且sql底层也会转化成、mapreduce任务,所以hive是基于hadoop的。

Hive的数据存储

Hive的数据存储基于Hadoop的 HDFS
Hive没有专门的数据存储格式
Hive默认可以直接加载文本文件(TextFile),还支持SequenceFile、RCFile等文件格式
针对普通文本数据,我们在创建表时,只需要指定数据的列分隔符与行分隔符,Hive即可解析里面的数据

Hive的系统架构

image

  • 用户接口,包括 CLI、JDBC/ODBC、WebGUI
    CLI,即Shell命令行,表示我们可以通过shell命令行操作Hive
    JDBC/ODBC 是 Hive 的Java操作方式,与使用传统数据库JDBC的方式类似
    WebGUI,即通过浏览器操作
  • 元数据存储(Metastore),注意:这里的存储是名词,Metastore表示是一个存储系统
    Hive中的元数据包括表的相关信息,Hive会将这些元数据存储在Metastore中,目前Metastore只支持 mysql、derby。
  • Driver:包含:编译器、优化器、执行器
    编译器、优化器、执行器可以完成 Hive的 查询语句从词法分析、语法分析、编译、优化以及查询计划的生成。生成的查询计划最终存储在 HDFS 中,并在随后由 MapReduce 调用执行
  • Hadoop:Hive会使用 HDFS 进行存储,利用 MapReduce 进行计算
    Hive 的数据存储在 HDFS 中,大部分的查询由 MapReduce 完成(特例 select * from table 不会生成 MapRedcue 任务,如果在SQL语句后面再增加where过滤条件就会生成MapReduce任务了。)

用户通过接口传递Hive SQL,然后经过Driver对SQL进行分析、编译,生成查询计划,查询计划会存储在HDFS中,然后再通过MapReduce进行计算出结果,这就是整个大的流程。

其实在这里我们可以发现,Hive这个哥们是既不存储数据,也不计算数据,这些活都给了Hadoop来干,Hive底层最核心的东西其实就是Driver这一块,将SQL语句解析为最终的查询计划。

在这有一点需要注意的,就是从Hive2开始,其实官方就不建议默认使用MapReduce引擎了,而是建议使用Tez引擎或者是Spark引擎,不过目前一直到最新的3.x版本中mapreduce还是默认的执行引擎。

大数据计算引擎的发展阶段

第一代大数据计算引擎:MapReduce

第二代大数据计算引擎:Tez

Tez的存在感比较低,它是源于MapReduce,主要和Hive结合在一起使用,它的核心思想是将Map和Reduce两个操作进一步拆分,这些分解后的元操作可以灵活组合,产生新的操作,这些操作经过一些控制程序组装后,可以形成一个大的作业,这样可以提高计算效率,我们在实际工作中Hive使用的就是 Tez引擎,替换Hive的执行引擎也很简单,只需要把Tez安装好(Tez也是支持在YARN上执行的),然后到Hive中配置一下就可以了,不管使用什么引擎,不会对我们使用hive造成什么影响,也就说对上层的使用没有影响

第三代大数据计算引擎:Spark

Spark在当时属于一个划时代的产品,改变了之前基于磁盘的计算思路,而是采用内存计算,就是说Spark把数据读取过来以后,中间的计算结果是不会进磁盘的,一直到出来最终结果,才会写磁盘,这样就大大提高了计算效率,而MapReduce的中间结果是会写磁盘的,所以效率没有Spark高。Spark的执行效率号称比MapReduce 快100倍,当然这需要在一定数据规模下才会差这么多,如果我们就计算几十兆或者几百兆的文件,你去对比发现其实也不会差多少,后面我们也会学到Spark这个基于内存的大数据计算引擎

注意:spark也是支持在YARN上执行的

Flink是一个可以支持纯实时数据计算的计算引擎,在实时计算领域要优于Saprk,Flink和Spark其实是有很多相似之处,在某些方面他们两个属于互相参考,互相借鉴,互相成长,Flink后面我们也会学到,等后面我们讲到这个计算引擎的时候再详细分析。

注意:Flink也是支持在YARN上执行的。

MapReduce、Tez、Spark、Flink这些计算引擎都是支持在yarn上执行的,所以说Hdoop2中对架构的拆分是非常明智的。

Hive中的元数据存储,Metastore

Metastore是Hive元数据的集中存放地。Hive 中的元数据包括表的名字,表的列和分区及其属性,表的属性(是否为外部表等),表的数据所在的hdfs目录等

Metastore默认使用内嵌的derby数据库
Derby数据库的缺点:在同一个目录下一次只能打开一个会话
使用derby存储方式时,Hive会在当前目录生成一个derby.log文件和一个metastore_db目录,metastore_db里面会存储具体的元数据信息。

推荐使用MySQL作为外置存储引擎,可以支持多用户同时访问以及元数据共享。

Hive VS Mysql

HIVE MySQL
数据存储位置 HDFS 本地磁盘
数据格式 用户定义 系统决定
数据更新 不支持(不支持修改和删除) 不支持(不支持修改和删除)
索引 有,但较弱,一般很少用 有,经常使用的
执行 MapReduce Executor
执行延迟
可扩展性
数据规模

数据库 VS 数据仓库

前面我们说了Hive是一个数据仓库,咱们平时经常使用的mysql属于数据库,那数据库和数据仓库到底有什么区别呢?

下面我们来分析一下

  • 数据库:传统的关系型数据库主要应用在基本的事务处理,例如银行交易之类的场景
    数据库支持增删改查这些常见的操作。
  • 数据仓库:主要做一些复杂的分析操作,侧重决策支持,相对数据库而言,数据仓库分析的数据规模要大得多。但是数据仓库只支持查询操作,不支持修改和删除

这些都是明面上的一些区别
其实数据库与数据仓库的本质区别就是 OLTP与OLAP 的区别

OLTP VS OLAP

  • OLTP(On-Line Transaction Processing):操作型处理,称为联机事务处理,也可以称为面向交易的处理系统,它是针对具体业务在数据库联机的日常操作,通常对少数记录进行查询、修改。用户较为关心操作的响应时间、数据的安全性、完整性等问题
  • OLAP(On-Line Analytical Processing):分析型处理,称为联机分析处理,一般针对某些主题历史数据进行分析,支持管理决策。

OLTP侧重于事务,OLAP侧重于分析

所以数据库和数据仓库的特性是不一样的,不过我们平时在使用的时候,可以把Hive作为一个数据库来操作,但是你要知道他们两个是不一样的。数据仓库的概念是比数据库要大的。

Hive安装部署

下载

下载地址

目前hive主要有三大版本,Hive1.x、Hive2.x、Hive3.x。

注意了,在选择Hive版本的时候我们需要注意已有的Hadoop集群的版本。因为Hive会依赖于Hadoop,所以版本需要兼容才可以。的hive2.x的需要在hadoop2.x版本中运行,hive3.x的需要在hadoop3.x版本中运行。所以在这里我们最好是使用Hive3.x的版本,最终我们使用3.1.2版本。

Hive相当于Hadoop的客户端工具,安装时不一定非要放在集群的节点中,可以放在任意一个集群客户端节点上都可以

修改配置文件

进入hive的conf目录中,先对这两个模板文件重命名

mv hive-env.sh.template hive-env.sh
mv hive-default.xml.template hive-site.xml

然后再修改这两个文件的内容,在 hive-env.sh 文件的末尾直接增加下面三行内容,【根据实际的路径配置】

export JAVA_HOME=/root/test_hadoop/jdk8
export HIVE_HOME=/root/test_hive/hive3.1.2
export HADOOP_HOME=/root/test_hadoop/hadoop3.2

注意:在hive-site.xml文件中根据下面property中的name属性的值修改对应value的值,这些属性默认里面都是有的,所以都是修改对应的value的值即可,根据属性名搜索。

由于这里面需要指定Metastore的地址,Metastore我们使用Mysql,所以需要大家提前安装好
Mysql。

<property>
 <name>javax.jdo.option.ConnectionURL</name>
 <value>jdbc:mysql://42.192.20.119:3310/hive?serverTimezone=Asia/Shanghai</value>
</property>
<property>
 <name>javax.jdo.option.ConnectionDriverName</name>
 <value>com.mysql.cj.jdbc.Driver</value>
</property>
<property>
 <name>javax.jdo.option.ConnectionUserName</name>
 <value>root</value>
</property>
<property>
 <name>javax.jdo.option.ConnectionPassword</name>
 <value>abdyou000</value>
</property>
<property>
 <name>hive.querylog.location</name>
 <value>/root/test_hive/querylog</value>
</property>
<property>
 <name>hive.exec.local.scratchdir</name>
 <value>/root/test_hive/scratchdir</value>
</property>
<property>
 <name>hive.downloaded.resources.dir</name>
 <value>/root/test_hive/resources</value>
</property>

url及账号密码都需要改成自己mysql服务器的,mysql的驱动包也要上传到hive的lib目录下(可以通过windows下springboot项目的maven依赖找到jar包)。

修改hadoop的core-site.xml,如果不增加这个配置,使用beeline连接hive的时候会报错

<property>
 <name>hadoop.proxyuser.root.hosts</name>
 <value>*</value>
</property>
<property>
 <name>hadoop.proxyuser.root.groups</name>
 <value>*</value>
</property>

然后重启hadoop集群

初始化Hive的Metastore

bin/schematool -dbType mysql -initSchema

但是执行之后发现报错了,提示hive-site.xml文件中的第3215行内容有问题,其实这个是原始配置文件本身就有的问题,最直接的方法就是把这一行删掉就可以了。

Exception in thread "main" java.lang.RuntimeException: com.ctc.wstx.exc.WstxParsingException: Illegal character entity: expansion character (code 0x8
 at [row,col,system-id]: [3215,96,"file:/root/test_hive/hive3.1.2/conf/hive-site.xml"]
        at org.apache.hadoop.conf.Configuration.loadResource(Configuration.java:2981)
        at org.apache.hadoop.conf.Configuration.loadResources(Configuration.java:2930)
        at org.apache.hadoop.conf.Configuration.getProps(Configuration.java:2805)
        at org.apache.hadoop.conf.Configuration.get(Configuration.java:1459)
        at org.apache.hadoop.hive.conf.HiveConf.getVar(HiveConf.java:4996)
        at org.apache.hadoop.hive.conf.HiveConf.getVar(HiveConf.java:5069)
        at org.apache.hadoop.hive.conf.HiveConf.initialize(HiveConf.java:5156)
        at org.apache.hadoop.hive.conf.HiveConf.<init>(HiveConf.java:5104)
        at org.apache.hive.beeline.HiveSchemaTool.<init>(HiveSchemaTool.java:96)
        at org.apache.hive.beeline.HiveSchemaTool.main(HiveSchemaTool.java:1473)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:497)
        at org.apache.hadoop.util.RunJar.run(RunJar.java:323)
        at org.apache.hadoop.util.RunJar.main(RunJar.java:236)

修改后再执行初始化命令,初始化Metastore,这个过程需要等一会,大概几十秒。初始化成功以后,查看MySQL数据库,发现会自动创建一堆表,看到这些就说明Metastore初始化成功了。

这样Hive就安装好了,注意了,目前针对Hive不需要启动任何进程