Hive跑在YARN上为什么这么慢——Hive on MR/Tez/Spark对比
先说结论
三种引擎性能排序:Spark SQL > Hive on Tez > Hive on MapReduce。MapReduce最慢但最稳定、Tez是中间方案(比MR快2-5倍)、Spark SQL最快(比MR快10-100倍)。2025年新项目几乎都用Spark SQL了,但存量系统中Hive on Tez还非常普遍。
先把这段讲顺;面试官追问时,再展开下面的原理和细节。
详细讲解
Hive是Hadoop生态最重要的SQL引擎,但它有三种执行引擎可选:MapReduce(最老)、Tez(DAG优化)、Spark(内存计算)。在某短视频平台入行时用的是Hive on MapReduce,一个简单的COUNT(*)要跑3分钟;在某知名出海硬件品牌切到了Spark SQL(本质上是Hive on Spark的进化版),同样的查询10秒就出来了。面试官问Hive引擎选择,考的是你对三种引擎差异的理解和实际使用经验。
三种引擎核心对比
| 维度 | Hive on MR | Hive on Tez | Spark SQL |
|---|---|---|---|
| 执行模型 | Map+Reduce两阶段 | DAG(有向无环图) | DAG+内存计算 |
| 中间数据 | 全部落盘(HDFS) | 内存+落盘 | 优先内存 |
| 多Stage传递 | 通过HDFS中转 | 内存/本地磁盘 | 内存Pipeline |
| Task启动 | 每Task启动JVM | Container复用 | Executor常驻 |
| SQL优化器 | 简单规则优化 | 规则+CBO | Catalyst+AQE |
| 典型性能 | 基准 | 比MR快2-5倍 | 比MR快10-100倍 |
| 稳定性 | 最高 | 高 | 高(偶尔OOM) |
| 适用场景 | 超大规模容错 | CDH/HDP默认 | 新项目首选 |
为什么Tez比MapReduce快?
# 一个多Stage的Hive查询
# SELECT a.country, SUM(b.amount)
# FROM t1 a JOIN t2 b ON a.id = b.id
# WHERE a.dt = '2024-01-15'
# GROUP BY a.country ORDER BY SUM(b.amount) DESC
# MapReduce执行(3个独立的MR Job):
# Job 1: Scan + Filter ==> 写HDFS
# Job 2: 读HDFS ==> JOIN ==> 写HDFS
# Job 3: 读HDFS ==> GROUP BY + ORDER BY ==> 写HDFS
# 3次写HDFS + 3次读HDFS = 6次磁盘IO
# Tez执行(1个DAG,3个Vertex):
# Vertex 1: Scan + Filter
# ↓ (内存/本地磁盘传递,不写HDFS)
# Vertex 2: JOIN
# ↓ (内存/本地磁盘传递)
# Vertex 3: GROUP BY + ORDER BY ==> 写HDFS
# 只有最终结果写HDFS,中间不落盘
# 减少了4次HDFS IO,所以快2-5倍
Tez的核心优化:① DAG执行模型——多个Stage在一个DAG里执行,中间结果不写HDFS;② Container复用——同一个Container可以执行多个Task,省了JVM启动开销;③ 数据本地化传递——上游Vertex的输出直接传给下游Vertex,不需要通过HDFS中转。
为什么Spark SQL比Tez还快?
Spark SQL在Tez的基础上又多了三个优势:
① 更强的内存计算:Tez的中间数据虽然不写HDFS,但还是会溢出到本地磁盘。Spark优先把中间数据存在内存里,溢出是最后的手段。内存读写比磁盘快100倍。
② Catalyst优化器:Spark SQL有业界最强的SQL优化器之一——Catalyst。它做的优化包括谓词下推、列裁剪、JOIN重排序、子查询展开等,比Hive的规则优化全面得多。
③ AQE(Adaptive Query Execution):Spark 3.0+引入的运行时优化——根据实际数据量动态调整Shuffle分区数、自动转换Join策略、自动处理数据倾斜。这些是编译时无法做到的优化。
-- AQE的三大能力(Spark 3.0+)
-- 1. 自动合并小Partition
-- Shuffle后某些Partition只有几KB
-- AQE自动把多个小Partition合并成一个
SET spark.sql.adaptive.coalescePartitions.enabled = true;
-- 2. 自动转换Join策略
-- 编译时估计右表100MB用了Sort Merge Join
-- 运行时发现过滤后只有5MB,自动改成Broadcast Join
SET spark.sql.adaptive.localShuffleReader.enabled = true;
-- 3. 自动处理数据倾斜
-- 发现某个Partition是其他的10倍
-- 自动拆分大Partition并行处理
SET spark.sql.adaptive.skewJoin.enabled = true;
-- 在出海硬件品牌,开启AQE后:
-- 数据倾斜作业从40分钟降到8分钟
-- 整体ETL稳定性显著提升
实战经验:三种引擎的实际性能对比
在某短视频平台和某知名出海硬件品牌,我实际用过三种引擎。同样逻辑的ETL作业在不同引擎上的执行时间:
| 查询类型 | Hive on MR | Hive on Tez | Spark SQL |
|---|---|---|---|
| 简单COUNT(*) | 3分钟 | 40秒 | 8秒 |
| 带过滤的聚合 | 10分钟 | 3分钟 | 30秒 |
| 两表JOIN+聚合 | 45分钟 | 12分钟 | 5分钟 |
| 复杂ETL(5 Stage) | 3小时 | 50分钟 | 15分钟 |
| 数据倾斜作业 | 4小时(超时) | 1.5小时 | 8分钟(AQE) |
可以看到Spark SQL在所有场景下都是最快的,尤其是数据倾斜场景(AQE的贡献)。Tez比MR快3-5倍,但比Spark还是差一个数量级。
什么时候还需要用Hive on MR?
2025年了,还有人用Hive on MapReduce吗?答案是:有,但越来越少。
还在用MR的场景:① 极大规模数据处理(PB级)——MR的容错比Spark更强,不怕OOM;② 存量系统迁移成本高——改引擎需要测试所有作业的兼容性;③ 公司没有Spark运维能力——MR更简单不容易出问题。
应该迁到Spark的场景:几乎所有新项目。Spark SQL是Hive的上位替代——更快、更强、社区更活跃。即使暂时不迁移,至少应该升级到Hive on Tez作为过渡。
面试高频追问
追问一:Hive on Spark和Spark SQL有什么区别?
Hive on Spark是让Hive的SQL引擎用Spark做执行引擎(Hive翻译SQL,Spark执行)。Spark SQL是Spark自己的SQL引擎(Catalyst翻译SQL,Spark执行)。Spark SQL有更强的优化器(Catalyst+AQE),性能通常比Hive on Spark好20-30%。大部分公司直接用Spark SQL而不是Hive on Spark。
追问二:Tez还有人用吗?
CDH/HDP生态的公司还在大量使用Hive on Tez。Tez是Hortonworks主推的引擎,和Hive深度集成,稳定性很好。对于不想从Hive迁移到Spark SQL的公司,Tez是一个低成本的性能提升方案(不需要改SQL,只需要换引擎配置)。
追问三:LLAP是什么?
LLAP(Live Long and Process)是Hive 2.0+引入的常驻服务——在每个节点上运行一个LLAP Daemon,缓存热数据在内存中,提供亚秒级的交互式查询。可以理解为'Hive版的Presto'——适合BI报表的低延迟查询。但LLAP的使用和运维比较复杂,很多公司选择直接用Presto/Trino替代。
总结
Hive引擎选择面试讲清楚三点:① 三种引擎的核心差异(MR全落盘、Tez用DAG减少落盘、Spark内存计算+Catalyst+AQE);② 性能对比数据(MR基准、Tez快3-5倍、Spark快10-100倍);③ 选型建议(新项目用Spark SQL、存量系统升级到Tez做过渡、PB级超大规模可以保留MR)。能讲出自己在不同公司使用不同引擎的对比经验和迁移效果,面试官会觉得你有全面的技术视野。
下一篇聊HDFS的数据迁移:DistCp拷贝数据拷了一夜——跨集群数据同步怎么做?
你们Hive用的什么引擎?有没有从MR迁移到Spark?评论区聊聊~
关注「Wood聊大数据」| 9年大数据老兵,聊技术、聊职场、聊成长