sqoop参数详解(全量、增量导入导出)

一、全量导入

从RDBMS到HIVE:

sqoop import \
--connect  jdbc:oracle:thin:@//192.168.156.111/test
--username test
--password test
--query select * from it.t_test where inserttime >= to_date('${date1}','yyyy-mm-dd') and inserttime < to_date('${date2}','yyyy-mm-dd') and $CONDITIONS
--hive-overwrite
--hive-table it.test
--target-dir hdfs://ns1/user/hive/warehouse/it.db/t_test
--null-string \\N
-null-non-string \\N
--fields-terminated-by \001
--delete-target-dir
--split-by emp_no
-m
1

1.参数详解:

 	--connect 关系型数据库连接

  --username 关系型数据库连接用户名

  --password 关系型数据库连接密码

  --table 关系型数据库表

  --query 自定义sql查询,sql结束要加$CONDITIONS

  --hive-overwrite 覆盖之前的分区写入数据

  --hive-drop-import-delims 导入hive的数据某列中如果有换行符或者回车键可以删除
 
 	--hive-database  hive的数据库

  --hive-table	  hive的表

  --hive-partition-key hive的分区字段

  --hive-partition-value hive的分区值

  --fields-terminated-by 导入到hdfs时,hdfs文件的分隔符

  --input-fields-terminated-by 从hdfs导出时,hdfs文件的分隔符

  --export-dir 从hdfs导出时的源目录

  --target-dir HDFS目标目录
  				(确保目录不存在,否则会报错,因为Sqoop在导入数据至HDFS时会自己在HDFS上创建目录)

  --delete-target-dir 如果hdfs的目录已经存在,则先删除

  --direct 快速模式,使用mysql自带的mysqldump导出数据

  --split-by  数据切片,如果-m参数不为1,必须指定该参数否则会报错

  -m 指定map的数量,也是生成文件的数量(默认为4)

hive 到数据库

2. 补充:参数-m和–split-by用法

–split-by 一般和参数-m放在一起使用,-m表示使用几个map并发执行,–split-by表示拆分数据的字段。

举例:

--split-by :拆分数据的字段. -m设置为4,数据有100条,sqoop首先会获取拆分字段的最大值,最小值,
步长为100/4=25;

那么第一个map执行拆分字段值为(1,25)之间的数据

第二个map执行拆分字段值为(26,50)之间的数据

第三个map执行拆分字段值为(51,75)之间的数据

第四个map执行拆分字段值为(76,100)之间的数据

注意事项:

1.拆分字段默认为主键

2.拆分字段的数据类型最好为int,如果不是则将-m设置为1,split-by不设置

3.拆分字段的值最好分布均匀,否则会造成数据倾斜的问题

3、常见数据库导入

(1)从Mysql导入

sqoop import \
--connect jdbc:mysql://服务器地址:3306/数据库名 \
--username 账号 \
--password 密码 \
--table 表名 \
--fields-terminated-by "," \
--lines-terminated-by "\n" \
--hive-import \
--hive-database 数仓中库名 \
--hive-table 数仓中表名 \
--hive-overwrite

举例:

扫描二维码关注公众号,回复: 11037043 查看本文章
#1、全量导入 合同表lnk_agreement:
sqoop import \
--connect jdbc:mysql://172.30.2.217:3306/linkcrm \
--username biuser \
--password 123456 \
--table lnk_agreement \
--fields-terminated-by "," \
--lines-terminated-by "\n" \
--hive-import \
--hive-database test_ods \
--hive-table ods_lnk_agreement \
--hive-overwrite;

说明:从mysql(地址为172.30.2.217,端口3306,账号密码为biuser/123456)的源数据库,导入表到hive中;

源数据库名:linkcrm,
表名:lnk_agreement

hive中数据库名:crm_ods(这个需要先提前在hive中创建)
表名:ods_lnk_agreement(自动生成,不需要建)

(2)从Oracle导入

#全量导入(不需要提前建表,自动生成表,后续增量会覆盖)
#销售主表B2B_SALE_ORDER
sqoop import --hive-import \
--connect jdbc:oracle:thin:@172.31.13.27:1521/xtpdg \
--username=dmuser \
--password=kWV8xudDIic= \
--table MPLATFORM.B2B_SALE_ORDER \
--hive-database test_ods \
--hive-table ods_B2B_SALE_ORDER \
--hive-overwrite -m 1 \
--compression-codec org.apache.hadoop.io.compress.SnappyCodec \
--null-string '\\N' \
--null-non-string '\\N';

#query方式全量导入
#产品基础表
sqoop import --hive-import \
--connect jdbc:oracle:thin:@172.31.13.27:1521/xtpdg \
--username=dmuser \
--password=kWV8xudDIic= \
--direct \
--query "select  * from MPLATFORM.BASE_PRODUCT_INFO where \$CONDITIONS" \
--target-dir /test01/ods_tmp/ods_BASE_PRODUCT_INFO/ \
--hive-database test_ods \
--hive-table ods_BASE_PRODUCT_INFO \
--hive-overwrite \
--compression-codec org.apache.hadoop.io.compress.SnappyCodec \
--null-string '\\N' \
--null-non-string '\\N' \
-m 1 ;

(3)从SqlServer导入

#全量导入方式
#AD人员表
sqoop import --driver com.microsoft.sqlserver.jdbc.SQLServerDriver \
--connect "jdbc:sqlserver://172.30.3.93:1433;username=dds_user;password=dds_user;database=Ultimus2017Biz;selectMethod=cursor" \
--table ORG_USER --hive-table test_ods.ods_ORG_USER \
--hive-import -m 1 \
--hive-overwrite \
--input-null-string '\\N' \
--input-null-non-string '\\N' \
--null-string '\\N' \
--null-non-string '\\N'  \
--hive-drop-import-delims \
--fields-terminated-by '\0001';

#query方式导入
#场景:个别字段过长容易失败可以选择query导入,指定条件和字段)
#流程实例表(xml格式的列不支持)
sqoop import --driver com.microsoft.sqlserver.jdbc.SQLServerDriver \
--connect "jdbc:sqlserver://172.30.3.93:1433; username=dds_user;password=dds_user;database=Ultimus2017Server;selectMethod=cursor" \
--query 'select PROCESSNAME,INCIDENT,SUMMARY,STARTTIME,ENDTIME,STATUS,INITIATOR,TIMELIMIT from INCIDENTS WHERE $CONDITIONS' \
--target-dir /test01/ods_tmp \
--hive-table test_ods.ods_INCIDENTS --hive-import -m 1 --hive-overwrite \
--input-null-string '\\N' --input-null-non-string '\\N' \
--null-string '\\N' \
--null-non-string '\\N'  \
--hive-drop-import-delims --fields-terminated-by '\0001' ;

#优化,引入--delete-target-dir参数代表指定目录如果存在先删除目录再重新创建
#ods_INCIDENTS流程实例表
sqoop import --driver com.microsoft.sqlserver.jdbc.SQLServerDriver \
--connect "jdbc:sqlserver://172.31.12.41:1433; username=dds_user;password=dds_user;database=Ultimus2017Server;selectMethod=cursor" \
--query 'select PROCESSNAME,INCIDENT,SUMMARY,STARTTIME,ENDTIME,STATUS,INITIATOR,TIMELIMIT from INCIDENTS WHERE $CONDITIONS' \
--target-dir /test01/ods_tmp \
--delete-target-dir  \
--hive-table test01.ods_INCIDENTS --hive-import -m 1 --hive-overwrite \
--input-null-string '\\N' --input-null-non-string '\\N' \
--null-string '\\N' \
--null-non-string '\\N'  \
--hive-drop-import-delims --fields-terminated-by '\0001' ;

二、增量导入

事实上,在生产环境中,系统可能会定期从与业务相关的关系型数据库向Hadoop导入数据,导入数仓后进行后续离线分析。故我们此时不可能再将所有数据重新导一遍,此时我们就需要增量数据导入这一模式了
增量数据导入分两种,一是基于递增列的增量数据导入(Append方式)。二是基于时间列的增量数据导入(LastModified方式)

1、Append方式

举个栗子,有一个订单表,里面每个订单有一个唯一标识自增列ID,在关系型数据库中以主键形式存在。之前已经将id在0~5201314之间的编号的订单导入到Hadoop中了(这里为HDFS),现在一段时间后我们需要将近期产生的新的订单数据导入Hadoop中(这里为HDFS),以供后续数仓进行分析。此时我们只需要指定–incremental 参数为append,–last-value参数为5201314即可。表示只从id大于5201314后开始导入。

# Append方式的全量数据导入
 sqoop import \
   --connect jdbc:mysql://192.168.xxx.xxx:3316/testdb \
   --username root \
   --password 123456 \
   --query “select order_id, name from order_table where \$CONDITIONS” \
   --target-dir /user/root/orders_all \ 
   --split-by order_id \
   -m 6  \
   --incremental append \
   --check-column order_id \
   --last-value 5201314

重要参数:
incremental append 基于递增列的增量导入(将递增列值大于阈值的所有数据增量导入Hadoop)
check-column 递增列(int)
last-value 阈值(int)

说明:

增量抽取,需要指定–incremental append,同时指定按照源表中哪个字段进行增量–check-column
id,并指定hive表appendTest当前最大值–last-value 3。创建sqoop
job的目的是,每次执行job以后,sqoop会自动记录appedndTest的last-value,下次再执行时,就会自动指定last-value,不需要手工去改了。**

2、lastModify方式

此方式要求原有表中有time字段,它能指定一个时间戳,让Sqoop把该时间戳之后的数据导入至Hadoop(这里为HDFS)。因为后续订单可能状态会变化,变化后time字段时间戳也会变化,此时Sqoop依然会将相同状态更改后的订单导入HDFS,当然我们可以指定merge-key参数为orser_id,表示将后续新的记录与原有记录合并。

# 将时间列大于等于阈值的数据增量导入HDFS
 sqoop import \
   --connect jdbc:mysql://192.168.xxx.xxx:3316/testdb \
   --username root \
   --password transwarp \
   --query “select order_id, name from order_table where \$CONDITIONS” \
   --target-dir /user/root/order_all \ 
   --split-by id \
   -m 4  \
   --incremental lastmodified \
   --merge-key order_id \
   --check-column time \
   # remember this date !!!
   --last-value “2014-11-09 21:00:00”  

重要参数:
incremental lastmodified 基于时间列的增量导入(将时间列大于等于阈值的所有数据增量导入Hadoop)
check-column 时间列(int)
last-value 阈值(int)
merge-key 合并列(主键,合并键值相同的记录)

并发导入参数如何设置?
我们知道通过 -m 参数能够设置导入数据的 map 任务数量,即指定了 -m 即表示导入方式为并发导入,这时我们必须同时指定 - -split-by 参数指定根据哪一列来实现哈希分片,从而将不同分片的数据分发到不同 map 任务上去跑,避免数据倾斜。

重要Tip:

生产环境中,为了防止主库被Sqoop抽崩,我们一般从备库中抽取数据。 一般RDBMS的导出速度控制在60~80MB/s,每个 map 任务的处理速度5~10MB/s 估算,即 -m 参数一般设置4~8,表示启动 4~8 个map 任务并发抽取。

三、全量导出

应用场景: 将Hive表中的全部记录(可以是全部字段也可以部分字段)导出到目标表。
说明:

(1)导出之前要在mysql中建表,并设置id为主键!,不设主键会重复导入
(2)转译字符 \ 和代码之间要有空格
(3)后三行不写也可以实现
(4)使用限制:一般只有当目标表为空表时才使用该模式进行首次数据导出。
(5)参数:源表、目标表、导出字段(select的字段)、映射关系(–column后的参数)
(6)适用的数据库:Oracle、DB2、SQL Server、PG、MySQL

#全量导出合同表
sqoop export \
--connect jdbc:mysql://172.30.3.78:3309/CRM2020?useSSL=false \
--username ywfxuat \
--password ywfxuat123 \
--table dm_agreement \
--export-dir /user/hive/warehouse/crm_dm.db/dm_agreement/000000_0 \
--input-fields-terminated-by '\001' \
--update-key id \
--update-mode allowinsert \
--input-null-string '\\N' \
--input-null-non-string '\\N' \
--fields-terminated-by '\t';

注意:后三行参数不写也可以实现

#全量导出合同表
sqoop export \
--connect jdbc:mysql://172.30.3.78:3309/CRM2020?useSSL=false \
--username ywfxuat \
--password ywfxuat123 \
--table dm_agreement \
--export-dir /user/hive/warehouse/crm_dm.db/dm_agreement/000000_0 \
--input-fields-terminated-by '\001' \
--update-key id \
--update-mode allowinsert ;

四、增量导出(待验证)

应用场景:将Hive表中的增量记录以及有修改的记录同步到目标表中。
实现逻辑:
在这里插入图片描述
几点说明:
使用限制:update-key可以是多个字段,但这些字段的记录都应该是未被更新过的,若该参数指定的字段有更新,则对应记录的更新不会被同步到目标表中。

参数:源表、目标表、筛选字段及其取值范围、导出字段(select的字段)、映射关系(–column后的参数)、更新的参考字段(–update-key后的参数)

适用的数据库:Oracle、SQL Server、MySQL

参考脚本
全量导出
HQL示例:insert overwrite  directory ‘/user/root/export/test’ row format delimited fields terminated by,’ STORED AS textfile select F1,F2,F3 from <sourceHiveTable>;
 
SQOOP脚本:sqoop export --connect jdbc:mysql://localhost:3306/wht --username root --password cloudera --table <targetTable> --fields-terminated-by ','  --columns F1,F2,F3 --export-dir /user/root/export/test
 
增量导出(insert模式)
HQL示例:insert overwrite  directory ‘/user/root/export/test’ row format delimited fields terminated by,’ STORED AS textfile select F1,F2,F3 from <sourceHiveTable> where <condition>;
 
SQOOP脚本:sqoop export --connect jdbc:mysql://localhost:3306/wht --username root --password cloudera --table <targetTable> --fields-terminated-by ‘,’  --columns F1,F2,F3 --update-key F4 --update-mode  allowinsert --export-dir /user/root/export/test
 
 
更新导出(update模式)
HQL示例:insert overwrite  directory ‘/user/root/export/test’ row format delimited fields terminated by,’ STORED AS textfile select F1,F2,F3 from <sourceHiveTable> where <condition>;
 
SQOOP脚本:sqoop export --connect jdbc:mysql://localhost:3306/wht --username root --password cloudera --table <targetTable> --fields-terminated-by ‘,’  --columns F1,F2,F3 --update-key F4 --update-mode  updateonly --export-dir /user/root/export/test

发布了450 篇原创文章 · 获赞 120 · 访问量 20万+

猜你喜欢

转载自blog.csdn.net/ZZQHELLO2018/article/details/105216703
今日推荐