Tez 用什么换性能
传统 MapReduce 把每个阶段的结果都落到磁盘再起下一轮任务,多阶段 ETL 会反复读写中间数据。Tez 把多个阶段串成一个 DAG,中间结果尽量直接在内存里流转给下游算子,减少落盘与启动开销。切换引擎只需改执行参数,SQL 本身不用动。
基本信息
| 执行模型 | DAG,多阶段合并为一个作业 |
|---|---|
| 核心收益 | 减少中间结果落盘与作业启动次数 |
| 适用负载 | 多阶段 ETL、链路较长的加工任务 |
| 切换方式 | set hive.execution.engine=tez |
| 资源相关 | hive.tez.container.size、hive.tez.java.opts |
典型使用场景
- 多层加工链路:一个任务里连续 insert 多张中间表,Tez 能合并阶段
- 小文件密集的读取:容器复用降低任务启动开销
- 需要多次 map 后 reduce 的链路:合并不必要的中间落盘
- 资源受限集群:作业数减少,调度排队压力同步下降
- 已经用 Spark 承担重计算的团队:把 Hive 侧留在 Tez,避免两套引擎重复建设
Tez 常用参数
Tez 常用参数
-- 会话级切换引擎与队列
set hive.execution.engine=tez;
set tez.queue.name=etl_default; -- 与调度平台分配的队列一致
set hive.tez.container.size=4096; -- 容器内存,MB
set hive.tez.java.opts=-Xmx3276m; -- 堆内存留出余量给堆外
-- 容器复用,减少启动开销
set tez.am.container.reuse.enabled=true;
set hive.vectorized.execution.enabled=true; -- 可与向量化叠加执行引擎对照
| 引擎 | 执行模型 | 适用判断 |
|---|---|---|
| MapReduce | 逐阶段落盘 | 存量兼容,重负载下性能差 |
| Tez | DAG 合并阶段 | 多阶段 Hive ETL 的首选 |
| Spark | 内存计算 + 调度器 | 复杂迭代与流式场景更合适 |
| 向量化 + Tez | 批量列式处理 | 扫描密集型的聚合查询收益明显 |
Tez 容器内存要与队列资源上限匹配:容器请求超过队列单容器上限时,任务会一直处于等待状态,日志里看不到明显报错,现象是「卡住不动」。
把 hive.tez.container.size 一味调大并不会更快:并行度下降、排队变长,反而拖长整体产出时间。按数据量与队列规格做压测后再定。
什么时候不该换引擎
单阶段、纯扫描的简单任务从 Tez 得到的收益有限,反而可能因为容器调度方式不同而变慢。存量脚本里存在大量短任务时,先挑链路最长、阶段最多的几支做对照测试,用产出时间与资源消耗两个指标衡量,再决定是否扩大切换范围。
上线与观测要点
- 先在测试队列跑一轮对照,记录总时长、峰值内存与中间落盘量
- 切换按任务粒度推进,保留回退开关,出问题能按任务改回旧引擎
- 关注队列的容器等待时间,它往往比单任务耗时更能反映整体影响
- 把参数写进调度脚本的公共配置,避免每个任务各带一套数值