使用Apache Drill关联MySQL表与两个HDFS CSV文件失败求助
我来帮你捋捋这个问题——在Apache Drill里做多源跨库/跨存储关联时,单关联没问题、多关联失败的情况我也碰到过几次,大概率是这几个地方出了问题,咱们一步步排查:
首先先明确你的场景和问题:
尝试用Apache Drill关联1张MySQL表(
MySQL.dummy.accident_05_07)与HDFS上的2个CSV文件,关联MySQL表和单个CSV时查询正常,但同时关联两个CSV就失败了,SQL大致如下:select CAST(a.Longitude AS DOUBLE),CAST(a.Latitude AS DOUBLE) from ((MySQL.dummy.`accident_05_07` as a inner join dfs.`/user/drill/accidents_2009_to_2011.csv` as b on a.Longitude=CAST(b.Longitude AS DOUBLE)) inner join dfs.`/u...` as c on [你的关联条件]
常见问题排查与解决步骤
1. 第二个CSV文件本身有数据/格式问题
Drill对CSV的格式兼容性很严格,第二个文件大概率存在以下问题:
- 行数据字段数量不一致(比如某行少列/多列,导致Drill解析schema出错)
- 关联字段(比如
Longitude)存在非数值内容,CAST转换时抛出异常 - 文件编码不是UTF-8,或者存在特殊不可见字符
解决方法:
- 先单独查询第二个CSV,验证是否能正常读取:
SELECT * FROM dfs.`/u...` LIMIT 10; - 检查关联字段的合法性,用
TRY_CAST筛选出转换失败的行:
如果有结果返回,说明存在非法值,要么清洗数据,要么在关联时用SELECT Longitude FROM dfs.`/u...` WHERE TRY_CAST(Longitude AS DOUBLE) IS NULL;TRY_CAST替代CAST避免查询中断。
2. 关联条件的类型不匹配或逻辑问题
- 可能第二个关联的字段没做类型转换,比如
a.Longitude已经转成DOUBLE,但c.Longitude还是字符串类型,直接关联会触发类型冲突 - 也可能关联条件逻辑导致笛卡尔积过大,Drill内存不足直接崩溃
解决方法:
- 确保所有关联字段类型一致,对第二个CSV的字段也做类型转换:
on a.Longitude = CAST(c.Longitude AS DOUBLE) - 如果是资源不足,调整Drill的内存配置:修改
drill-env.sh里的DRILL_HEAP参数(比如设为DRILL_HEAP=8G),或者在Drill Web UI(默认8047端口)的查询配置里调整并行度参数。
3. DFS存储插件配置或文件权限问题
- 第二个CSV所在的HDFS路径可能没有读取权限,或者DFS存储插件的CSV读取配置错误(比如没设置跳过表头、分隔符不匹配)
解决方法:
- 检查DFS存储插件的配置,确保路径
/u...有读取权限,并且CSV的格式配置正确(比如"skipFirstLine": true对应带表头的文件,"delimiter": ","匹配实际分隔符) - 也可以在查询时直接指定CSV读取选项,强制覆盖默认配置:
SELECT * FROM dfs.`/u...` (type => 'csv', skipFirstLine => true, delimiter => ',');
4. 关联顺序或查询写法的优化问题
Drill的查询优化器在处理多源关联时,可能对复杂嵌套关联的处理不够高效,你可以尝试用CTE(公共表表达式)先预处理每个数据源,再做关联:
WITH mysql_data AS ( SELECT CAST(Longitude AS DOUBLE) AS lon, CAST(Latitude AS DOUBLE) AS lat FROM MySQL.dummy.`accident_05_07` ), csv1_data AS ( SELECT CAST(Longitude AS DOUBLE) AS lon FROM dfs.`/user/drill/accidents_2009_to_2011.csv` (type => 'csv', skipFirstLine => true) ), csv2_data AS ( SELECT CAST(Longitude AS DOUBLE) AS lon FROM dfs.`/u...` (type => 'csv', skipFirstLine => true) ) SELECT md.lon, md.lat FROM mysql_data md JOIN csv1_data c1 ON md.lon = c1.lon JOIN csv2_data c2 ON md.lon = c2.lon;
5. 查看Drill错误日志精准定位
如果上面的方法都没解决,直接去看Drill的日志(默认路径是/var/log/drill/或你安装目录的log文件夹),里面会有具体的错误信息——比如转换异常、文件读取失败、内存溢出等,根据日志就能精准定位问题。
内容的提问来源于stack exchange,提问作者Shrinivas Deshmukh
相关产品推荐
相关产品推荐

