Hive是一个基于Hadoop的数据仓库工具, 可以将结构化的数据文件映射为一张表, 并提供类似于SQL的查询功能。
Hive本身并不存储和处理数据,更像是一个接口,存储由HDFS实现,处理数据由MapReduce实现。简单来说,Hive可以将sql语句转换为MapReduce任务, 在HDFS上进行数据查询。
Hive的特点
- Hive采用类SQL开发,简单容易上手,避免了编写MapReduce的工作
- Hive执行延迟比较高,无法胜任实时的工作(OLTP),大多用于数据分析工作(OLAP)。
- Hive擅长处理大规模的数据
Hive系统架构
(图源:https://zhuanlan.zhihu.com/p/25608332)
Hive主要由以下三个模块组成:
- 用户接口模块,含CLI、HWI、JDBC、Thrift Server等,用来实现对Hive的访问。CLI是Hive自带的命令行界面;HWI是Hive的一个简单网页界面;JDBC、ODBC以及Thrift Server可向用户提供进行编程的接口,其中Thrift Server是基于Thrift软件框架开发的,提供Hive的RPC通信接口。
- 驱动模块(Driver),含编译器、优化器、执行器等,负责把HiveQL语句转换成一系列MR作业,所有命令和查询都会进入驱动模块,通过该模块的解析变异,对计算过程进行优化,然后按照指定的步骤执行。
- 元数据存储模块(Metastore),是一个独立的关系型数据库,通常与MySQL数据库连接后创建的一个MySQL实例,也可以是Hive自带的Derby数据库实例。此模块主要保存表模式和其他系统元数据,如表的名称、表的列及其属性、表的分区及其属性、表的属性、表中数据所在位置信息等。
Hive工作原理
接下来,我们使用一个小例子来理解Hive如何将sql语句转换为MapReduce任务。
1. SQL转换为MapReduce实现连接操作
需求:将两个表的数据使用uid连接起来。
SELECT name, orderid FROM User u JOIN Order o ON u.uid=o.uid;
(图源:https://zhuanlan.zhihu.com/p/25608332)
上图可以很好地解释从数据层面上看,sql命令是如何转换为MapReduce任务的。
- 两种表进行了join命令,而join on所用的uid正是两个map任务中的key。同时,将表中的其他数据连同各个表的标识id放到value中。
- 通过这种key的选择方式,就可以用shuffle将相同key的不同表的数据聚合在一起。
- 通过shuffle操作后,相同key的数据被聚合到一起,接下来使用reduce把不同表的数据做整合就得到了最后的查询结果。
2. SQL转换为MapReduce实现分组操作
需求:对一张表的数据进行分组,将同一个rank和level的数据分为一组。
SELECT rank,level,count(*) as value FROM score GROUP BY rank,level;
- sql进行了group by,对rank和level进行分组,也就是说将这两列组合起来当作key,得到像<A, 1>的格式。
- value记录该数据的出现次数。
- 使用shuffle操作,将相同key的数据分到一起,实现了分组效果。
- 使用reduce操作,将数据进行聚合累加得到最后结果。
3. Hive工作流程
Hive的工作流程可以被归纳成下图。
(图源:https://cwiki.apache.org/confluence/display/Hive/Design)
上面的的每一步流程对应下面的文字流程
- 用户提交查询任务给Driver。
- Driver将查询任务给编译器,并请求返回一个plan。
- 编译器向MetaStore获取必要的元数据。
- MetaStore返回编译器请求的元数据。
- 编译器生成多个stage的DAG作为plan,并将plan交给Driver。每个stage代表着一个map/reduce任务,或一个元数据操作,或一个HDFS操作。这相当于做了一套job的流水线。在Map stage中,plan包含了Map Operator Tree; 在Reduce stage中,plan包含了Reduce Operator Tree。
- Driver上交plan给执行器去执行,获取元数据信息,提交给JobTracker或者ResourceManager去处理该任务,任务会直接读取HDFS中文件进行相应的操作。
- 获取执行的结果。
- 取得并返回执行结果。
4. SQL转换为MR的具体流程
- 在编译器中,用Antlr语言识别工具对HQL的输入进行词法和语法解析,将HQL语句转换成抽象语法树(AST Tree)的形式;
- 遍历抽象语法树,转化成QueryBlock查询块。因为AST结构复杂,不方便直接翻译成MR算法程序。其中QueryBlock是一条最基本的SQL语法组成单元,包括输入源、计算过程、和输入三个部分;
- 遍历QueryBlock,生成OperatorTree(操作树),OperatorTree由很多逻辑操作符组成,如TableScanOperator、SelectOperator、FilterOperator、JoinOperator、GroupByOperator和ReduceSinkOperator等。这些逻辑操作符可在Map、Reduce阶段完成某一特定操作;
- Hive驱动模块中的逻辑优化器对OperatorTree进行优化,变换OperatorTree的形式,合并多余的操作符,减少MR任务数、以及Shuffle阶段的数据量;
- 遍历优化后的OperatorTree,根据OperatorTree中的逻辑操作符生成需要执行的MR任务;
- 启动Hive驱动模块中的物理优化器,对生成的MR任务进行优化,生成最终的MR任务执行计划;
- 最后,有Hive驱动模块中的执行器,对最终的MR任务执行输出。
5. Hive HA基本原理
在实际应用中,Hive也暴露出不稳定的问题,在极少数情况下,会出现端口不响应或进程丢失问题。Hive HA(High Availablity)可以解决这类问题。
在Hive HA中,在Hadoop集群上构建的数据仓库是由多个Hive实例进行管理的,这些Hive实例被纳入到一个资源池中,由HAProxy提供统一的对外接口。客户端的查询请求,首先访问HAProxy,由HAProxy对访问请求进行转发。HAProxy收到请求后,会轮询资源池中可用的Hive实例,执行逻辑可用性测试。
如果某个Hive实例逻辑可用,就会把客户端的访问请求转发到Hive实例上;
如果某个实例不可用,就把它放入黑名单,并继续从资源池中取出下一个Hive实例进行逻辑可用性测试。
对于黑名单中的Hive,Hive HA会每隔一段时间进行统一处理,首先尝试重启该Hive实例,如果重启成功,就再次把它放入资源池中。
由于HAProxy提供统一的对外访问接口,因此,对于程序开发人员来说,可把它看成一台超强“Hive”。
参考:
https://zhuanlan.zhihu.com/p/25608332
https://cwiki.apache.org/confluence/display/Hive/Design