sqoop常用命令三 ---- import导入 与export 覆盖更新,常见问题总结

一.参数说明
1.import/export通用
选项         含义说明
--connect <jdbc-uri> 指定JDBC连接字符串
--connection-manager <class-name> 指定要使用的连接管理器类
--driver <class-name> 指定要使用的JDBC驱动类
--hadoop-mapred-home <dir> 指定$HADOOP_MAPRED_HOME路径
--help 打印用法帮助信息
--password-file 设置用于存放认证的密码信息文件的路径
-P 从控制台读取输入的密码
--password <password> 设置认证密码
--username <username> 设置认证用户名
--verbose 打印详细的运行信息
--connection-param-file <filename> 可选,指定存储数据库连接参数的属性文件
2.import
选项              含义说明
--append 将数据追加到HDFS上一个已存在的数据集上
--as-avrodatafile 将数据导入到Avro数据文件
--as-sequencefile 将数据导入到SequenceFile
--as-textfile 将数据导入到普通文本文件(默认)
--boundary-query <statement> 边界查询,用于创建分片(InputSplit)
--columns <col,col,col…> 从表中导出指定的一组列的数据
--delete-target-dir 如果指定目录存在,则先删除掉
--direct 使用直接导入模式(优化导入速度)
--direct-split-size <n> 分割输入stream的字节大小(在直接导入模式下)
--fetch-size <n> 从数据库中批量读取记录数
--inline-lob-limit <n> 设置内联的LOB对象的大小
-m,--num-mappers <n> 使用n个map任务并行导入数据
-e,--query <statement> 导入的查询语句
--split-by <column-name> 指定按照哪个列去分割数据
--table <table-name> 导入的源表表名
--target-dir <dir> 导入HDFS的目标路径
--warehouse-dir <dir> HDFS存放表的根路径
--where <where clause> 指定导出时所使用的查询条件
-z,--compress 启用压缩
--compression-codec <c> 指定Hadoop的codec方式(默认gzip)
--null-string <null-string> 果指定列为字符串类型,使用指定字符串替换值为null的该类列的值
--null-non-string <null-string> 如果指定列为非字符串类型,使用指定字符串替换值为null的该类列的值
 3.export
选项 含义说明
--validate <class-name> 启用数据副本验证功能,仅支持单表拷贝,可以指定验证使用的实现类
--validation-threshold <class-name> 指定验证门限所使用的类
--direct 使用直接导出模式(优化速度)
--export-dir <dir> 导出过程中HDFS源路径
-m,--num-mappers <n> 使用n个map任务并行导出
--table <table-name> 导出的目的表名称
--call <stored-proc-name> 导出数据调用的指定存储过程名
--update-key <col-name> 更新参考的列名称,多个列名使用逗号分隔
--update-mode <mode> 指定更新策略,包括:updateonly(默认)、allowinsert
--input-null-string <null-string> 使用指定字符串,替换字符串类型值为null的列
--input-null-non-string <null-string> 使用指定字符串,替换非字符串类型值为null的列
--staging-table <staging-table-name> 在数据导出到数据库之前,数据临时存放的表名称
--clear-staging-table 清除工作区中临时存放的数据
--batch 使用批量模式导出

二.导入import
参照上表,列举常用的命令,使用 sql 语句查询时,需要指定 $CONDITIONS
$ sqoop import --connect jdbc:mysql://192.168.56.121:3306/metastore --username hiveuser --password redhat --query 'SELECT * from TBLS where $CONDITIONS ' --split-by tbl_id -m 4 --target-dir /user/hive/result
上面命令通过 -m 1 控制并发的 map 数。
使用 direct 模式:
$ sqoop import --connect jdbc:mysql://192.168.56.121:3306/metastore --username hiveuser --password redhat --table TBLS --delete-target-dir --direct --default-character-set UTF-8 --target-dir /user/hive/result
指定文件输出格式:
$ sqoop import --connect jdbc:mysql://192.168.56.121:3306/metastore --username hiveuser --password redhat --table TBLS --fields-terminated-by " " --lines-terminated-by " " --delete-target-dir --target-dir /user/hive/result

指定空字符串:
$ sqoop import --connect jdbc:mysql://192.168.56.121:3306/metastore --username hiveuser --password redhat --table TBLS --fields-terminated-by " " --lines-terminated-by " " --delete-target-dir --null-string '\N' --null-non-string '\N' --target-dir /user/hive/result
如果需要指定压缩:

$ sqoop import --connect jdbc:mysql://192.168.56.121:3306/metastore --username hiveuser --password redhat --table TBLS --fields-terminated-by " " --lines-terminated-by " " --delete-target-dir --null-string '\N' --null-non-string '\N' --compression-codec "com.hadoop.compression.lzo.LzopCodec" --target-dir /user/hive/result

三.导出export
在增量导出模式下,无论是allowinsert模式还是updateonly模式,都需要设置update-key:

1.allowinsert模式:该模式下生成的是insert语句,从这个角度讲update-key是没有作用的,但是在CDH Sandbox上测试时发现,如果不指定update-key则会导致reduce执行失败。

2. updateonly模式:该模式下生成的是update语句,update-key中指定的字段用于构成update语句中的where字句,因此是必须的,同时也可以看出选择的update-key字段必须是未被更新的字段,这样才能确定一条记录导出前后是否一致,而如果将update-key设置为被更新过的字段,则在目标表中通过where条件筛选不到匹配的记录,从而造成数据无法被更新。此外,如果update-key中指定了所有字段,也会报错。
参数介绍
--update-key 后面也可以接多个关键字列名,可以使用逗号隔开,Sqoop将会匹配多个关键字后再执行更新操作。
--export-dir 参数配合--table或者--call参数使用,指定了HDFS上需要将数据导入到MySQL中的文件集目录。
--update-mode updateonly和allowinsert。 默认模式为updateonly,如果指定--update-mode模式为allowinsert,可以将目标数据库中原来不存在的数据也导入到数据库表中。即将存在的数据更新,不存在数据插入。
组合测试及说明
1、当指定update-key,且关系型数据库表存在主键时:
   A、allowinsert模式时,为更新目标数据库表存的内容,并且原来不存在的数据也导入到数据库表;
   B、updateonly模式时,为更新目标数据库表存的内容,并且原来不存在的数据也不导入到数据库表;
2、当指定update-key,且关系型数据库表不存在主键时:
   A、allowinsert模式时,为全部数据追加导入到数据库表;
   B、updateonly模式时,为更新目标数据库表存的内容,并且原来不存在的数据也不导入到数据库表;
3、当不指定update-key,且关系型数据库表存在主键时:
   A、allowinsert模式时,报主键冲突,数据无变化;
   B、updateonly模式时,报主键冲突,数据无变化;
4、当不指定update-key,且关系型数据库表不存在主键时:
   A、allowinsert模式时,为全部数据追加导入到数据库表;
   B、updateonly模式时,为全部数据追加导入到数据库表;

所以再用 不同的 --update-mode 模式时,注意关系型数据库的主键设置,否则会影响数据的导出效果。

四.常见错误:

1.使用 --update-mode allowinsert 导出时,报错

Error during export:
Mixed update/insert is not supported against the target database yet

原因:指定的Jdbc  连接器不支持 allowinsert;

解决:删除 --driver com.mysql.jdbc.Driver (如果出现新的报错 删除  --direct )   问题可以解决;

2.sqoop导出hive数据到MySQL出现字符编码问题解决

ERROR [Thread-11] org.apache.sqoop.mapreduce.AsyncSqlOutputFormat: Got exception in update thread: java.sql.SQLException: Incorrect string value: 'xF0 'itemName' at row 70;

java.sql.SQLException: Incorrect string value: 'xF0xA1xB7x8AxF0xA1...' for column 'itemName' at row 70

原因:由于MySQL表编码位数导致,解决

解决 : 1.修改表的编码格式:

alter table 表名 convert to character set utf8mb4 collate utf8mb4_bin;

ALTER TABLE 表名 CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

2.sqoop导命令指定编码格式:

export  --connect "jdbc:mysql://ip:port/库名?useUnicode=true&characterEncoding=utf-8" --username 用户民--password 密码 --table 表名 --columns "字段1,字段2,..,字段n" --export-dir "hdfs:// 路径" --fields-terminated-by ' ' --input-null-string '\N' --input-null-non-string '\N' -m 1 --driver com.mysql.jdbc.Driver;

重新执行导出命令,成功!(前提确保数据库编码是UTF8);

(遇到问题不断更新。。。)


————————————————
版权声明:本文为CSDN博主「D·Virus」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_35281775/article/details/92794295

原文地址:https://www.cnblogs.com/javalinux/p/14944561.html