使用AvroSerDe构建的Hive表执行ORDER BY语句报错如何解决
问题成因
该问题的核心触发原因是Avro格式文件不支持Hive默认的CombineFileInputFormat切片合并机制:
- 执行
SELECT * FROM twitter时,Hive默认不会启动MapReduce任务,直接通过FetchTask读取原始Avro文件,不会触发切片合并逻辑,因此可以正常返回结果。 - 执行带ORDER BY的查询时,Hive需要启动MapReduce任务完成排序逻辑,默认会将多个小体积的Avro文件合并为同一个切片分配给Map任务处理。Avro文件本身自带独立的文件头、同步标记,跨文件合并的切片会破坏Avro文件的结构完整性,读取过程中读取到不完整的Avro记录就会抛出日志中的EOFException异常。
- 次要可能诱因:你当前配置的Avro schema路径为本地文件路径
file:///home/siva/TwitterDataAvroSchema.avsc,如果是分布式集群环境,除当前节点外的其他计算节点无法读取该schema文件,也会导致文件读取失败报错。
解决办法
可按照优先级选择以下方案修复问题:
- 临时修复:执行查询前先在当前Hive会话中关闭切片合并功能,再执行查询语句即可正常返回结果:
set hive.hadoop.supports.splittable.combineinputformat=false; select user_screen_name as name , user_location as location ,user_followers_count as count from twitter order by count desc limit 5;
- 永久表级修复:无需每次会话修改配置,将Avro schema文件上传至HDFS路径,修改表配置指向HDFS上的schema,同时关闭该表的切片合并配置:
ALTER TABLE twitter SET TBLPROPERTIES ( 'avro.schema.url'='hdfs://<你的HDFS集群地址>/存储路径/TwitterDataAvroSchema.avsc', 'hive.hadoop.supports.splittable.combineinputformat'='false' );
- 损坏文件修复:如果上述配置修改后仍然报错,说明存储路径下存在损坏的不完整Avro文件,可通过avro-tools工具扫描所有Avro文件,检测并删除损坏文件后重新导入数据即可:
# 检测单个Avro文件是否损坏 avro-tools getschema /待检测的Avro文件路径 # 执行后如果抛出异常则为损坏文件,直接删除即可
- 长期优化方案:如果该表需要频繁执行聚合、排序类查询,建议将Avro数据转换为Parquet或ORC这类支持切片合并的高性能列式存储格式,改写建表语句重新导入数据即可彻底解决该类兼容性问题。
内容的提问来源于stack exchange,提问作者Fatiha IMOUSSAINE
相关产品推荐
相关产品推荐

