Hive Parquet外部表select count(*)在Tez执行失败,MR正常求原因
select count(*)失败但MR引擎正常的常见原因及排查思路 碰到这种Tez跑select count(*)挂了但MR正常的情况,我之前帮不少同学排查过,本质是两个引擎在执行逻辑、资源调度和Parquet文件处理上的差异导致的,给你梳理几个最常见的原因和排查方向:
Tez资源配置跟不上
Tez作为DAG引擎,对内存、CPU的调度逻辑和MR完全不一样,默认配置可能撑不住你的查询。比如Tez的容器内存设得太小,或者Application Master(AM)的内存不够,直接导致执行过程中OOM(内存溢出)。
你可以这么排查:- 对比Tez和MR的内存配置:看看
tez.am.resource.memory.mb、tez.container.size和MR的mapreduce.map.memory.mb、mapreduce.reduce.memory.mb,如果Tez的数值明显偏小,调大后再试。 - 打开查询日志,找有没有
OutOfMemoryError的报错,这是最直接的信号。
- 对比Tez和MR的内存配置:看看
Parquet文件元数据出问题了
Tez在处理count查询时,会优先用Parquet文件自带的统计元数据(比如每个文件的行数)来加速计算,但如果你的Parquet文件元数据损坏、缺失或者不一致,Tez读取这些元数据时就会报错;而MR引擎可能会直接 fallback 到全量扫描文件,反而能跑通。
解决思路:- 先执行
ANALYZE TABLE table1 COMPUTE STATISTICS FOR COLUMNS;重新生成表的统计信息,再用Tez跑一次。 - 用
parquet-tools meta命令手动检查单个Parquet文件的元数据,看是否有异常(比如行数统计为null、字段信息不匹配等)。
- 先执行
版本兼容性坑
不同版本的Tez和Hive、Parquet之间可能存在兼容性bug,比如某些老版本Tez对Parquet的特定编码、压缩算法支持有问题,而MR引擎的实现更成熟,没这个隐患。
排查方法:- 核对你的Hive、Tez、Parquet版本组合,比如如果是Tez 0.9.x搭配较新的Parquet 1.10+,可能会有这类问题。可以尝试升级Tez到对应Hive版本推荐的稳定版,或者调整Parquet的版本试试。
Tez的激进优化踩了坑
Tez会做更激进的查询优化,比如合并小任务、跳过不必要的扫描,但如果你的表是外部表,存在文件路径变更、部分文件缺失的情况,Tez的优化逻辑可能会处理出错;而MR的逻辑更保守,能正常应对这些“不完美”的情况。
验证方法:- 临时关闭Tez的优化:执行
set tez.optimizer.enabled=false;,再跑查询,如果能成功,说明是优化逻辑的问题,再针对性排查具体是哪个优化步骤出了问题。
- 临时关闭Tez的优化:执行
权限或文件访问差异
虽然MR能访问文件,但Tez的任务容器可能用了不同的用户身份或权限配置,导致无法读取部分Parquet文件。比如Tez的AM或任务容器用户没有某些文件的读权限,而MR的任务用户有。
排查方向:- 检查HDFS上Parquet文件的权限,对比Tez和MR任务运行的用户,确保Tez的任务用户有足够的权限访问所有文件。
你可以按照上面的顺序逐一排查,优先从资源配置和元数据问题入手,这两个是最常见的诱因。
内容的提问来源于stack exchange,提问作者kunrazor

