<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Tez on My Learning Notes</title><link>https://eleanora-lyh.github.io/MyLearningNotes/tags/tez/</link><description>Recent content in Tez on My Learning Notes</description><generator>Hugo -- gohugo.io</generator><language>zh-cn</language><lastBuildDate>Thu, 04 Jun 2026 06:54:22 +0000</lastBuildDate><atom:link href="https://eleanora-lyh.github.io/MyLearningNotes/tags/tez/index.xml" rel="self" type="application/rss+xml"/><item><title>【八】Hive 计算引擎：MapReduce / Tez / Spark 对比与选型</title><link>https://eleanora-lyh.github.io/MyLearningNotes/posts/hive/08hive%E8%AE%A1%E7%AE%97%E5%BC%95%E6%93%8E/</link><pubDate>Tue, 26 May 2026 21:37:59 +0800</pubDate><guid>https://eleanora-lyh.github.io/MyLearningNotes/posts/hive/08hive%E8%AE%A1%E7%AE%97%E5%BC%95%E6%93%8E/</guid><description>&lt;h1 id="一什么是计算引擎"&gt;一、什么是计算引擎
&lt;/h1&gt;&lt;p&gt;计算引擎是大数据处理中的核心软件框架，它负责对海量数据执行具体的计算任务，是数据从“存储”到“价值”的加工车间。&lt;/p&gt;
&lt;p&gt;它的核心职责是：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;资源管理&lt;/strong&gt;：协调和管理集群中的CPU、内存等计算资源。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;任务调度&lt;/strong&gt;：将用户编写的计算逻辑（如一个复杂的分析或转换任务）拆解成多个小任务，并合理分配到集群的各个节点上并行执行。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;执行计算&lt;/strong&gt;：在分配的节点上真正执行代码，完成数据的过滤、聚合、关联、机器学习等操作。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;为什么需要它？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;它抽象了底层分布式计算的复杂性（如容错、并行、通信），让开发者可以像编写单机程序一样，通过高级API（如SQL、Python、Java）来处理TB/PB级的数据。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;一个简单类比&lt;/strong&gt;：&lt;/p&gt;
&lt;p&gt;把数据比作食材，数据存储（如HDFS）是&lt;strong&gt;仓库&lt;/strong&gt;，而计算引擎（如Spark、Flink）就是&lt;strong&gt;厨房和厨师&lt;/strong&gt;，负责按照菜谱（你的程序）将食材加工成菜肴（分析结果）。&lt;/p&gt;
&lt;p&gt;在企业数据平台里，计算需求通常会自然聚成三类：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;三类主流大数据计算引擎举例&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;批处理引擎&lt;/strong&gt;：&lt;strong&gt;Apache Spark&lt;/strong&gt;（核心，速度快，通用），&lt;strong&gt;MapReduce&lt;/strong&gt;（Hadoop原生，较慢但经典）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;流处理引擎&lt;/strong&gt;：&lt;strong&gt;Apache Flink&lt;/strong&gt;（流批一体，延迟极低），&lt;strong&gt;Apache Spark Streaming&lt;/strong&gt;（微批处理）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;查询引擎&lt;/strong&gt;：&lt;strong&gt;Apache Hive&lt;/strong&gt;（将SQL翻译成MapReduce/Spark/Tez任务），&lt;strong&gt;Presto/Trino&lt;/strong&gt;（交互式快速查询）&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;三类计算引擎的定义是根据下面的指标划分的&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;数据边界不同&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;批处理：数据集是&lt;strong&gt;有界&lt;/strong&gt;的（比如“昨天全量日志”“历史订单全量”），可以等数据齐了再算。&lt;/li&gt;
&lt;li&gt;流处理：数据是&lt;strong&gt;无界&lt;/strong&gt;的（事件持续产生），系统必须边来边算、一直跑。&lt;/li&gt;
&lt;li&gt;查询：数据通常已落地（湖/仓/OLAP），重点是“对已存在数据做&lt;strong&gt;即席查询&lt;/strong&gt;”。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;时效/延迟目标不同&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;批：分钟~小时级（吞吐优先、成本友好）。&lt;/li&gt;
&lt;li&gt;流：毫秒~秒级（低延迟 + 连续输出）。&lt;/li&gt;
&lt;li&gt;查：秒级甚至亚秒级（交互体验优先）。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;运行形态不同&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;批：典型是“提交一次作业 → 跑完结束”。&lt;/li&gt;
&lt;li&gt;流：典型是“提交一个长期运行作业 → 持续处理”。&lt;/li&gt;
&lt;li&gt;查：典型是“每个 SQL/请求是一条短查询”，并发高、响应快。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;状态与一致性处理方式不同&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;批：很多时候“状态”隐含在 shuffle/sort 和中间结果里，失败可重跑整批。&lt;/li&gt;
&lt;li&gt;流：必须显式维护&lt;strong&gt;跨事件状态&lt;/strong&gt;（窗口、聚合、会话、去重），需要 checkpoint/一致性语义。Apache Flink Documentation 明确把 Flink定位为在有界/无界数据流上做有状态计算，并强调 exactly-once、事件时间等能力。&lt;/li&gt;
&lt;li&gt;查：倾向“每次查询尽量无状态/弱状态”，靠列式、向量化、谓词下推、并行执行把单次查询做到极快。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h1 id="二三类引擎分别负责什么功能"&gt;二、三类引擎分别“负责什么功能”？
&lt;/h1&gt;&lt;h3 id="a-批处理引擎batch-engine算全量大规模离线作业"&gt;A. 批处理引擎（Batch Engine）——“算全量/大规模离线作业”
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;核心功能&lt;/strong&gt;：对&lt;strong&gt;有界&lt;/strong&gt;数据集进行一次性计算，强调吞吐、可扩展、成本效率。&lt;br&gt;
典型任务：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;离线 ETL/ELT（ODS→DWD→DWS→ADS 的批加工）&lt;/li&gt;
&lt;li&gt;T+1 报表、历史回溯重算（backfill）&lt;/li&gt;
&lt;li&gt;大规模 join、聚合、排序、离线特征工程、离线训练数据准备&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;典型特征&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;作业是“短生命周期”：提交→执行→结束&lt;/li&gt;
&lt;li&gt;更能容忍较高延迟，换取更高吞吐/更低成本&lt;/li&gt;
&lt;li&gt;容错常见方式：失败重跑整批或重跑失败 stage&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;常见代表（举例）&lt;/strong&gt;：MapReduce、Spark（Batch）、Hive on Tez/Spark 等（按生态演进不同）。&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id="b-流处理引擎stream-engine事件来了立刻算持续产出结果"&gt;B. 流处理引擎（Stream Engine）——“事件来了立刻算、持续产出结果”
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;核心功能&lt;/strong&gt;：对&lt;strong&gt;无界&lt;/strong&gt;数据流做持续计算，强调&lt;strong&gt;低延迟 + 有状态 + 时间语义 + 一致性&lt;/strong&gt;。&lt;br&gt;
典型任务：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;实时指标/实时大屏（PV/UV、延迟、成功率）&lt;/li&gt;
&lt;li&gt;实时风控/反欺诈、实时告警&lt;/li&gt;
&lt;li&gt;会话窗口（session window）、滚动/滑动窗口聚合&lt;/li&gt;
&lt;li&gt;CDC（变更数据捕获）入湖/入仓、实时维表关联（enrichment）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;典型特征（以 Flink 的官方描述为例）&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;运行形态：长作业常驻&lt;/li&gt;
&lt;li&gt;能力侧重：有状态计算、Exactly-once 状态一致性、事件时间处理、低延迟高吞吐、checkpoint（增量检查点）等。&lt;/li&gt;
&lt;li&gt;结果输出：持续不断更新（流式 sink）&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id="c-查询交互式查询引擎query-engine--interactive-sql-engine即席问快速答"&gt;C. 查询/交互式查询引擎（Query Engine / Interactive SQL Engine）——“即席问、快速答”
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;核心功能&lt;/strong&gt;：对已落地在数据湖/数仓/多数据源的数据做&lt;strong&gt;交互式 SQL&lt;/strong&gt;，强调&lt;strong&gt;低延迟、并发、即席分析体验&lt;/strong&gt;。&lt;br&gt;
典型任务：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;BI 报表/仪表盘（高并发、秒级响应）&lt;/li&gt;
&lt;li&gt;数据分析师 ad-hoc 探索（临时 join、过滤、聚合）&lt;/li&gt;
&lt;li&gt;联邦查询：跨 Hive/湖表 + MySQL/ES/Kafka 等多源联合分析（取决于引擎）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;典型特征（以 Presto 官方首页描述为例）&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;定位：开源 SQL 查询引擎，面向数据分析；支持交互式/即席查询，目标是（可达）亚秒级性能；并强调“查询数据所在之处”、连接多种数据源、分布式内存 SQL 引擎等。&lt;/li&gt;
&lt;li&gt;作业形态：每条查询是短请求；适合高并发、多用户&lt;/li&gt;
&lt;li&gt;通常不负责复杂 ETL 流水线（更多是“读多、快查”）&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="三类引擎功能边界总结"&gt;三类引擎“功能边界”总结
&lt;/h2&gt;&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;维度&lt;/th&gt;
 &lt;th&gt;批处理引擎&lt;/th&gt;
 &lt;th&gt;流处理引擎&lt;/th&gt;
 &lt;th&gt;查询引擎（交互式）&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;主要处理对象&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;有界&lt;/strong&gt;数据集（全量/分区批）&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;无界&lt;/strong&gt;事件流（持续进入）&lt;/td&gt;
 &lt;td&gt;已落地数据（湖/仓/多源）&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;运行形态&lt;/td&gt;
 &lt;td&gt;提交一次作业→跑完结束&lt;/td&gt;
 &lt;td&gt;长期运行作业→持续处理&lt;/td&gt;
 &lt;td&gt;每条 SQL/请求一次执行&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;核心目标&lt;/td&gt;
 &lt;td&gt;吞吐、成本效率、可扩展&lt;/td&gt;
 &lt;td&gt;低延迟、状态一致性、时间语义&lt;/td&gt;
 &lt;td&gt;低延迟、并发、即席分析体验&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;状态管理&lt;/td&gt;
 &lt;td&gt;多为“批内隐式状态”，失败可重跑&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;强状态&lt;/strong&gt;（窗口/去重/会话），需 checkpoint&lt;/td&gt;
 &lt;td&gt;尽量无状态/弱状态（单查询内）&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;典型延迟&lt;/td&gt;
 &lt;td&gt;分钟~小时&lt;/td&gt;
 &lt;td&gt;毫秒~秒&lt;/td&gt;
 &lt;td&gt;秒级~亚秒（视数据与查询）&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;典型产出&lt;/td&gt;
 &lt;td&gt;离线表、宽表、汇总表、离线特征&lt;/td&gt;
 &lt;td&gt;实时指标流、告警、实时明细/宽表增量&lt;/td&gt;
 &lt;td&gt;查询结果集（给人/BI）&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;代表例子（举例）&lt;/td&gt;
 &lt;td&gt;MapReduce、Spark Batch&lt;/td&gt;
 &lt;td&gt;Flink、Storm、Kafka Streams&lt;/td&gt;
 &lt;td&gt;Presto/Trino、Impala 等&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;

 &lt;blockquote&gt;
 &lt;p&gt;说明：现实里很多系统在“流批一体/湖仓一体”趋势下会互相渗透，但&lt;strong&gt;主责&lt;/strong&gt;仍按上表分工最清晰。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="现在为什么又出现流批一体多引擎协作"&gt;现在为什么又出现“流批一体/多引擎协作”？
&lt;/h2&gt;&lt;p&gt;你会发现越来越多平台不再只选一种引擎，而是&lt;strong&gt;组合拳&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Spark 的 Structured Streaming&lt;/strong&gt;：官方文档强调它构建在 Spark SQL 引擎上，允许你用“写批处理”的方式表达流计算；默认内部用 micro-batch，把流当作一系列小批作业增量执行，并通过 checkpoint/WAL 提供端到端 exactly-once 等保证。 &lt;a class="link" href="https://spark.apache.org/docs/latest/streaming/index.html" target="_blank" rel="noopener"
 &gt;[spark.apache.org]&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Flink&lt;/strong&gt;：官方定位就是同时支持有界/无界数据流的有状态计算（把批看作有界流的一种情况）。 &lt;a class="link" href="https://flink.apache.org/zh/" target="_blank" rel="noopener"
 &gt;[flink.apache.org]&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这背后的工程现实是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;批&lt;/strong&gt;负责“把数据加工成可用形态”（治理、建模、汇总）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;流&lt;/strong&gt;负责“把最新变化尽快算出来/写进去”（实时指标、CDC 入湖）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;查&lt;/strong&gt;负责“让人/BI 快速取数”（交互式体验）&lt;br&gt;
成熟平台往往三者共存，各做各的甜区，整体成本和体验最好。&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id="三查询引擎"&gt;三、查询引擎
&lt;/h1&gt;&lt;p&gt;今天学习的是查询引擎&lt;strong&gt;Apache Hive&lt;/strong&gt;，目前Hive支持&lt;strong&gt;MapReduce、Tez和Spark&lt;/strong&gt;三种执行引擎。&lt;/p&gt;
&lt;p&gt;Hive 本质上是一个 SQL → 分布式计算任务 的翻译器，它本身不执行计算，而是把 HiveQL 解析、优化后翻译成底层引擎可执行的物理计划。Hive 从 0.x 时代一路演进到 3.x/4.x，先后支持了 &lt;strong&gt;MapReduce、Tez、Spark&lt;/strong&gt; 三种执行引擎，可通过 &lt;code&gt;hive.execution.engine&lt;/code&gt; 参数切换：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;1
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;2
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;SET&lt;/span&gt; hive.execution.engine&lt;span style="color:#f92672"&gt;=&lt;/span&gt;mr; &lt;span style="color:#75715e"&gt;-- MapReduce（已废弃）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;SET&lt;/span&gt; hive.execution.engine&lt;span style="color:#f92672"&gt;=&lt;/span&gt;tez; &lt;span style="color:#75715e"&gt;-- Tez（Hortonworks/HDP 主推）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;SET&lt;/span&gt; hive.execution.engine&lt;span style="color:#f92672"&gt;=&lt;/span&gt;spark; &lt;span style="color:#75715e"&gt;-- Spark（Cloudera/CDH 主推）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id="31-mapreduce-引擎hive-的出生引擎"&gt;3.1 MapReduce 引擎（Hive 的&amp;quot;出生&amp;quot;引擎）
&lt;/h2&gt;&lt;p&gt;Hive 把 SQL 翻译成一连串的 &lt;strong&gt;MR Job&lt;/strong&gt;：每个 Job 由一个 Map 阶段 + 一个 Reduce 阶段组成，&lt;strong&gt;中间结果必须落盘到 HDFS&lt;/strong&gt;，下一个 Job 再从 HDFS 读取。&lt;/p&gt;
&lt;h3 id="-工作原理详细数据流"&gt;① 工作原理（详细数据流）
&lt;/h3&gt;&lt;p&gt;MapReduce 是一个&lt;strong&gt;严格的两段式&lt;/strong&gt;计算模型：&lt;code&gt;Map → Shuffle → Reduce&lt;/code&gt;，每个阶段的数据流动都涉及大量磁盘 I/O。&lt;/p&gt;
&lt;h4 id="-map-端输入侧"&gt;🟦 Map 端（输入侧）
&lt;/h4&gt;&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Split 切分&lt;/strong&gt;：输入文件（HDFS 上的大文件）会被按 &lt;strong&gt;InputSplit&lt;/strong&gt;（默认与 HDFS Block 对齐，约 128MB）切分成若干份，每份对应一个 &lt;strong&gt;MapTask&lt;/strong&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Record 读取&lt;/strong&gt;：每个 MapTask 通过 &lt;code&gt;RecordReader&lt;/code&gt; 把数据按行（或按 key-value）读入 &lt;strong&gt;map() 方法&lt;/strong&gt; 进行业务处理。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;环形缓冲区（Ring Buffer）&lt;/strong&gt;：map() 的输出 &lt;strong&gt;不直接写磁盘&lt;/strong&gt;，而是先写到一块内存缓冲区（默认 100MB，由 &lt;code&gt;mapreduce.task.io.sort.mb&lt;/code&gt; 控制）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;分区 + 排序 + Spill 溢写&lt;/strong&gt;：当缓冲区使用率达到阈值（默认 80%，&lt;code&gt;mapreduce.map.sort.spill.percent&lt;/code&gt;）时，后台线程会：
&lt;ul&gt;
&lt;li&gt;按 &lt;strong&gt;Partitioner&lt;/strong&gt;（默认 &lt;code&gt;HashPartitioner&lt;/code&gt;）给每条记录打上分区号（决定将来去哪个 Reduce）；&lt;/li&gt;
&lt;li&gt;在分区内按 key 进行&lt;strong&gt;快速排序&lt;/strong&gt;；&lt;/li&gt;
&lt;li&gt;将排序后的数据&lt;strong&gt;溢写（spill）到本地磁盘&lt;/strong&gt;，形成一个个临时 spill 文件。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Merge 归并&lt;/strong&gt;：一个 MapTask 通常会产生多个 spill 文件，Map 结束时会把它们&lt;strong&gt;多路归并成一个有序的大文件&lt;/strong&gt;（按分区 + key 排序），存放在该节点的&lt;strong&gt;本地磁盘&lt;/strong&gt;（注意：不是 HDFS！），等待 Reduce 来拉取。&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id="-reduce-端拉取--聚合"&gt;🟥 Reduce 端（拉取 + 聚合）
&lt;/h4&gt;&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Shuffle（Copy 阶段）&lt;/strong&gt;：ReduceTask 启动后，会通过 HTTP 从&lt;strong&gt;所有 MapTask 节点&lt;/strong&gt;拉取属于自己分区的数据，先写入 Reduce 节点的内存缓冲区。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;内存溢写 + 再次排序&lt;/strong&gt;：内存装不下时再次 spill 到磁盘，并对数据进行&lt;strong&gt;第二轮排序&lt;/strong&gt;（保证全局有序）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Merge 归并&lt;/strong&gt;：所有 Map 端数据拉取完成后，对磁盘上的多个临时文件进行&lt;strong&gt;多路归并&lt;/strong&gt;，形成一个有序的输入流。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Reduce 计算&lt;/strong&gt;：归并后的数据&lt;strong&gt;作为 reduce() 函数的数据源&lt;/strong&gt;，按 key 分组喂给业务逻辑，最终结果&lt;strong&gt;写入 HDFS&lt;/strong&gt;。&lt;/li&gt;
&lt;/ol&gt;

 &lt;blockquote&gt;
 &lt;p&gt;📌 &lt;strong&gt;核心特征&lt;/strong&gt;：整个过程中数据要经历 &lt;strong&gt;HDFS输入文件 → Map内存溢出到本地磁盘 → Reduce读取本地文件到内存 → Reduce内存溢出到多个本地磁盘→ 合并到一个本地文件&lt;/strong&gt; 多次落盘，I/O 是性能瓶颈的根源。也就是为什么后面出现了Tez执行引擎&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;h3 id="-多-job-串行的痛点"&gt;② 多 Job 串行的痛点
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;1
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;2
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;SELECT&lt;/span&gt; a.x, &lt;span style="color:#66d9ef"&gt;SUM&lt;/span&gt;(b.y) &lt;span style="color:#66d9ef"&gt;FROM&lt;/span&gt; a 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;JOIN&lt;/span&gt; b &lt;span style="color:#66d9ef"&gt;ON&lt;/span&gt; a.id &lt;span style="color:#f92672"&gt;=&lt;/span&gt; b.id 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;GROUP&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;BY&lt;/span&gt; a.x;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;会被拆分成：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Job 1（JOIN）&lt;/strong&gt;：Map(读 a/b) → Shuffle → Reduce(关联) → &lt;strong&gt;写 HDFS 临时目录&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Job 2（GROUP BY）&lt;/strong&gt;：Map(读临时文件) → Shuffle → Reduce(聚合) → 输出&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;两个 Job 之间通过 HDFS 传递中间结果&lt;/strong&gt;，复杂 SQL 可能产生 5~10 个串行 Job，每个 Job 都要重启 JVM、重新读写 HDFS，性能极差。&lt;/p&gt;
&lt;h3 id="-优缺点"&gt;③ 优缺点
&lt;/h3&gt;&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;维度&lt;/th&gt;
 &lt;th&gt;表现&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;✅ 稳定性&lt;/td&gt;
 &lt;td&gt;极高，&amp;ldquo;慢但不死&amp;rdquo;，适合 PB 级离线批处理&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;✅ 容错性&lt;/td&gt;
 &lt;td&gt;任务失败粒度细，单 Task 失败重跑代价小&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;❌ 性能&lt;/td&gt;
 &lt;td&gt;中间结果反复落盘（本地磁盘 + HDFS），磁盘 I/O 巨大&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;❌ 启动开销&lt;/td&gt;
 &lt;td&gt;每个 Job 启动 JVM，多 Stage SQL 启动开销叠加&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;❌ DAG 表达力&lt;/td&gt;
 &lt;td&gt;只能&amp;quot;两段式&amp;quot;（Map→Reduce），复杂 SQL 必须拆成多个 Job 串行&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;

 &lt;blockquote&gt;
 &lt;p&gt;⚠️ &lt;strong&gt;Hive 2.0 起官方已标记 MR 为 deprecated，Hive 3.x 默认不再推荐使用，Hive 4.0 已彻底移除 MR 引擎支持。&lt;/strong&gt;&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="32-tez-引擎在-mr-基础上的dag-化升级"&gt;3.2 Tez 引擎（在 MR 基础上的&amp;quot;DAG 化&amp;quot;升级）
&lt;/h2&gt;&lt;h3 id="-定位与起源"&gt;① 定位与起源
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;Apache Tez 是面向大规模数据处理、支持 DAG(Directed Acyclic Graph) 作业的通用计算框架&lt;/strong&gt;，&lt;strong&gt;直接源自 MapReduce&lt;/strong&gt;——可以理解为&amp;quot;MR 的进化版&amp;quot;。它&lt;strong&gt;完全兼容 MR 的能力&lt;/strong&gt;（Map/Reduce 语义、Shuffle 语义、容错语义），但在此之上提供了&lt;strong&gt;更灵活的作业表达模型&lt;/strong&gt;，允许多种作业形式在同一集群内统一调度。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;MapReduce的固定模型&lt;/strong&gt;：一旦这个 Job 需要跨分区重分布数据，执行模式必须按&lt;code&gt;Map -&amp;gt; Shuffle/Sort -&amp;gt; Reduce&lt;/code&gt;的固定三阶段执行，导致冗余的I/O和调度开销。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;注意：这里强调的是&lt;strong&gt;一旦这个 Job 需要跨分区重分布数据&lt;/strong&gt;，如对于 group by、join、distinct、全局排序等需要按 key 汇聚数据的任务。MapReduce 对这类复杂多阶段任务的表达能力较弱，&lt;strong&gt;多个阶段往往需要拆成多个 Job&lt;/strong&gt;，通常需要经过 Shuffle/Sort，再由 Reduce 处理，并&lt;strong&gt;通过 HDFS 落盘（HDFS落盘=HDFS-&amp;gt;本地磁盘）传递中间结果，从而带来额外 I/O 和调度开销&lt;/strong&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;并不是所有任务都必须有 Reduce，也不是所有场景都必须发生完整 Shuffle。Map-only 任务可以没有 Shuffle；如果数据已经按计算 key 做了合适的分区/分桶/排序，执行引擎可能减少或避免某些 Shuffle。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Directed Acyclic Graph 有向无环图&lt;/strong&gt;：在计算引擎里，DAG 表示一个作业中，各个计算步骤之间的依赖关系图。比如 SQL：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;1
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;2
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;3
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;4
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;SELECT&lt;/span&gt; user_id, &lt;span style="color:#66d9ef"&gt;COUNT&lt;/span&gt;(&lt;span style="color:#f92672"&gt;*&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;FROM&lt;/span&gt; logs
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;WHERE&lt;/span&gt; dt &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;2026-05-27&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;AND&lt;/span&gt; event_type &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;click&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;GROUP&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;BY&lt;/span&gt; user_id;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;传统 MapReduce 更像这样：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 1
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 2
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 3
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 4
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 5
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 6
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 7
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 8
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 9
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;10
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;11
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;12
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;13
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;14
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;15
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;Map&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;：&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;各个&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;Map&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;（读&lt;/span&gt; logs&lt;span style="color:#960050;background-color:#1e0010"&gt;、过滤&lt;/span&gt; dt&lt;span style="color:#960050;background-color:#1e0010"&gt;、过滤&lt;/span&gt; event_type&lt;span style="color:#960050;background-color:#1e0010"&gt;）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;→&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;各个&lt;/span&gt;Map生成中间结果 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;→&lt;/span&gt; Map将中间结果写入本地磁盘 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Shuffle&lt;span style="color:#960050;background-color:#1e0010"&gt;：&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;按照&lt;/span&gt;user_id进行分区&lt;span style="color:#960050;background-color:#1e0010"&gt;，相同&lt;/span&gt;user_id分配到同一个 Reducer
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;→&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;各个&lt;/span&gt;Reducer &lt;span style="color:#960050;background-color:#1e0010"&gt;通过网络从各个&lt;/span&gt; Mapper &lt;span style="color:#960050;background-color:#1e0010"&gt;所在节点拉取对应分区的中间结果，合并结果&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Reduce&lt;span style="color:#960050;background-color:#1e0010"&gt;：&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Reducer &lt;span style="color:#960050;background-color:#1e0010"&gt;对相同&lt;/span&gt; &lt;span style="color:#f92672"&gt;`&lt;/span&gt;city&lt;span style="color:#f92672"&gt;`&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;的数据做最终聚合，例如&lt;/span&gt; &lt;span style="color:#f92672"&gt;`&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;COUNT&lt;/span&gt;(&lt;span style="color:#f92672"&gt;*&lt;/span&gt;)&lt;span style="color:#f92672"&gt;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;Output&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;：&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Reduce &lt;span style="color:#960050;background-color:#1e0010"&gt;结果直接写入&lt;/span&gt; HDFS&lt;span style="color:#960050;background-color:#1e0010"&gt;。&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DAG 引擎会先看到完整流程，再切分执行阶段分析，而不是每一步都机械地变成一个 MR Job（例如：哪些操作可以合并？哪里必须 Shuffle？哪里可以 pipeline？哪里可以避免落盘？哪里可以并行？）&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;1
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;2
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;3
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;4
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;Read&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;→&lt;/span&gt; Filter &lt;span style="color:#960050;background-color:#1e0010"&gt;→&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;Partial&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;Count&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;↓&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Shuffle
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;↓&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;Final&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;Count&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;→&lt;/span&gt; Outputort
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Tez的DAG模型&lt;/strong&gt;：允许你根据实际数据处理逻辑，自由定义任务节点（可以是Map、Reduce或其他处理器）和它们的依赖边。DAG 引擎相比 MapReduce 的优势在于，它能从全局依赖关系出发，把多个操作组合成更灵活的执行图，只在必要的边界进行 Shuffle 或落盘。例如，一个作业可以是 &lt;code&gt;Map -&amp;gt; Reduce&lt;/code&gt;，也可以是 &lt;code&gt;Map -&amp;gt; Map -&amp;gt; Reduce&lt;/code&gt;，甚至是多个Map的输出汇合到一个Reduce。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Tez 由 Hortonworks 主导贡献给 Apache 社区，HDP/CDP 体系（现 Cloudera CDP）默认采用。&lt;/p&gt;
&lt;h3 id="-核心抽象vertex--edge"&gt;② 核心抽象：Vertex + Edge
&lt;/h3&gt;&lt;p&gt;Tez 最关键的创新是&lt;strong&gt;把 MR 那种僵硬的 &amp;ldquo;Map + Reduce 两段式&amp;rdquo; 拆解为更细粒度的元操作&lt;/strong&gt;，重新组合成 DAG：&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;Tez 抽象&lt;/th&gt;
 &lt;th&gt;含义&lt;/th&gt;
 &lt;th&gt;类比 MR&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Vertex（顶点）&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;一个计算节点，代表一组并行执行的 Task&lt;/td&gt;
 &lt;td&gt;相当于一个 Map 阶段或 Reduce 阶段&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Vertex Input&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;Vertex 的数据输入逻辑&lt;/td&gt;
 &lt;td&gt;类比 MR 的 InputFormat&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Vertex Output&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;Vertex 的数据输出逻辑&lt;/td&gt;
 &lt;td&gt;类比 MR 的 OutputFormat&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Sorting&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;排序原语&lt;/td&gt;
 &lt;td&gt;MR 中固化在 shuffle 里，Tez 中可选&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Shuffling&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;跨节点数据传输&lt;/td&gt;
 &lt;td&gt;MR 的 shuffle 阶段&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Merging&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;归并多源数据&lt;/td&gt;
 &lt;td&gt;MR 的 merge 阶段&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Edge（边）&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;Vertex 之间的数据通信通道&lt;/td&gt;
 &lt;td&gt;相当于 MR Job 之间的 HDFS 中转&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;

 &lt;blockquote&gt;
 &lt;p&gt;💡 &lt;strong&gt;关键思想&lt;/strong&gt;：Sorting / Shuffling / Merging 这些在 MR 中&lt;strong&gt;强制绑定&lt;/strong&gt;的步骤，在 Tez 里变成&lt;strong&gt;可拆卸、可组合的元操作&lt;/strong&gt;。例如某些 Join 不需要排序，Tez 就可以&lt;strong&gt;跳过 Sorting&lt;/strong&gt;；某些计算不需要全量 shuffle，可以用更轻量的 Edge 类型（如 Broadcast Edge）。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;这些元操作被&lt;strong&gt;控制程序（DAG Plan）灵活组装&lt;/strong&gt;后，形成一张完整的 &lt;strong&gt;DAG 作业&lt;/strong&gt;——原本需要 N 个 MR Job 串行的 SQL，&lt;strong&gt;现在可以塞进一个 Tez DAG 任务一次性跑完&lt;/strong&gt;。&lt;/p&gt;
&lt;h3 id="-与-mr-的对比图逻辑示意"&gt;③ 与 MR 的对比图（逻辑示意）
&lt;/h3&gt;&lt;p&gt;假设有 SQL：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;1
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;2
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;3
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;SELECT&lt;/span&gt; city, &lt;span style="color:#66d9ef"&gt;COUNT&lt;/span&gt;(&lt;span style="color:#f92672"&gt;*&lt;/span&gt;) &lt;span style="color:#66d9ef"&gt;AS&lt;/span&gt; cnt
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;FROM&lt;/span&gt; user_log
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;WHERE&lt;/span&gt; dt &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;2026-05-27&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;GROUP&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;BY&lt;/span&gt; city;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;hr&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;对比项&lt;/th&gt;
 &lt;th&gt;Hive on MapReduce&lt;/th&gt;
 &lt;th&gt;Hive on Tez&lt;/th&gt;
 &lt;th&gt;Hive on Spark&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;核心定位&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;Hive SQL 被编译成一个或多个 MapReduce Job 执行&lt;/td&gt;
 &lt;td&gt;Hive SQL 被编译成 Tez DAG 执行&lt;/td&gt;
 &lt;td&gt;Hive SQL 被编译成 Spark 执行计划，通过 Spark DAG/Stage 执行&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;执行模型&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;主要是 &lt;code&gt;Map-only&lt;/code&gt; 或 &lt;code&gt;Map → Shuffle/Sort → Reduce&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;DAG → Vertex → Task&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;Application → Job → Stage → Task&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;过程&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;Map 阶段：&lt;/strong&gt;&lt;br&gt;&lt;br&gt;读取 HDFS 上的输入数据&lt;br&gt;&lt;br&gt;执行过滤条件，例如 &lt;code&gt;dt = '2026-05-27'&lt;/code&gt;&lt;br&gt;&lt;br&gt;生成中间 KV，例如 &lt;code&gt;(city, 1)&lt;/code&gt;&lt;br&gt;&lt;br&gt;Map 输出会按照分区规则写入本地磁盘的中间文件，不是写入 HDFS&lt;br&gt;&lt;br&gt;&lt;strong&gt;Shuffle/Sort 阶段：&lt;/strong&gt;&lt;br&gt;&lt;br&gt;按照 &lt;code&gt;city&lt;/code&gt; 进行分区。&lt;br&gt;&lt;br&gt;相同 &lt;code&gt;city&lt;/code&gt; 的数据会被分配到同一个 Reducer。&lt;br&gt;&lt;br&gt;Reducer 通过网络从各个 Mapper 所在节点拉取对应分区的中间结果。&lt;br&gt;&lt;br&gt;拉取后会进行 merge/sort。&lt;br&gt;&lt;br&gt;&lt;strong&gt;Reduce 阶段：&lt;/strong&gt;&lt;br&gt;&lt;br&gt;Reducer 对相同 &lt;code&gt;city&lt;/code&gt; 的数据做最终聚合，例如 &lt;code&gt;COUNT(*)&lt;/code&gt;。&lt;br&gt;&lt;br&gt;&lt;strong&gt;Output 阶段：&lt;/strong&gt;&lt;br&gt;&lt;br&gt;Reduce 结果直接写入 HDFS。&lt;br&gt;&lt;br&gt;如果 SQL 很复杂，例如包含多个 join、group by、order by，可能被拆成多个 MR Job 串联执行，Job 之间通常通过 HDFS 落盘传递中间结果。&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;Vertex 1：&lt;/strong&gt;&lt;br&gt;&lt;br&gt;读取数据。&lt;br&gt;&lt;br&gt;执行过滤条件。&lt;br&gt;&lt;br&gt;执行局部聚合，例如先在每个 Task 内部做 &lt;code&gt;city → partial count&lt;/code&gt;。&lt;br&gt;&lt;br&gt;&lt;strong&gt;Shuffle Edge by city：&lt;/strong&gt;&lt;br&gt;&lt;br&gt;通过 Tez Edge 按 &lt;code&gt;city&lt;/code&gt; 重新分布数据。&lt;br&gt;&lt;br&gt;相同 &lt;code&gt;city&lt;/code&gt; 的数据进入下游对应的 Vertex Task。&lt;br&gt;&lt;br&gt;&lt;strong&gt;Vertex 2：&lt;/strong&gt;&lt;br&gt;&lt;br&gt;执行全局聚合。&lt;br&gt;&lt;br&gt;输出最终结果。&lt;br&gt;&lt;br&gt;相比 MapReduce，Tez 可以把多个处理阶段组织成一个 DAG，不一定每个阶段都落 HDFS。&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;Stage 0：&lt;/strong&gt;&lt;br&gt;&lt;br&gt;读取数据。&lt;br&gt;&lt;br&gt;执行过滤。&lt;br&gt;&lt;br&gt;执行 map-side combine / partial aggregation。&lt;br&gt;&lt;br&gt;执行 shuffle write，把按 &lt;code&gt;city&lt;/code&gt; 分区后的中间结果写到本地磁盘，供下游 Stage 拉取。&lt;br&gt;&lt;br&gt;&lt;strong&gt;Shuffle：&lt;/strong&gt;&lt;br&gt;&lt;br&gt;按照 &lt;code&gt;city&lt;/code&gt; 重新分布数据。&lt;br&gt;&lt;br&gt;&lt;strong&gt;Stage 1：&lt;/strong&gt;&lt;br&gt;&lt;br&gt;执行 shuffle read。&lt;br&gt;&lt;br&gt;读取上游 Stage 的 shuffle 文件。&lt;br&gt;&lt;br&gt;执行 reduce aggregation，也就是最终聚合。&lt;br&gt;&lt;br&gt;输出结果到 HDFS 或其他存储。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;是否必须有 Reduce/Shuffle&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;不一定。&lt;br&gt;&lt;br&gt;如果只是 &lt;code&gt;SELECT ... WHERE ...&lt;/code&gt; 这种过滤/投影，可以是 Map-only Job。&lt;br&gt;&lt;br&gt;如果有 &lt;code&gt;GROUP BY city&lt;/code&gt;，一般需要 Shuffle 和 Reduce。&lt;/td&gt;
 &lt;td&gt;不一定。&lt;br&gt;&lt;br&gt;如果只是过滤/投影，可以只有一个 Vertex。&lt;br&gt;&lt;br&gt;如果有 group by/join/order by，则 DAG 中会出现 Shuffle Edge。&lt;/td&gt;
 &lt;td&gt;不一定。&lt;br&gt;&lt;br&gt;窄依赖操作，例如 filter/map/project，可以放在同一个 Stage。&lt;br&gt;&lt;br&gt;遇到 groupBy/join/distinct/orderBy 这类宽依赖，通常会产生 Shuffle 并切分 Stage。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;中间结果位置&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;Map 输出中间结果主要在 Mapper 节点本地磁盘。&lt;br&gt;&lt;br&gt;多个 MR Job 之间的中间结果通常落 HDFS。&lt;/td&gt;
 &lt;td&gt;Vertex 之间可以通过内存、本地磁盘、网络传输。&lt;br&gt;&lt;br&gt;不必像多个 MR Job 那样频繁落 HDFS。&lt;/td&gt;
 &lt;td&gt;Stage 内部可以 pipeline。&lt;br&gt;&lt;br&gt;Shuffle 文件通常写本地磁盘。&lt;br&gt;&lt;br&gt;RDD/DataFrame 可以 cache/persist 到内存或磁盘。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;DAG 能力&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;单个 MR Job 本身不是灵活 DAG。&lt;br&gt;&lt;br&gt;复杂 SQL 往往拆成多个 MR Job 串起来。&lt;/td&gt;
 &lt;td&gt;Tez 的核心就是 DAG。&lt;br&gt;&lt;br&gt;Hive 会把 SQL 编译成 Vertex + Edge 的 DAG。&lt;/td&gt;
 &lt;td&gt;Spark 也是 DAG 执行。&lt;br&gt;&lt;br&gt;Spark 根据 RDD lineage 或 Spark SQL 物理计划生成 DAG，再切分 Stage。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;优化&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;主要依赖 Hive 优化器 + MapReduce 能力。&lt;br&gt;&lt;br&gt;常见优化包括：&lt;br&gt;&lt;br&gt;分区裁剪。&lt;br&gt;&lt;br&gt;列裁剪。&lt;br&gt;&lt;br&gt;谓词下推。&lt;br&gt;&lt;br&gt;Map-side aggregation。&lt;br&gt;&lt;br&gt;Combiner。&lt;br&gt;&lt;br&gt;MapJoin。&lt;br&gt;&lt;br&gt;Bucket Map Join。&lt;br&gt;&lt;br&gt;Sort-Merge Bucket Join。&lt;br&gt;&lt;br&gt;压缩。&lt;br&gt;&lt;br&gt;合理设置 Reducer 数量。&lt;/td&gt;
 &lt;td&gt;相比 MR，可以减少不必要的 HDFS 落盘。&lt;br&gt;&lt;br&gt;多个阶段可以组织成一个 DAG。&lt;br&gt;&lt;br&gt;支持更灵活的数据传输边，例如 shuffle edge、broadcast edge。&lt;br&gt;&lt;br&gt;可以减少 Job 启动开销。&lt;br&gt;&lt;br&gt;更适合 Hive SQL 批处理查询。&lt;/td&gt;
 &lt;td&gt;支持 Catalyst 优化器和 Tungsten 执行优化。&lt;br&gt;&lt;br&gt;可以做 whole-stage codegen。&lt;br&gt;&lt;br&gt;支持 cache/persist。&lt;br&gt;&lt;br&gt;对迭代计算、交互式查询、复杂 ETL 更友好。&lt;br&gt;&lt;br&gt;可以通过 AQE 自适应优化 shuffle 分区、join 策略等。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;优点&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;模型简单。&lt;br&gt;&lt;br&gt;稳定成熟。&lt;br&gt;&lt;br&gt;容错能力强。&lt;br&gt;&lt;br&gt;适合传统大规模离线批处理。&lt;/td&gt;
 &lt;td&gt;相比 MR 更快。&lt;br&gt;&lt;br&gt;减少多 MR Job 之间的 HDFS 落盘。&lt;br&gt;&lt;br&gt;更适合 Hive SQL。&lt;br&gt;&lt;br&gt;资源利用率更好。&lt;/td&gt;
 &lt;td&gt;通用性强。&lt;br&gt;&lt;br&gt;不只支持 SQL，还支持 DataFrame、RDD、机器学习、流处理。&lt;br&gt;&lt;br&gt;内存计算能力强。&lt;br&gt;&lt;br&gt;复杂任务性能通常更好。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;缺点&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;多阶段 SQL 容易拆成多个 MR Job。&lt;br&gt;&lt;br&gt;Job 启动开销较大。&lt;br&gt;&lt;br&gt;中间结果频繁落 HDFS。&lt;br&gt;&lt;br&gt;对复杂 DAG 表达能力弱。&lt;br&gt;&lt;br&gt;交互式查询性能较差。&lt;/td&gt;
 &lt;td&gt;主要作为 DAG 执行框架，本身不是完整通用计算生态。&lt;br&gt;&lt;br&gt;通常依赖 Hive/Pig 等上层系统。&lt;br&gt;&lt;br&gt;调优也有一定复杂度。&lt;/td&gt;
 &lt;td&gt;集群资源消耗可能更高。&lt;br&gt;&lt;br&gt;内存管理、shuffle、倾斜、executor 配置调优复杂。&lt;br&gt;&lt;br&gt;Hive on Spark 在很多企业环境中不一定是主流 Hive 执行方式。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;适合场景&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;传统离线批处理。&lt;br&gt;&lt;br&gt;稳定性要求高、性能要求不极致的任务。&lt;br&gt;&lt;br&gt;老 Hadoop 集群。&lt;/td&gt;
 &lt;td&gt;Hive SQL 批处理查询。&lt;br&gt;&lt;br&gt;希望替代 Hive on MR，提高 SQL 执行效率。&lt;/td&gt;
 &lt;td&gt;复杂 ETL。&lt;br&gt;&lt;br&gt;交互式分析。&lt;br&gt;&lt;br&gt;机器学习。&lt;br&gt;&lt;br&gt;流批一体。&lt;br&gt;&lt;br&gt;需要复用 Spark 生态的场景。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h3 id="-tez-在-hive-上的关键收益"&gt;④ Tez 在 Hive 上的关键收益
&lt;/h3&gt;&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;DAG 一次性执行&lt;/strong&gt;：让 Hive 一条复杂 SQL 在一个 Tez 任务内跑完，而不是多个 MR Job 串行。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;中间结果免落 HDFS&lt;/strong&gt;：上游 Vertex 输出通过 Edge &lt;strong&gt;直接传给下游 Vertex&lt;/strong&gt;，走内存或本地磁盘，&lt;strong&gt;不强制写 HDFS&lt;/strong&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;容器复用（Container Reuse）&lt;/strong&gt;：一个 YARN Container 可被多个 Task 复用，&lt;strong&gt;避免反复启动 JVM&lt;/strong&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;动态优化&lt;/strong&gt;：Dynamic Partition Pruning、Runtime Reoptimization 等，运行时根据数据量动态调整 reducer 数、shuffle 策略。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="-优缺点-1"&gt;⑤ 优缺点
&lt;/h3&gt;&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;维度&lt;/th&gt;
 &lt;th&gt;表现&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;✅ 性能&lt;/td&gt;
 &lt;td&gt;相比 MR 提升 &lt;strong&gt;3~10 倍&lt;/strong&gt;，尤其多 Join、多聚合 SQL&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;✅ 资源利用&lt;/td&gt;
 &lt;td&gt;Container 复用 + 动态调度，YARN 资源效率更高&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;✅ Hive 集成度&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;专为 Hive 优化&lt;/strong&gt;，与 CBO、向量化执行、LLAP 配合最好&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;❌ 通用性&lt;/td&gt;
 &lt;td&gt;几乎只服务 Hive/Pig，不像 Spark 是通用计算引擎&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;❌ 社区活跃度&lt;/td&gt;
 &lt;td&gt;近几年活跃度下降，主要靠 Cloudera 维护&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;

 &lt;blockquote&gt;
 &lt;p&gt;💡 &lt;strong&gt;HDP/CDP 体系的 Hive 默认引擎就是 Tez&lt;/strong&gt;，配合 &lt;strong&gt;LLAP（Long-Live and Process）&lt;/strong&gt; 可以做到秒级交互式查询。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="33-spark-引擎hive-on-spark"&gt;3.3 Spark 引擎（Hive on Spark）
&lt;/h2&gt;&lt;h3 id="-定位"&gt;① 定位
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;Apache Spark 是专为大规模数据处理而设计的快速、通用、支持 DAG 作业的计算引擎&lt;/strong&gt;，类似于 Hadoop MapReduce 的通用并行框架，可用来构建&lt;strong&gt;大型、低延迟的数据分析应用&lt;/strong&gt;。Spark 是&lt;strong&gt;大规模数据处理的统一分析引擎&lt;/strong&gt;，核心特点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;基于内存计算&lt;/strong&gt;：中间结果优先驻留内存（RDD/DataFrame Cache），相比 MR 的反复落盘，数据处理实时性大幅提升。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;高容错&lt;/strong&gt;：通过 RDD 的 Lineage（血缘）机制，失败时可重算丢失分区，无需全量重跑。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;高可伸缩&lt;/strong&gt;：可部署在大量普通硬件上形成集群，从单机到数千节点弹性扩展。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;通用性&lt;/strong&gt;：同一个引擎覆盖批处理、流计算（Structured Streaming）、机器学习（MLlib）、图计算（GraphX）。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Hive on Spark 就是把 Hive 的物理计划翻译成 &lt;strong&gt;Spark 的 RDD/DAG 任务&lt;/strong&gt; 来执行，由 Cloudera 主导推进（CDH 体系默认）。&lt;/p&gt;
&lt;h3 id="-概念定义"&gt;② 概念定义
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;1、RDD = Resilient Distributed Dataset 弹性分布式数据集&lt;/strong&gt;，它是 Spark 早期最核心的抽象，可以拆成三层理解&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Dataset：数据集&lt;/strong&gt;，RDD 表示一批数据。比如日志文件：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;1
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;2
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;3
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;line1
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;line2
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;line3
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;在 Spark 里可以表示成 &lt;code&gt;val rdd = sc.textFile(&amp;quot;hdfs://logs&amp;quot;)&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Distributed：分布式&lt;/strong&gt;，RDD 不是存在一台机器上，而是被切成多个 partition，分布在集群多个 Executor 上。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;1
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;2
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;3
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;4
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;RDD
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;├──&lt;/span&gt; Partition &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;→&lt;/span&gt; Executor A
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;├──&lt;/span&gt; Partition &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;→&lt;/span&gt; Executor B
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;├──&lt;/span&gt; Partition &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;→&lt;/span&gt; Executor &lt;span style="color:#66d9ef"&gt;C&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;└──&lt;/span&gt; Partition &lt;span style="color:#ae81ff"&gt;3&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;→&lt;/span&gt; Executor D
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;这里的 partition 是 Spark 内部的计算分区，不要和 Hive 表分区完全混淆。（Hive 表分区通常是物理目录：&lt;code&gt;/dt=2026-05-27/hour=10/&lt;/code&gt;）&lt;/p&gt;
&lt;p&gt;Spark RDD partition 是执行层面的数据切片：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;1
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;2
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Task &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;处理&lt;/span&gt; Partition &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Task &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;处理&lt;/span&gt; Partition &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Task &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;处理&lt;/span&gt; Partition &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Resilient：弹性/容错&lt;/strong&gt;，RDD 的重点是：&lt;/p&gt;
&lt;p&gt;它不一定要把每一步的中间结果都持久化下来，而是记录“这个 RDD 是怎么由上游 RDD 计算出来的”。（这就是 lineage，血缘 ）例如：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;1
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;2
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;3
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;4
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-scala" data-lang="scala"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;val&lt;/span&gt; rdd1 &lt;span style="color:#66d9ef"&gt;=&lt;/span&gt; sc&lt;span style="color:#f92672"&gt;.&lt;/span&gt;textFile&lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;logs&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;val&lt;/span&gt; rdd2 &lt;span style="color:#66d9ef"&gt;=&lt;/span&gt; rdd1&lt;span style="color:#f92672"&gt;.&lt;/span&gt;map&lt;span style="color:#f92672"&gt;(&lt;/span&gt;parse&lt;span style="color:#f92672"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;val&lt;/span&gt; rdd3 &lt;span style="color:#66d9ef"&gt;=&lt;/span&gt; rdd2&lt;span style="color:#f92672"&gt;.&lt;/span&gt;filter&lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;_&lt;/span&gt;&lt;span style="color:#f92672"&gt;.&lt;/span&gt;isValid&lt;span style="color:#f92672"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;val&lt;/span&gt; rdd4 &lt;span style="color:#66d9ef"&gt;=&lt;/span&gt; rdd3&lt;span style="color:#f92672"&gt;.&lt;/span&gt;map&lt;span style="color:#f92672"&gt;(&lt;/span&gt;x &lt;span style="color:#66d9ef"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#f92672"&gt;(&lt;/span&gt;x&lt;span style="color:#f92672"&gt;.&lt;/span&gt;userId&lt;span style="color:#f92672"&gt;,&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;&lt;span style="color:#f92672"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;val&lt;/span&gt; rdd5 &lt;span style="color:#66d9ef"&gt;=&lt;/span&gt; rdd4&lt;span style="color:#f92672"&gt;.&lt;/span&gt;reduceByKey&lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;_&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;_&lt;/span&gt;&lt;span style="color:#f92672"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;血缘关系是：&lt;code&gt;rdd1 → rdd2 → rdd3 → rdd4 → rdd5&lt;/code&gt; &lt;strong&gt;用于实现 RDD 的容错能力&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;如果 rdd3 的某个 partition 丢了，Spark 可以根据血缘重新算：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;1
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;2
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;3
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;4
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;5
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;6
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-scala" data-lang="scala"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;rdd1 的对应 partition
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;↓&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;重新 map
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;↓&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;重新 filter
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;↓&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;恢复 rdd3 的那个 partition
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;2、某分区数据丢失&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;“分区数据丢失”通常不是指 Hive 表分区目录丢了，而是指：计算过程中，某个 Task 产生的中间结果丢失了。比如 Spark 中：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;RDD Partition &lt;span style="color:#ae81ff"&gt;3&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;缓存在&lt;/span&gt; Executor B &lt;span style="color:#960050;background-color:#1e0010"&gt;内存中&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;后来：&lt;code&gt;Executor B 挂了&lt;/code&gt;，那么 &lt;code&gt;Partition 3 的缓存数据就没了&lt;/code&gt;
但是 Spark 有 lineage存储了 &lt;code&gt;Partition 3 是怎么从上游 partition 算出来的&lt;/code&gt;，所以可以重新计算。&lt;/p&gt;
&lt;p&gt;MapReduce 的 Map 输出中间结果通常在本地磁盘。比如：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;1
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;MapTask_1 &lt;span style="color:#960050;background-color:#1e0010"&gt;在&lt;/span&gt; NodeA &lt;span style="color:#960050;background-color:#1e0010"&gt;上产生中间文件&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;ReduceTask_3 &lt;span style="color:#960050;background-color:#1e0010"&gt;需要从&lt;/span&gt; NodeA &lt;span style="color:#960050;background-color:#1e0010"&gt;拉这个文件&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;如果 NodeA 挂了，Reduce 拉不到这个中间结果。&lt;/p&gt;
&lt;p&gt;MapReduce 的处理方式是：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;1
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;2
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;重新运行失败的&lt;/span&gt; MapTask_1
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;重新生成中间输出&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Reduce &lt;span style="color:#960050;background-color:#1e0010"&gt;再去拉&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;所以 &lt;strong&gt;MapReduce&lt;/strong&gt; 也有容错。但是它的容错方式更偏：&lt;strong&gt;Task 级别重试&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Spark RDD&lt;/strong&gt; 更强调：&lt;strong&gt;通过 RDD 血缘关系重算丢失的 partition&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id="--区分两个易混概念"&gt;③ ⚠️ 区分两个易混概念
&lt;/h3&gt;&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;概念&lt;/th&gt;
 &lt;th&gt;入口&lt;/th&gt;
 &lt;th&gt;SQL 解析&lt;/th&gt;
 &lt;th&gt;物理执行&lt;/th&gt;
 &lt;th&gt;元数据&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Hive on Spark&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;Hive CLI / HS2&lt;/td&gt;
 &lt;td&gt;Hive 解析器&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;Spark RDD&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;Hive Metastore&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Spark on Hive&lt;/strong&gt;（Spark SQL + HMS）&lt;/td&gt;
 &lt;td&gt;Spark / SparkSQL&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;Spark Catalyst&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;Spark Tungsten&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;Hive Metastore&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;

 &lt;blockquote&gt;
 &lt;p&gt;业界主流是后者：&lt;strong&gt;Spark 自己解析 + 自己执行，只借用 HMS 读元数据&lt;/strong&gt;。Hive 退化成元数据中枢。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;h3 id="-核心改进"&gt;④ 核心改进
&lt;/h3&gt;&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;天然 DAG + 内存计算&lt;/strong&gt;：中间结果优先驻留内存（RDD/DataFrame Cache），磁盘 I/O 大幅降低。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;统一执行模型&lt;/strong&gt;：Map/Reduce/Shuffle 都是 RDD 上的算子，调度粒度细化为 Stage → Task。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tungsten + CodeGen&lt;/strong&gt;：堆外内存管理 + 全阶段代码生成，把物理执行下推到接近手写代码的效率。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;丰富生态&lt;/strong&gt;：批/流/ML/图 一栈式复用，无需为不同负载切换引擎。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="-优缺点-2"&gt;⑤ 优缺点
&lt;/h3&gt;&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;维度&lt;/th&gt;
 &lt;th&gt;表现&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;✅ 性能&lt;/td&gt;
 &lt;td&gt;内存计算 + Tungsten 优化，复杂 SQL 与 Tez 相当或更快&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;✅ 生态&lt;/td&gt;
 &lt;td&gt;MLlib、Structured Streaming、GraphX 一栈式&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;✅ 通用性&lt;/td&gt;
 &lt;td&gt;不仅服务 Hive，还能跑批/流/ML，企业一栈式落地&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;❌ 资源占用&lt;/td&gt;
 &lt;td&gt;内存吃得多，OOM 风险比 Tez 高&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;❌ 版本耦合&lt;/td&gt;
 &lt;td&gt;Hive on Spark 版本兼容性敏感（Hive ↔ Spark 严格对应）&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;维度&lt;/th&gt;
 &lt;th&gt;表现&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;✅ 性能&lt;/td&gt;
 &lt;td&gt;内存计算，复杂 SQL 表现优秀，与 Tez 相当或更快&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;✅ 生态&lt;/td&gt;
 &lt;td&gt;Spark 生态丰富（MLlib、Streaming、GraphX），同一个引擎可复用&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;✅ 通用性&lt;/td&gt;
 &lt;td&gt;Spark 不仅服务 Hive，还能跑批/流/ML，企业一栈式&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;❌ 资源占用&lt;/td&gt;
 &lt;td&gt;内存吃得多，OOM 风险比 Tez 高&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;❌ 与 Hive 耦合&lt;/td&gt;
 &lt;td&gt;Hive on Spark 版本兼容性较敏感（Hive 版本 ↔ Spark 版本严格对应）&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="34-三者对比总表重点记忆"&gt;3.4 三者对比总表（重点记忆）
&lt;/h2&gt;&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;对比项&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;MapReduce&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;Tez&lt;/strong&gt;&lt;/th&gt;
 &lt;th&gt;&lt;strong&gt;Spark&lt;/strong&gt;&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;执行模型&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;两段式 Map-Reduce&lt;/td&gt;
 &lt;td&gt;DAG&lt;/td&gt;
 &lt;td&gt;DAG + 内存计算&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;中间结果&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;必须落 HDFS&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;内存 / 本地磁盘&lt;/td&gt;
 &lt;td&gt;优先内存（可 cache）&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;JVM 启动&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;每 Task 一个，启动开销大&lt;/td&gt;
 &lt;td&gt;Container 复用&lt;/td&gt;
 &lt;td&gt;Executor 长驻，任务复用，启动开销小。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;多 Stage SQL&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;多个 Job 串行&lt;/td&gt;
 &lt;td&gt;一个 DAG&lt;/td&gt;
 &lt;td&gt;一个 DAG&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;性能&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;⭐（最慢）&lt;/td&gt;
 &lt;td&gt;⭐⭐⭐⭐&lt;/td&gt;
 &lt;td&gt;⭐⭐⭐⭐&lt;br/&gt;比基于磁盘的 MapReduce 快 10-100 倍&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;稳定性&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;⭐⭐⭐⭐⭐&lt;/td&gt;
 &lt;td&gt;⭐⭐⭐⭐&lt;/td&gt;
 &lt;td&gt;⭐⭐⭐&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;资源占用&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;低（磁盘换内存）&lt;/td&gt;
 &lt;td&gt;中&lt;/td&gt;
 &lt;td&gt;高（内存密集）&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;典型发行版&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;Hive 1.x、早期 CDH&lt;/td&gt;
 &lt;td&gt;HDP / CDP&lt;/td&gt;
 &lt;td&gt;CDH / 通用&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;当前状态&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;已废弃&lt;/td&gt;
 &lt;td&gt;仍在维护&lt;/td&gt;
 &lt;td&gt;主流之一&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;适用场景&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;超大规模、稳定优先的离线批&lt;/td&gt;
 &lt;td&gt;Hive 交互式 / 批处理（HDP/CDP）&lt;/td&gt;
 &lt;td&gt;批流一体、ML 一栈式&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="35-实际工程中的选型建议"&gt;3.5 实际工程中的选型建议
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;新项目几乎不再选 MR&lt;/strong&gt;：太慢，且官方已废弃。除非有遗留作业兼容性需求。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;HDP/CDP 体系 → Tez + LLAP&lt;/strong&gt;：交互式查询体验最好，是 Hive 原生最优解。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;需要一栈式（批 + 流 + ML）→ Spark SQL on Hive Metastore&lt;/strong&gt;：现代数据平台主流姿势，&lt;strong&gt;Hive 退化为元数据服务（HMS）&lt;/strong&gt;，计算全交给 Spark。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;湖仓一体场景（Delta/Iceberg/Hudi）→ Spark / Flink / Trino&lt;/strong&gt;：Hive 本身的执行引擎已经不是重点，HMS 仍作为元数据中枢继续存在。&lt;/li&gt;
&lt;/ol&gt;

 &lt;blockquote&gt;
 &lt;p&gt;🎯 &lt;strong&gt;趋势总结&lt;/strong&gt;：Hive 正在从&amp;quot;计算+存储+元数据&amp;quot;的三合一系统，演变为&lt;strong&gt;Hive Metastore（HMS）+ 计算引擎插件化&lt;/strong&gt;的模式。MR 已退场，Tez 守住 Hive 自家阵地，Spark 则在更大的数据平台范畴内成为事实标准。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;引擎&lt;/th&gt;
 &lt;th&gt;核心思想&lt;/th&gt;
 &lt;th&gt;优点&lt;/th&gt;
 &lt;th&gt;缺点&lt;/th&gt;
 &lt;th&gt;应用场景比喻&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;MapReduce&lt;/strong&gt;​&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;分而治之&lt;/strong&gt;。将任务分成Map（映射）和Reduce（归约）两个阶段，中间结果写入磁盘。&lt;/td&gt;
 &lt;td&gt;1. &lt;strong&gt;非常稳定&lt;/strong&gt;，Hadoop原生支持。&lt;br&gt;2. 适合处理海量离线数据。&lt;br&gt;3. 容错性强。&lt;/td&gt;
 &lt;td&gt;1. &lt;strong&gt;速度慢&lt;/strong&gt;，每一步都要读写磁盘。&lt;br&gt;2. 编程模型相对复杂。&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;“绿皮火车”&lt;/strong&gt;：稳定、能拉重货（海量数据），但速度慢。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Tez&lt;/strong&gt;​&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;有向无环图优化&lt;/strong&gt;。将多个MR任务拼接成一个更复杂的执行图，减少不必要的磁盘I/O。&lt;/td&gt;
 &lt;td&gt;1. &lt;strong&gt;比MR快数倍&lt;/strong&gt;。&lt;br&gt;2. 资源利用率更高。&lt;br&gt;3. 与Hive、YARN集成好。&lt;/td&gt;
 &lt;td&gt;生态系统和社区活跃度低于Spark。&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;“动车组”&lt;/strong&gt;：在原有铁路（YARN）上大幅提速，是MR的优化升级版。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Spark&lt;/strong&gt;​&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;基于内存的迭代计算&lt;/strong&gt;。将数据尽可能放在内存中处理，并提供了更丰富的算子（API）。&lt;/td&gt;
 &lt;td&gt;1. &lt;strong&gt;速度极快&lt;/strong&gt;，比MR快10-100倍。&lt;br&gt;2. 提供一站式解决方案（Spark SQL, Streaming, MLlib）。&lt;br&gt;3. 生态火爆，是当前主流。&lt;/td&gt;
 &lt;td&gt;对内存资源要求高，配置不当易OOM（内存溢出）。&lt;/td&gt;
 &lt;td&gt;“高铁”：速度最快，乘坐体验（开发体验）好，是现代主流选择。&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;</description></item></channel></rss>