Hive的产生背景
MapReduce编程带来的不便性
MapReduce编程十分繁琐,在大多情况下,每个MapReduce程序需要包含Mapper、Reduceer和一个Driver,之后需要打成jar包扔到集群上运 行。如果mr写完之后,且该项目已经上线,一旦业务逻辑发生了改变,可能就会带来大规模的改动代码,然后重新打包,发布,非常麻烦(这种方式,也是最古老的方式)当大量数据都存放在HDFS上,如何快速的对HDFS上的文件进行统计分析操作?
一般来说,想要做会有两种方式:- 学Java、学MapReduce(十分麻烦)
- 做DBA的:写SQL(希望能通过写SQL这样的方式来实现,这种方式较好)
然而,HDFS中最关键的一点就是,数据存储HDFS上是没有schema的概念的
(schema:相当于表里面有列、字段、字段名称、字段与字段之间的分隔符等,这些就是schema信息)
然而HDFS上的仅仅只是一个纯的文本文件而已
那么,没有schema,就没办法使用sql进行查询
因此,在这种背景下,就有问题产生:
如何为HDFS上的文件添加Schema信息?如果加上去,是否就可以通过SQL的方式进行处理了呢?因此在这种背景下,Hive产生了
Hive概述
- 官网:https://hive.apache.org/
概述
简单介绍
使用一种类似于SQL的查询语言直接作用在分布式存储系统的文件之上
Facebook开源,贡献给社区的,解决海量结构化的日志数据统计问题(日志文件就是结构化的)构建在Hadoop之上的数据仓库:
1)Hive的数据是存放在HDFS上的
2)Hive的计算是通过yarn 和 mr的执行引擎
Hive QL ==翻译==> MapReduce作业 ==提交==> 集群Hive底层:
支持MapReduce
生产上用的多,速度虽然慢,但是稳定,能出结果;支持Spark(即Hive on Spark)
生产上不太用 可能会出现各种OOM,结果可能跑不出来支持Tez
Tez和Spark类似,都是DAG的执行引擎,这种执行引擎的性能比MR的性能要好很多
压缩/存储格式
压缩在大数据中,是非常非常重要的一个特性
进来的数据势必要进行压缩,如果不压缩,在网络中进行传输,网络开销太大
所以如何选择合适的压缩格式,是非常的关键;但是随之带来的问题是对CPU的要求会高些(因为涉及到了解压)
注意:Hive的社区,这几年对Hive做了非常多的优化,很多优化对比于以前,速度做了非常大的提升
Hive的发展历程
在Hive的发展历程中,不得不提的就是Stinger
Stinger分了几个阶段来做:Phase 1、2、3 ,Stringer.next;这几个阶段对Hive性能的提升是非常至关重要的
07/08 facebook
13/05 hive-0.11 Stinger Phase 1 加入了ORC/HiveServer2
13/10 hive-0.12 Stinger Phase 2 ORC improvement(对ORC做了些改善)
14/04 hive-0.13 Stinger Phase 3 Tez/Vectorized query engine(加入了Tez和支持向量化的查询)
14/11 hive-0.14 Stinger.next Phase 1 Cost-based optimizer(Cost-based简称CBO) (Cost-based的优化 很牛逼 算法各方面的优化 Spark现在也在做)
…… …….
当时有一句话:The Stinger Initiative making Apache Hive 100 times faster
Hive系统架构&部署架构&与RDBMS对比
Hive系统架构
Command-line shell:Hive自己的shell操作
Trift/JDBC:Thrift代表一种协议/服务端启起来,客户端可以通过JDBC的方式去访问
SQL进来Hive不认识,需要经历这几个阶段:- 首先将SQL语句转换成抽象语法树(抽象语法树拿到是不能执行的)
- 将抽象语法树转换成逻辑执行计划
- 对逻辑执行计划进行优化,形成物理执行计划,优化之后才能够变成作业去运行
有以下几点优点:
- 简单易上手
- 扩展能力较好(指集群 HDFS或是YARN)
- 统一的元数据管理
metastore包括的内容
database: name,location,owner,name
table: name,owner,location,column name/type/index,createtime - 和spark/impala等SQL引擎是通用的
通用的指,在拥有了统一的metastore之后,在Hive中创建一张表,在Spark/impala中是能用的,反之在Spark中创建一张表, 在Hive中也能用;只需要共用元数据,就可以切换SQL引擎
Hive部署架构
分为测试环境和生产环境- Hive元数据默认是存在derby里的,测试环境建议也用mysql(测试环境没有主备)
- 生产环境中mysql要配成主备(万一有一个挂了,就要出事,因此要将MySQL配成主备)
生产中不用derby
最终的作业提交到Hadoop集群上进行运行
Hive和RDBMS的关系
没有任何关系,只是sql长得有点像
对于Hive/RDBMS有以下几点:- 时效性、延时性比较高
- 事务没什么用(比较鸡肋,没什么实际的意义,对于离线的来说)
- insert/update没什么实际用途,大数据场景下大多数是select
- RDBMS也支持分布式,节点有限 成本高,处理的数据量小
- Hadoop集群规模更大 部署在廉价机器上,处理的数据量大
Hive部署
Hadoop生态圈软件下载地址
http://archive.cloudera.com/cdh5/cdh/5/
Hadoop部署
可以参考博主之前的Hadoop部署文章
MySQL部署
可以参考博主之前的MySQL编译安装
Hive部署
不需要每台节点上部署hive,只要选择一台部署就可以了(Hive仅仅是一个客户端而已)
在这里我们选用的版本是hive-1.1.0-cdh5.7.0
解压
$>cd /opt/software/
$>tar -zxvf hive-1.1.0-cdh5.7.0.tar.gz -C /opt/app/
$>cd /opt/app
配置到系统环境变量
$>vi /etc/profile
export HIVE_HOME=/opt/app/hive-1.1.0-cdh5.7.0
export PATH=$HIVE_HOME/bin:$PATH
生效环境变量
$>source /etc/profile
hive-env.sh
HADOOP_HOME=/opt/app/hadoop-2.6.0-cdh5.7.0
hive-site.xml
<configuration>
<!-- 配置连接串 -->
<property>
<name>javax.jdo.option.ConnectionURL</name>
<!-- 数据库名称:zhaotao_hive -->
<!-- createDatabaseIfNotExist=true:当数据库不存在的时候,自动帮你创建 -->
<value>jdbc:mysql://localhost:3306/zhaotao_hive?createDatabaseIfNotExist=true</value>
</property>
<!-- mysql的driver类 -->
<property>
<name>javax.jdo.option.ConnectionDriverName</name>
<value>com.mysql.jdbc.Driver</value>
</property>
<!-- 用户名 -->
<property>
<name>javax.jdo.option.ConnectionUserName</name>
<value>root</value>
</property>
<!-- 密码 -->
<property>
<name>javax.jdo.option.ConnectionPassword</name>
<value>root</value>
</property>
</configuration>
拷贝mysql驱动到$HIVE_HOME/lib/
版本:5.1.27
执行hive
$>bin/hive
使用默认Derby数据库会遇到的问题
采用derby情况下,有一个值得注意的问题:
默认情况下,启动一个hive之后,再打开一个窗口之后,启动第二个会进行报错
报错信息:
java.sql.SQLException: Unable to open a test connection to the given database. JDBC url = jdbc:derby:;databaseName=metastore_db;create=true, username = APP. Terminating connection pool (set lazyInit to true if you expect to start your database after your app). Original Exception: ------
原因:derby是单session(即不能多客户端对其进行访问,只能当前窗口有效)
Hive简单入门
创建emp表
hive>create table emp(
empno int, ename string, job string, mgr int, hiredate string, sal double, comm double, deptno int
)row format delimited fields terminated by '\t';
导入数据
hive>load data local inpath '/opt/data/emp.txt' overwrite into table emp;
hive>select * from emp;
数据导入成功:
进入mysql查看相关数据
mysql>use zhaotao_hive;
mysql>select * from TBLS \G;
mysql>select * from DBS \G;
mysql>select * from COLUMNS_V2 \G;
查出的结果如下:
*************************** 1. row ***************************
CD_ID: 6
COMMENT: NULL
COLUMN_NAME: comm
TYPE_NAME: double
INTEGER_IDX: 6
*************************** 2. row ***************************
CD_ID: 6
COMMENT: NULL
COLUMN_NAME: deptno
TYPE_NAME: int
INTEGER_IDX: 7
*************************** 3. row ***************************
CD_ID: 6
COMMENT: NULL
COLUMN_NAME: empno
TYPE_NAME: int
INTEGER_IDX: 0
*************************** 4. row ***************************
CD_ID: 6
COMMENT: NULL
COLUMN_NAME: ename
TYPE_NAME: string
INTEGER_IDX: 1
*************************** 5. row ***************************
CD_ID: 6
COMMENT: NULL
COLUMN_NAME: hiredate
TYPE_NAME: string
INTEGER_IDX: 4
*************************** 6. row ***************************
CD_ID: 6
COMMENT: NULL
COLUMN_NAME: job
TYPE_NAME: string
INTEGER_IDX: 2
*************************** 7. row ***************************
CD_ID: 6
COMMENT: NULL
COLUMN_NAME: mgr
TYPE_NAME: int
INTEGER_IDX: 3
*************************** 8. row ***************************
CD_ID: 6
COMMENT: NULL
COLUMN_NAME: sal
TYPE_NAME: double
INTEGER_IDX: 5
8 rows in set (0.00 sec)
CD_ID代表emp那张表
索引从0开始,一一对应创建表时字段的先后顺序
这个编号很重要,如果搞反了,数据很可能就会查不出来
所以每一个字段 对应的字段名称、数据类型以及所处的index 一定不能写错
查看HDFS上相关数据
$>hadoop fs -ls /user/hive/warehouse
$>hadoop fs -ls /user/hive/warehouse/emp
$>hadoop fs -text /user/hive/warehouse/emp/emp.txt