Sqoop导出数据至数据库时触发NoSuchElementException及空输入解析错误
Sqoop 数据导出解析报错排查
异常链路定位
从提供的日志栈回溯可明确:
Sqoop执行导出的map task读取指定目录的文本文件时,按--fields-terminated-by '|'规则拆分字段,字段迭代器在无剩余元素的情况下继续取值,触发java.util.NoSuchElementException,最终被封装为“无法导出数据,请检查map task日志”的通用IOException。
该类异常的共性触发原因是:按分隔符拆分得到的实际字段数量,和命令中--columns指定的目标表字段数量不匹配。
排查&解决操作步骤
- 采样校验导出目录的文件实际列数
执行如下命令采样数据文件的前10行,按设定的分隔符统计实际列数:hdfs dfs -cat $FILE_DIRECTORY/下属数据文件 | head -n 10 | awk -F'|' '{print NF}'
重点排查列数异常的典型场景:- 数据文件中存在无内容的空行,拆分后有效字段数不足,直接触发迭代器越界
- 字段值本身包含未转义的
|分隔符,导致非预期拆分,实际列数比预期多 - 部分数据行缺失分隔符、末尾分隔符遗漏,导致实际列数比预期少
- 核对现有Sqoop命令的配置匹配度
当前命令配置存在两个容易触发解析错位的疏漏:- 仅配置了
--input-null-string '',未配套配置--input-null-non-string '',非字符串类型字段的空值无法正确映射,容易触发解析逻辑异常 - 空值映射规则和实际数据的空值表示不对齐:如果导出文件内的空值实际为
\N、NULL类的固定标识,将空字符串映射为null的规则就会失效,进一步导致字段值错位
- 仅配置了
- 利用已开启的错误转储配置定位精准问题行
命令中已经配置了-Dorg.apache.sqoop.export.text.dump_data_on_error=true,对应报错map task的运行日志中,会直接打印触发解析失败的原始数据行。可通过Yarn控制台找到对应任务attempt的日志,搜索Failed to parse input关键字,直接获取出错的原始行内容,无需全量逐行扫描排查。 - 针对性补充容错配置
排查确认问题后可对应调整参数:- 如果导出文件包含表头,增加
--skip-header参数跳过首行表头,避免表头被作为数据行解析 - 按照实际数据的空值表示,补充
--input-null-non-string配置,对齐非字符串字段的空值映射规则 - 校验
--direct模式下的本地数据加载逻辑,确保本地加载使用的分隔符规则和文本解析的分隔符规则完全一致
- 如果导出文件包含表头,增加
内容的提问来源于stack exchange,提问作者arsh
相关产品推荐
相关产品推荐

