Sqoop import导入MySQL数据到S3报SAX驱动初始化异常如何解决
问题现象
使用sqoop import将MySQL数据导入S3时任务执行失败,核心报错信息如下:
ERROR tool.ImportTool: Import failed: org.apache.hadoop.fs.s3a.AWSClientIOException: getFileStatus on tmp/tb_room_type3/: com.amazonaws.SdkClientException: Couldn't initialize a SAX driver to create an XMLReader: Couldn't initialize a SAX driver to create an XMLReader, ..., Caused by: org.xml.sax.SAXNotRecognizedException: Feature 'http://xml.org/sax/features/external-general-entities' is not recognized.
本次执行的导入命令如下:
sqoop import \ --connect jdbc:mysql://address/mydatabase \ --username xxx\ --password xxx\ --table tb_room_type \ --target-dir s3a://my-bucket/tmp/tb_room_type2/ \ --hive-table tb_room_type2 \ --hive-database mydatabase \ --fields-terminated-by "," \ --hive-import --m 1 \ --hive-overwrite
根因分析
该报错属于XML解析器版本冲突:AWS SDK初始化S3客户端时,会默认开启XXE安全防护,需要调用SAX驱动设置外部实体禁用的特性参数,但当前Sqoop运行时的classpath下加载了不兼容的低版本XML解析包(多为低版本xercesImpl、xml-apis包),这类旧版本解析器不识别该安全特性参数,直接抛出异常导致任务失败。
排查步骤
- 扫描运行环境classpath下所有XML解析相关包,定位冲突来源:
# 遍历Sqoop、Hadoop、Hive的lib目录,查找xerces、xml-apis相关jar包 find $SQOOP_HOME/lib $HADOOP_HOME/share/hadoop $HIVE_HOME/lib -name "*xerces*" -o -name "*xml-apis*" | sort - 核对当前集群部署的
hadoop-aws包对应依赖的AWS SDK版本,确认其兼容的xerces包版本要求,和上一步查到的实际加载包版本做对比。 - 优先排查Sqoop自身lib目录下的第三方包,绝大多数这类冲突都是Sqoop自带的低版本xerces包优先级高于Hadoop提供的高版本包被加载导致。
解决方案
按优先级从高到低尝试以下方案:
- 移除冲突的低版本解析包
找到版本低于2.12.0的xercesImpl、xml-apis包,将其移出公共lib目录(可移动到备份目录,不要直接删除避免误删),保证运行时加载的是和AWS SDK版本兼容的高版本解析包。注意:如果是CDH/HDP等商业发行版集群,不要修改Hadoop、Hive公共lib目录下的原生自带包,优先处理Sqoop lib目录下额外引入的第三方冲突包,避免影响其他组件正常运行。
- 显式指定JVM使用内置SAX驱动
如果不方便直接移除jar包,可以在执行sqoop命令前配置环境变量,强制JVM使用JDK内置的SAX解析实现,绕开第三方低版本包的冲突:
配置完成后直接重新执行原导入命令即可。export SQOOP_OPTS="$SQOOP_OPTS -Djavax.xml.parsers.SAXParserFactory=com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl" - 依赖版本对齐校验
确认集群使用的hadoop-aws包版本和当前Hadoop大版本完全一致,禁止跨大版本混用hadoop-aws包,避免连带引入版本不匹配的AWS SDK依赖触发解析器冲突。
内容的提问来源于stack exchange,提问作者littlely
相关产品推荐
相关产品推荐

