Presto无法读取数据但Hive可正常读取的问题求助
问题分析与解决方案
我之前在EMR环境里碰到过几乎一模一样的问题,结合你用的emr-5.9.0(Hive2.3.0、Presto0.184)版本,大概率是以下几个原因导致的,咱们逐个排查解决:
1. Presto元数据缓存未同步
Presto默认会缓存Hive的元数据,哪怕你在Hive里新增了分区,Presto可能还拿着旧的缓存信息,导致看不到新分区的数据。
- 解决办法:在Presto里执行刷新命令:
刷新后再执行-- 刷新整个表的元数据 REFRESH TABLE default.table; -- 或者针对单个分区刷新 REFRESH TABLE default.table PARTITION (dt = 'yyyy-MM-dd');select count(*) from default.table试试。
2. Parquet SerDe兼容性问题
你建表用的是org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe,而Presto 0.184对这个Hive专属SerDe的兼容性不太好,尤其是date类型字段的解析逻辑和Hive2.3.0存在差异。
- 排查解决:尝试把表的SerDe换成通用的Parquet SerDe:
另外检查分区目录命名:Hive的date类型分区是ALTER TABLE default.table SET SERDE 'org.apache.hadoop.hive.ql.io.parquet.serde.ParquetSerDe';dt=2024-05-20格式,Presto 0.184对这种格式的识别是否正常,如果是自定义路径,要确保和元数据里的路径完全匹配。
3. S3权限或分区路径不匹配
虽然Presto能看到分区元数据,但可能没权限读取对应S3分区下的Parquet文件,或者分区的实际存储路径和Presto解析的路径不一致:
- 排查步骤:
- 检查EMR集群的EC2执行角色是否有
s3://Bucket/Folder及其子目录的s3:GetObject权限; - 在Hive里执行
DESCRIBE EXTENDED default.table PARTITION (dt='yyyy-MM-dd');查看分区实际路径,再在Presto里执行SHOW PARTITIONS default.table WITH (location=true);对比路径,如果不一致,需要在Hive里修正分区路径,再重新刷新Presto元数据。
- 检查EMR集群的EC2执行角色是否有
4. Date类型分区的解析差异
你的分区列是date类型,Hive2.3.0和Presto0.184对date类型的处理逻辑有差异,比如Presto可能把分区目录里的日期字符串当成普通字符串,而非date类型,导致过滤或全表扫描时匹配不到数据。
- 测试方法:先尝试在Presto里显式指定分区过滤,比如
select count(*) from default.table where dt = date '2024-05-20';,如果能返回数据,说明是类型解析问题。可以临时把分区列改成string类型测试,或者调整Presto的hive.parquet.datetime-interpolation配置(需要重启Presto服务)。
5. EMR旧版本的已知bug
emr-5.9.0是比较老的版本了,Hive2.3.0和Presto0.184之间确实存在一些Parquet外部表分区查询的兼容性bug,如果上面的方法都无效,建议升级到较新的稳定EMR版本(比如emr-5.34.0,兼容Hive2.3.9和Presto0.272),升级前记得做好测试。
内容的提问来源于stack exchange,提问作者Bramat
相关产品推荐
相关产品推荐

