由于Sqoop在使用时不需要编程,主要依赖环境配置以及运行参数,所以也导致很多问题出现的时候只能通过报错信息来进行排查,本篇文章整理了一些常见问题以及生产环境中会采用的做法。
一、运行异常
1. 程序卡死
程序卡死的实际表现是Sqoop启动后,在准备阶段没有任何报错,但是也无法继续运行。这个问题产生的主要原因是分配给Hadoop运行任务的最大内存不足,主要的体现是有些数据操作可以执行成功而有些不行。此时需要修改Hadoop的yarn-site.xml,修改yarn.nodemanager.resource.memory-mb的值【单位是MB】,如下:
<property> <name>yarn.nodemanager.resource.memory-mb</name> <value>3072</value> </property>
2. 环境缺失
在使用Hadoop 3.x版本运行时,可能会遇到以下问题【小编的印象中Hadoop 2.x未出现过类似问题】:
这个问题是因为在运行过程中未能正确的找到依赖,可以通过配置classpath解决,修改yarn-site.xml的yarn.application.classpath属性值:
<property> <name>yarn.application.classpath</name> <value>/home/hadoop/hadoop-3.3.5/etc/hadoop:/home/hadoop/hadoop-3.3.5/share/hadoop/common/lib/*:/home/hadoop/hadoop-3.3.5/share/hadoop/common/*:/home/hadoop/hadoop-3.3.5/share/hadoop/hdfs:/home/hadoop/hadoop-3.3.5/share/hadoop/hdfs/lib/*:/home/hadoop/hadoop-3.3.5/share/hadoop/hdfs/*:/home/hadoop/hadoop-3.3.5/share/hadoop/mapreduce/*:/home/hadoop/hadoop-3.3.5/share/hadoop/yarn:/home/hadoop/hadoop-3.3.5/share/hadoop/yarn/lib/*:/home/hadoop/hadoop-3.3.5/share/hadoop/yarn/*</value> </property>
需要将其中的 /home/hadoop/hadoop-3.3.5 替换为自己的Hadoop安装路径根目录。
3. 其它异常
其它的导入失败问题一般是参数设置、数据源连接、Hive配置等问题导致的,可以参考:Sqoop的安装及使用。
二、参数过长
在使用Sqoop命令时,通常涉及到多个参数,不利于维护,并且可读性不高。一般会将所有的参数放在一个文件中,然后通过 options-file 参数指定一个配置文件,使用方式入下:
1. 创建配置文件
新建一个conf文件,如user_info_hive.conf:
--connect jdbc:mysql://localhost:3306/test --username root --password root --table user_info --columns "id,name,age" --hive-import --hive-database test --hive-table user_info --hive-overwrite --delete-target-dir --m 1
各配置项与值各成一行,如果没有需要配置的值,则单独成行。
2. 程序执行规则
对于sqoop命令而言,以两个横杠开头的指令都可以视为参数,在调用时将import/export以及 -Dorg.apache.sqoop.xxx 参数作为执行命令,其它的所有参数都可以放在文件中。使用以下命令执行:
sqoop import --options-file user_info_hive.conf
三、条件查询
有很多时候,数据不需要全量导入,或者在导入时需要拼接一些其它的列等,这个时候可以使用SQL语句的方式获得结果集,然后再进行导入。这个时候如果使用自动建表,即导入之前Hive中没有对应的表,则需要注意一下查询结果中列名的写法或者先进行建表,再进行导入。如果使用手动建表,需要保证新建的数据表与要导入的数据的结构是匹配的。
sqoop import \ --connect jdbc:mysql://localhost:3306/test \ --username root \ --password root \ --query "select id,name,age from user_info where id > 3 and \$CONDITIONS" \ --hive-import \ --hive-database test \ --hive-table user_info \ --hive-overwrite \ --target-dir /tmp/user_info \ --delete-target-dir \ --split-by id
- query:用于引导一个查询语句,语句中必须包含 $CONDITIONS ,前方的斜杠用于转义【某些数据库需要】。
- target-dir:如果使用query的方式获取数据,则需要指定一个路径存放临时数据,导入成功后会自动删除。
- split-by:指定一个列用于任务的分割,一般为纯数字的主键,会执行MAX以及MIN操作来分割数据区间。该列必须包含在最终的结果列中,如果是一个非整数列,则需要添加额外参数,见下文。
四、空值处理
数据中如果出现空值,则在Hive导入时应该额外指定对空值要如何处理。在默认情况下,会以null的字符串形式写入,这会导致is null的判断失效,需要额外添加以下两个参数:
--null-string '\\N' --null-non-string '\\N'
五、特殊密码
在生产环境中,数据库的密码通常强度较高,很有可能使用到各种符号,有时会影响到命令的正常解析。无论是使用命令直接执行,还是使用文件的方式执行都会遇到问题,这个时候需要使用 –password-file 从文件中读取密码,并且这个密码文件需要特别写入。
1. 密码文件生成
首先使用echo命令将密码写入文件,如果手动编辑会产生换行符,将会导致密码不匹配。在使用echo时也需要添加 -n 参数,如:
echo -n '123|:5y!678Aa' > password.file
2. 密码文件指定
在执行命令时使用如下写法指定从本地磁盘路径读取【不添加file协议时则从HDFS读取】:
--password-file file:///home/hadoop/password.file
六、额外参数
1. 修改临时路径
Sqoop运行时,会生成一个对应的java程序,并且向Hadoop提交一个Jar包,开始运行一个MR任务。这个过程中还会产生很多临时文件及日志,通常情况下不会出现问题,但是如果开启了较为严格的权限管理,当前的账号对默认的HDFS写入路径没有操作权限时,可以更改路径,需要通过运行参数实现。
sqoop import "-Dmapreduce.jobhistory.intermediate-done-dir=/user/tmp/history/intermediate" "-Dmapreduce.jobhistory.done-dir=/user/tmp/history/done" xxx
一般只需要指定这两个路径即可,每个执行参数放在单独的双引号中,用空格隔开。
2. 非整数主键列
如果数据源使用的主键并不是纯数字类型的,则需要在执行时开启allow_text_splitter,写法如下:
sqoop import "-Dorg.apache.sqoop.splitter.allow_text_splitter=true" xxx