Hive详解
什么是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的系统架构
- 用户接口,包括 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安装好(Tez也是支持在YARN上执行的),然后到Hive中配置一下就可以了,不管使用什么引擎,不会对我们使用hive造成什么影响,也就说对上层的使用没有影响
第三代大数据计算引擎:Spark
Spark在当时属于一个划时代的产品,改变了之前基于磁盘的计算思路,而是采用内存计算,就是说Spark把数据读取过来以后,中间的计算结果是不会进磁盘的,一直到出来最终结果,才会写磁盘,这样就大大提高了计算效率,而MapReduce的中间结果是会写磁盘的,所以效率没有Spark高。Spark的执行效率号称比MapReduce 快100倍,当然这需要在一定数据规模下才会差这么多,如果我们就计算几十兆或者几百兆的文件,你去对比发现其实也不会差多少,后面我们也会学到Spark这个基于内存的大数据计算引擎
注意:spark也是支持在YARN上执行的
第四代大数据计算引擎,:Flink
Flink是一个可以支持纯实时数据计算的计算引擎,在实时计算领域要优于Saprk,Flink和Spark其实是有很多相似之处,在某些方面他们两个属于互相参考,互相借鉴,互相成长,等后面我们学到这个计算引擎的时候再详细分析。
注意: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://ip:port/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>xxx</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不需要启动任何进程