Drill读取Spark生成的Parquet文件时多数列读取失败求助
解决Drill 1.15读取Spark 2.3生成Parquet文件部分列失败的问题
我之前在处理跨引擎Parquet交互的时候遇到过几乎一模一样的问题,结合你的场景(Drill 1.15 + Spark 2.3),给你几个靠谱的排查和解决方向:
1. 先检查Spark生成Parquet的格式兼容性
Spark 2.3对部分数据类型的Parquet编码逻辑,和Drill 1.15的默认解析规则不太兼容,尤其是这两类情况:
- Decimal类型:Spark默认可能用了非标准的精度存储方式,或者开启了
LEGACY模式的decimal编码 - 复杂嵌套类型(数组、结构体):如果报错里的
Line列是复杂类型,Spark的嵌套结构编码可能让Drill的解析器卡壳
解决办法:
在生成Parquet的Spark代码里,强制指定兼容标准Parquet的配置,重新生成文件后再试:
// 强制使用旧版Parquet格式,兼容Drill等老引擎 spark.conf.set("spark.sql.parquet.writeLegacyFormat", "true") // 关闭INT96时间戳自动转换,避免时间类型解析冲突 spark.conf.set("spark.sql.parquet.int96TimestampConversion", "false")
2. 调整Drill的Parquet解析配置
Drill的默认配置可能没开启对Spark特性的支持,你可以修改dfs存储的Parquet参数:
- 打开Drill的Web UI(默认端口8047),进入Storage → dfs → Update
- 在
formats下的parquet配置块中,添加或修改这些参数:
简单解释下关键参数:"parquet": { "type": "parquet", "readDecimalAsDouble": false, "enableInt96TimestampSupport": true, "useSchemaMetadata": true, "failOnError": false }enableInt96TimestampSupport:开启对Spark常用的INT96时间戳格式的支持useSchemaMetadata:强制读取Parquet文件自带的元数据Schema,而不是让Drill自动推断failOnError:临时设为false,看看能不能跳过错误列读取其他数据,帮你定位问题
修改完保存配置,重启Drill集群再测试查询。
3. 验证Parquet文件的行组完整性
报错里提到了Row Group Start: 111831,有可能这个行组存在细微损坏——Spark的容错逻辑比Drill宽松,所以能读但Drill不行。你可以用parquet-tools工具检查文件:
# 查看文件的元数据,包括行组和列信息 parquet-tools meta hdfs:///hdfs/path/to/parquet/file.parquet # 单独查看Line列的内容,确认是否有异常 parquet-tools cat -j hdfs:///hdfs/path/to/parquet/file.parquet | grep "Line"
看看Line列的元数据(比如数据类型、长度)是否符合标准Parquet规范。
4. 临时排查小技巧
如果想快速确认是不是只有Line列出问题,可以拆分查询:
-- 先查其他列,确认是否正常 select col1, col2 from dfs.`/hdfs/path/to/parquet/file.parquet`; -- 单独查Line列,看是否触发报错 select Line from dfs.`/hdfs/path/to/parquet/file.parquet`;
这样能快速缩小问题范围,判断是单列问题还是整体文件的兼容性问题。
可选方案:升级Drill版本
Drill 1.15是2019年的旧版本,后续的1.17+版本修复了大量和Spark生成Parquet相关的解析bug。如果前面的方法都无效,升级到较新的稳定版本会是一劳永逸的解决办法。
内容的提问来源于stack exchange,提问作者Avik Aggarwal
相关产品推荐
相关产品推荐

