这是我参与8月更文挑战的第8天,活动详情查看:8月更文挑战
基本架构
Hive 对外提供了三种访问方式,包括 WebUI 、 CLI ( ClientLineInterface )和 Thrift 协议(支持 JDBC/ODBC ),而在 Hive 后端,主要由三个服务组件构成:
Driver
与关系型数据库的查询引擎类似, Driver 实现了 SQL 解析,生成逻辑计划、物理计划、査询优化与执行等,它的输入是 SQL 语句,输出为一系列分布式执行程序(可以为 MapReduce 、 Tez 或 Spark 等)。
Metastore
HiveMetastore 是管理和存储元信息的服务,它保存了数据库的基本信息以及数据表的定义等,为了能够可靠地保存这些元信息, HiveMetastore 一般将它们持久化到关系型数据库中,默认采用了嵌入式数据库 Derby ,用户可根据需要启用其他数据库,比如 MySQL 。
Hadoop
Hive 依赖于 Hadoop ,包括分布式文件系统 HDFS 、分布式资源管理系统 YARN 以及分布式计算引擎 MapReduce , Hive 中的数据表对应的数据存放在 HDFS 上,计算资源由 YARN 分配,而计算任务则来自 MapReduce 引擎。
部署模式
根据 Metastore 的运行方式不同,可将 Hive 分成三种部署模式
- 嵌入式模式: Metastore 和数据库( Derby )两个进程嵌入到 Driver 中,当 Driver 启动时会同时运行这两个进程,一般用于测试.
- 本地模式: Driver 和 Metastore 运行在本地,而数据库(比如 MYSQL )启动在个共享节点上。
- 远程模式: Metastore 运行在单独一个节点上,被其他所有服务共享。
工作流程
Hive 建立在 Hadoop 之上,那么它和 Hadoop 之间是如何工作的呢?
接下来,通过一张图来描述,具体如图所示。
接下来,针对图中 Hive 和 Hadoop 之间的工作过程进行简单说明,具体如下。
- UI 将执行的査询操作发送给 Driver 执行。
- Driver 借助查询编译器解析查询,检查语法和查询计划或查询需求
- 编译器将元数据请求发送到 Metastore
- 编译器将元数据作为对编译器的响应发送出去
- 编译器检査需求并将计划重新发送给 Driver 。
至此,查询的解析和编译已经完成。
- Driver 将执行计划发送给执行引擎执行 Job 任务
- 执行引擎从 DataNode 上获取结果集,并将结果发送给 UI 和 Driver 。
查询引擎
Hive最初是构建在 MapReduce 计算引擎之上的,但随着越来越多的新型计算引擎的出 现, Hive 也逐步支持其他更高效的 DAG 计算引擎,包括 Tez 和 Spark 等,用户可个性化指定每个 HQL 的执行引擎。
相比于 MapReduce 计算引擎,新型 DAG 计算引擎采用以下优化机制让 HQL 具有更高的执行性能:
- 避免借助分布式文件系统交换数据而减少不必要的网络和磁盘 IO 。
- 将重复使用的数据缓存到内存中以加速读取效率。
- 复用资源直到HQL运行结束(比如在 Spark, Executor 一旦启用后不会释放,直到所有任务运行完成)。
实践
在Hive中运行以下HQL,在该HQL中,3个表进行连接操作,并按照 state 维度进行聚集操作
SELECT a.state, COUNT(*), AVERAGE(c.price)
FROM a JOIN b
ON (a.id = b.id)
JOIN c ON (a.itemid = c.itemid)
GROUP BY a.state
- 如果采用 MapReduce 计算引擎,该 HQL 最终被转换成 4 个 MapReduce 作业,它们之间通过分布式文件系统 HDFS 交换数据,并最终由一个 MapReduce 作业将结果返回。在该计算过程中,中间结果要被前一个作业写入 HDFS (需要写三个副本),并由下一个作业从 HDFS 读取数据,并进一步处理。
- 如果采用类似 Tez 或 Spark 的 DAG 计算引擎,该 HQL 最终仅被转换成 1 个应用程序(得益于 DAG 引擎的通用性),该作业中不同算子的数据交换可直接通过本地磁盘或者网络进行,因而磁盘和网络 IO 开销较小,性能会更高。