下图是 hive 系统的整体结构图
Hive 体系结构
上图显示了 Hive 的主要组件以及 Hive 跟 Hadoop 的交互过程,这些组件分别是:
UI:用户提交查询和其他操作到系统的用户接口。
Driver:接收查询的组件,负责 session 管理,提供基于 JDBC/ODBC 接口的执行和数据拉取 API。
Compiler:解析查询,对查询的不同部分做语法分析,生成执行计划。
Metastore:存储数据仓库中所有数据的结构信息,包括列名和列的类型信息;也负责数据读写的序列化和反序列化,以及定位数据对应的 HDFS 文件。
Execution Engine - 执行具体的执行计划。执行计划是一个状态的有向无环图(DAG),执行引擎管理图中状态的依赖关系,并进行调度。
Hive 数据模型
Hive 把数据组织成如下三级结构:
- Tables
- Partitions
- Buckets
Hive 除了支持基础类型之外,还支持数组、maps 和用户自定义类型。Hive 中用户是通过实现自己的对象 inspector 接口来自定义列类型以及他们的序列化逻辑。
元数据存储
Metastore 提供了两个非常重要但常常被忽略的特性:数据抽象和数据发现。数据抽象使得对数据的解释在表创建的时候就已经提供好了,之后每次查询都可以复用。
元数据对象
- Database
- Table
- Partition
元数据实现方案
Metastore 有两种实现方案:基于数据库的和基于文件的。
- 基于数据库的方案使用 DataNucleus 实现,该方案的好处是可以查询元数据,坏处是会有元数据同步和扩展的问题。
- 基于文件的方案的问题是没有一个很好的实现方法。
所以最终选择了基于关系数据库的 metastore 方案。
metastore 的访问有嵌入式和远程调用两种方式,远程调用是通过 Thrift 服务实现的,这样可以兼容非 Java 客户端;对于 Java 客户端可以直接使用嵌入方式。
Hive 查询语言
HiveQL 是一种类 SQL 查询语言,它在建表、加载数据和查询上大量模仿 SQL 语法。
HiveQL 支持嵌入用户自定义的 map-reduce 脚本,通过这些脚本可以在标准输入中按行读取数据再按行输出数据到标准输出。
另一个 HiveQL 的特性是多表插入,如果多个查询访问的是相同数据,只需要做一次数据扫描操作。
编译器
编译组件由下面四部分组成:
- Parser
- Semantic Analyser
这步中会做类型检查和类型的隐式转换;
对于涉及到划分的表,这里会收集所有的表达式,为后面的划分剪枝做准备;
这个步骤也会收集查询的指定采样。
- Logical Plan Generator
逻辑计划中的操作大体分为两类,一类是关系代数操作(filter、join 等),一类是 Hive 特有的操作(像 reduceSink 操作),这类特有的操作后续会被转换成 map-reduce 任务。
这个步骤中还会做一些查询优化的事情,比如:
- 把一系列 join 操作转换成一个单独的 multi-way join 操作
- 为 group by 执行一个 map-side 偏序聚合
- 把 group by 切分成两阶段来消除 reducer 的性能瓶颈问题
- Query Plan Generator
这个步骤中遍历逻辑计划树,把操作逐个分解成可以提交给 Hadoop 集群 map-reduce 框架的任务。查询计划也包括必要的采用和划分任务,最终这个计划被序列化到一个文件中。
翻译自:https://cwiki.apache.org/confluence/display/Hive/Design#