hive的sql语句是怎么运行的
步骤组件职责1. 提交接收用户查询2-5. 编译与优化编译器 + 元存储解析SQL、验证元数据、生成并优化逻辑/物理计划6. 执行执行引擎 + YARN分布式执行任务(MapReduce/Tez/Spark)7. 取结果Driver获取结果并返回给UIHive 本身不存储和处理数据:数据存储在 HDFS 上,计算由 MapReduce/Tez/Spark 完成。Hive 只是一个“翻译官”和“调度
·
Hive SQL 的运行机制与传统的 MySQL 等数据库完全不同,其核心在于将 SQL 查询转换成一个或多个 MapReduce(或 Tez/Spark)任务,并在 Hadoop 集群上分布式执行。
下面我将详细分解 Hive SQL 语句的运行步骤,并用一个通俗的比喻帮助你理解。
核心思想:编译与执行
Hive 处理 SQL 的过程可以大致分为两个阶段:
- 编译阶段:将 SQL 字符串转换为 MapReduce 任务蓝图。
- 执行阶段:在 Hadoop 集群上执行这个 MapReduce 任务。
详细步骤分解
第 1 步:UI 提交查询
用户通过Hive 命令行、JDBC/ODBC 客户端(如 Beeline)或 Hue 等工具向 Hive 提交一条 SQL 语句。
第 2 步:编译器(Compiler)进行词法、语法解析
- 词法分析 & 语法分析:Hive 会像所有编程语言编译器一样,将 SQL 字符串拆分成一个个的“单词”(Token),然后检查其是否符合 SQL 语法规则。例如,检查
SELECT、FROM等关键字的使用是否正确。 - 语义分析:检查语句的合法性。例如:
- 查询的表
tbl是否存在? - 查询的列
col在表tbl中是否存在? - 用户是否有权限执行这个查询?
- 这些操作会去查询 Hive Metastore。
- 查询的表
第 3 步:编译器生成逻辑执行计划
编译器会根据解析后的信息生成一个抽象语法树。然后,根据 Hive 的逻辑执行计划规则,将 AST 转换为一个逻辑执行计划。这是一个由逻辑操作符组成的树,描述了需要执行的操作,但还不涉及具体的计算引擎。
- 常见逻辑操作符:
TableScanOperator:扫描表,读取数据。FilterOperator:执行过滤(如WHERE条件)。JoinOperator:执行表连接(JOIN)。SelectOperator:选择投影(SELECT后面的字段)。GroupByOperator:执行分组聚合(GROUP BY)。ReduceSinkOperator:这是一个关键操作符,它标志着数据即将被重新分区,为后续的Shuffle和Reduce阶段做准备。
第 4 步:逻辑计划优化
编译器会应用一系列的优化规则对逻辑执行计划进行优化,目的是生成一个更高效的执行计划。
- 谓词下推:尽早地执行过滤操作,减少后续处理的数据量。例如,将
WHERE条件推到JOIN操作之前。 - 列值裁剪:只读取查询中需要用到的列,而不是读取整行数据。这在列式存储(如 ORC, Parquet)中效果尤其显著。
- 多路连接优化:优化多个表的
JOIN顺序,减少中间结果集的大小。
第 5 步:编译器生成物理执行计划
优化后的逻辑计划会被转换成物理执行计划。这时,逻辑操作符会被转换为对应的物理操作符,并明确指定使用哪种计算引擎(如 MapReduce、Tez 或 Spark)。
- 如果底层是 MapReduce,物理计划就会描述出哪些步骤在
Map阶段执行,哪些在Reduce阶段执行,以及如何序列化、反序列化数据等。 - 如果底层是 Tez,物理计划会变成一个由多个顶点和有向边组成的 DAG,描述更复杂的任务依赖关系,比 MapReduce 的效率更高。
第 6 步:执行引擎执行任务
- Driver:Hive 的驱动器(Driver)接收到物理执行计划。
- 提交任务:Driver 将物理计划提交给选定的执行引擎(如 YARN)。
- YARN 调度:YARN 的 ResourceManager 接收任务请求,分配 Container,并在 NodeManager 上启动 Application Master。
- 运行 MapReduce/Tez/Spark 任务:Application Master 根据物理计划向 ResourceManager 申请资源,并启动相应的 MapTask 和 ReduceTask(对于 MapReduce 引擎)。
- Map 阶段:各个 Mapper 读取 HDFS 上的数据块,进行映射、过滤、排序等操作,输出中间结果。
- Shuffle 阶段:将 Map 阶段的输出按照 Key 进行分区、排序,然后通过网络传输到对应的 Reducer 节点。
- Reduce 阶段:各个 Reducer 对收到的数据进行最终的聚合、计算等操作,并将结果写入 HDFS。
第 7 步:获取并返回结果
- 对于
SELECT查询,执行引擎(如 MapReduce)会将最终结果写入一个临时文件。 - Hive Driver 会从该临时文件中读取数据,并通过 UI 返回给用户。
- 对于
INSERT语句,结果会直接写入目标表所在的 HDFS 路径。
一个简单的比喻
想象一下你是一家公司的老板(用户),要统计所有部门的总工资(SQL查询)。
- 提交需求:你写了一张需求单(
SELECT dept, sum(salary) FROM employee GROUP BY dept;)交给助理(Hive UI)。 - 助理分析:助理(编译器)看懂你的需求后,发现需要:
- 去档案室(HDFS)拿所有员工的档案(TableScan)。
- 按部门分组(GroupBy)。
- 计算每个部门的工资总和(Sum)。
- 制定计划:助理觉得一个个看太慢,他制定了一个并行化方案(物理计划):
- 派一队人(Mappers)去档案室,每人负责一摞档案,分别把自己手里的档案按部门分开,并初步算出小计。
- 再派另一队人(Reducers),第一个人只负责接收所有“销售部”的初步结果并求总和,第二个人只负责“技术部”,以此类推。
- 执行计划:助理把这个计划交给项目经理(YARN),项目经理去协调人力(Containers)执行。
- 汇总结果:最后,各个负责人(Reducers)把结果报给项目经理,项目经理汇总后交给助理,助理最终把报表(结果集)呈交给你。
总结与关键点
| 步骤 | 组件 | 职责 |
|---|---|---|
| 1. 提交 | UI (CLI, Beeline, Hue) | 接收用户查询 |
| 2-5. 编译与优化 | 编译器 + 元存储 | 解析SQL、验证元数据、生成并优化逻辑/物理计划 |
| 6. 执行 | 执行引擎 + YARN | 分布式执行任务(MapReduce/Tez/Spark) |
| 7. 取结果 | Driver | 获取结果并返回给UI |
- Hive 本身不存储和处理数据:数据存储在 HDFS 上,计算由 MapReduce/Tez/Spark 完成。Hive 只是一个“翻译官”和“调度员”。
- 元数据是核心:
CREATE TABLE这样的语句并不在 HDFS 上创建数据,只是在 Metastore(通常是 MySQL 或 PostgreSQL 数据库)中记录表的结构、位置等信息。这正是 Hive 被称为“数据仓库”工具的原因。 - 执行引擎的演进:传统的 MapReduce 因为磁盘 I/O 过多而较慢。Tez 和 Spark 作为更现代的执行引擎,通过内存计算和更优的 DAG 调度,大大提升了 Hive 的执行速度,现在已成为主流选择。你可以通过
set hive.execution.engine=tez;来设置。
更多推荐


所有评论(0)