2018-09-11期 Sqoop将关系型数据导入到HDFS文件系统【高级使用】

1、指定导入到HDFS文件系统中数据分隔符,默认使用逗号进行分隔

示例以制表符"\t"进行分隔

[root@hadoop-server01 lib]#  sqoop import --connect jdbc:mysql://hadoop-server03:3306/sakila --username sqoop --password hive#2018 --table actor --fields-terminated-by '\t'

[root@hadoop-server01 lihadoop fs -ls /user/root/actor

Found 5 items

-rw-r--r--   1 root supergroup          0 2018-07-09 06:20 /user/root/actor/_SUCCESS

-rw-r--r--   1 root supergroup       1911 2018-07-09 06:20 /user/root/actor/part-m-00000

-rw-r--r--   1 root supergroup       1929 2018-07-09 06:20 /user/root/actor/part-m-00001

-rw-r--r--   1 root supergroup       1978 2018-07-09 06:20 /user/root/actor/part-m-00002

-rw-r--r--   1 root supergroup       1981 2018-07-09 06:20 /user/root/actor/part-m-00003

[root@hadoop-server01 lib]# hadoop fs -cat /user/root/actor/part-m-00000

1       PENELOPE        GUINESS 2006-02-15 04:34:33.0

2       NICK    WAHLBERG        2006-02-15 04:34:33.0

3       ED      CHASE   2006-02-15 04:34:33.0

4       JENNIFER        DAVIS   2006-02-15 04:34:33.0

...省略数据

2、指定导入到HDFS文件系统中数据输出路径

[root@hadoop-server01 lib]#  sqoop import --connect jdbc:mysql://hadoop-server03:3306/sakila --username sqoop --password hive#2018 --table actor  --target-dir '/mysql/actor1' --fields-terminated-by ','

如下所示,没有采用默认输出路径,使用了我们指定的输出路径 /mysql/actor1

[root@hadoop-server01 lib]# hadoop fs -ls /mysql/actor1

Found 5 items

-rw-r--r--   1 root supergroup          0 2018-07-09 06:24 /mysql/actor1/_SUCCESS

-rw-r--r--   1 root supergroup       1911 2018-07-09 06:24 /mysql/actor1/part-m-00000

-rw-r--r--   1 root supergroup       1929 2018-07-09 06:24 /mysql/actor1/part-m-00001

-rw-r--r--   1 root supergroup       1978 2018-07-09 06:24 /mysql/actor1/part-m-00002

-rw-r--r--   1 root supergroup       1981 2018-07-09 06:24 /mysql/actor1/part-m-00003

3、指定MapTask数量,通过指定MapTask数量,可以灵活控制执行的MapTask线程数,可以根据输入迁移表大小合理控制程序执行效率,使用 -m number参数

[root@hadoop-server01 lib]#  sqoop import --connect jdbc:mysql://hadoop-server03:3306/sakila --username sqoop --password hive#2018 --table actor  --target-dir '/mysql/actor2' --fields-terminated-by ',' -m 2

这里指定-m 2 表示采用2个MapTask线程执行。

18/07/09 06:28:14 INFO mapreduce.JobSubmitter: number of splits:2 表示控制生效,采用了2个MapTask线程执行

[root@hadoop-server01 lib]# hadoop fs -ls /mysql/actor2

Found 3 items

-rw-r--r--   1 root supergroup          0 2018-07-09 06:28 /mysql/actor2/_SUCCESS

-rw-r--r--   1 root supergroup       3840 2018-07-09 06:28 /mysql/actor2/part-m-00000

-rw-r--r--   1 root supergroup       3959 2018-07-09 06:28 /mysql/actor2/part-m-00001

输出为2个文件,说明指定MapTask参数生效

4、增加where条件进行数据迁移

[root@hadoop-server01 lib]# sqoop import --connect jdbc:mysql://hadoop-server03:3306/sakila --username sqoop --password hive#2018 --table actor  --target-dir '/mysql/actor3' --fields-terminated-by ',' -m 1 --where 'actor_id between 20 and 50'

[root@hadoop-server01 lib]# hadoop fs -ls /mysql/actor3

Found 2 items

-rw-r--r--   1 root supergroup          0 2018-07-09 06:36 /mysql/actor3/_SUCCESS

-rw-r--r--   1 root supergroup       1193 2018-07-09 06:36 /mysql/actor3/part-m-00000

[root@hadoop-server01 lib]# hadoop fs -cat /mysql/actor3/part-m-00000

20,LUCILLE,TRACY,2006-02-15 04:34:33.0

21,KIRSTEN,PALTROW,2006-02-15 04:34:33.0

22,ELVIS,MARX,2006-02-15 04:34:33.0

.....省略部分数据

47,JULIA,BARRYMORE,2006-02-15 04:34:33.0

48,FRANCES,DAY-LEWIS,2006-02-15 04:34:33.0

49,ANNE,CRONYN,2006-02-15 04:34:33.0

50,NATALIE,HOPKINS,2006-02-15 04:34:33.0

输出符合过滤条件

5、query语句

query语句更为灵活,可以根据自定义导入字段,而不必导入全部字段

sqoop import --connect jdbc:mysql://hadoop-server03:3306/sakila --username sqoop --password hive#2018  --target-dir '/mysql/actor3' --fields-terminated-by ',' -m 2 --query "SELECT actor_id,first_name,last_name FROM actor where first_name like 'D%' AND \$CONDITIONS" --split-by actor.first_name

说明:--query这个参数中的sql语句后面需要加上AND $CONDITIONS这个参数

 --split-by actor. 指定按表的哪个字段进行分片,格式为--split-by ${tablename.column},若指定的-m 参数为1,则无需指定 --split-by参数,因为默认为一个分片。

特别注意点:--query参数和--table参数互斥,指定了--query参数后不能再指定--table参数

[root@hadoop-server01 lib]# hadoop fs -ls /mysql/actor3

Found 3 items

-rw-r--r--   1 root supergroup          0 2018-07-09 07:12 /mysql/actor3/_SUCCESS

-rw-r--r--   1 root supergroup         96 2018-07-09 07:12 /mysql/actor3/part-m-00000

-rw-r--r--   1 root supergroup         17 2018-07-09 07:12 /mysql/actor3/part-m-00001

[root@hadoop-server01 lib]# hadoop fs -cat /mysql/actor3/part-m-00000

18,DAN,TORN

56,DAN,HARRIS

95,DARYL,WAHLBERG

116,DAN,STREEP

129,DARYL,CRAWFORD

182,DEBBIE,AKROYD

[root@hadoop-server01 lib]# hadoop fs -cat /mysql/actor3/part-m-00001

59,DUSTIN,TAUTOU

从导入结果可以看出满足SQL查询条件,把first_name中以D开头名字全部查询出来。且按照first_name字段进行了分片

6、压缩参数

如果想要使得导入到hdfs上的数据被压缩,就可以使用-z或者--compression-codec来进行压缩,-z压缩方式是gzip压缩,--compression-codec可以自定义压缩方式

sqoop import --connect jdbc:mysql://hadoop-server03:3306/sakila --username sqoop --password hive#2018 --table actor  --target-dir '/mysql/actor6' --fields-terminated-by ','  -z

[root@hadoop-server01 lib]# hadoop fs -ls /mysql/actor6

Found 5 items

-rw-r--r--   1 root supergroup          0 2018-07-09 07:19 /mysql/actor6/_SUCCESS

-rw-r--r--   1 root supergroup        584 2018-07-09 07:19 /mysql/actor6/part-m-00000.gz

-rw-r--r--   1 root supergroup        571 2018-07-09 07:19 /mysql/actor6/part-m-00001.gz

-rw-r--r--   1 root supergroup        570 2018-07-09 07:19 /mysql/actor6/part-m-00002.gz

-rw-r--r--   1 root supergroup        580 2018-07-09 07:19 /mysql/actor6/part-m-00003.gz

使用Snappy方式压缩

sqoop import --connect jdbc:mysql://hadoop-server03:3306/sakila --username sqoop --password hive#2018 --table actor  --target-dir '/mysql/actor6' --fields-terminated-by ',' --compression-codec org.apache.hadoop.io.compress.SnappyCodec

自定义压缩

7、delete-target-dir参数

当再次执行sqoop语句的时候,会报错,因为 /mysql/actor6文件夹已经存在了,我们需要先删除这个文件夹再运行sqoop语句。也可以使用sqoop提供的delete-target-dir参数。

sqoop import --connect jdbc:mysql://hadoop-server03:3306/sakila --username sqoop --password hive#2018 --table actor  --target-dir '/mysql/actor6' --fields-terminated-by ','  --delete-target-dir

8、append参数

如果目标文件夹在hdfs上已经存在,那么再次运行就会报错。可以使用--delete-target-dir来先删除目录。也可以使用append来往目录下追加数据。append和delete-target-dir是相互冲突的。

sqoop import --connect jdbc:mysql://hadoop-server03:3306/sakila --username sqoop --password hive#2018 --table actor  --target-dir '/mysql/actor6' --fields-terminated-by ',' --append

[root@hadoop-server01 lib]# hadoop fs -ls /mysql/actor6

Found 9 items

-rw-r--r--   1 root supergroup          0 2018-07-09 07:22 /mysql/actor6/_SUCCESS

-rw-r--r--   1 root supergroup       1911 2018-07-09 07:22 /mysql/actor6/part-m-00000

-rw-r--r--   1 root supergroup       1929 2018-07-09 07:22 /mysql/actor6/part-m-00001

-rw-r--r--   1 root supergroup       1978 2018-07-09 07:22 /mysql/actor6/part-m-00002

-rw-r--r--   1 root supergroup       1981 2018-07-09 07:22 /mysql/actor6/part-m-00003

-rw-r--r--   1 root supergroup       1911 2018-07-09 07:24 /mysql/actor6/part-m-00004

-rw-r--r--   1 root supergroup       1929 2018-07-09 07:24 /mysql/actor6/part-m-00005

-rw-r--r--   1 root supergroup       1978 2018-07-09 07:24 /mysql/actor6/part-m-00006

-rw-r--r--   1 root supergroup       1981 2018-07-09 07:24 /mysql/actor6/part-m-00007

4、5、6、7为append的文件

9、空值处理

sqoop提供了--null-string来处理字符类型的空值,提供了--null-non-string来处理非字符类型的空值。

sqoop import --connect jdbc:mysql://hadoop-server03:3306/sakila --username sqoop --password hive#2018 --table actor  --target-dir '/mysql/actor6' --fields-terminated-by ',' --null-string "" --null-non-string "false"

10、增量传输

增量导入的一个场景就是昨天导入了一批数据,今天又增加了部分数据,现在要把这部分数据也导入到hdfs中。

sqoop import --connect jdbc:mysql://hadoop-server03:3306/sakila --username sqoop --password hive#2018 --table actor  --target-dir '/mysql/actor8' --fields-terminated-by ',' -m 1 --where 'actor_id between 20 and 25' --check-column "actor_id" --incremental append --last-value 5

Incremental import arguments:

  --check-column <column>     Source column to check for incremental change

  --incremental <import-type>    Define an incremental import of type 'append' or 'lastmodified'

  --last-value <value>                Last imported value in the incremental check column

sqoop import --connect jdbc:mysql://hadoop-server03:3306/sakila --username sqoop --password hive#2018 --table actor  --target-dir '/mysql/actor9' --fields-terminated-by ',' -m 1

.......省略开头数据

196,BELA,WALKEN,2006-02-15 04:34:33.0

197,REESE,WEST,2006-02-15 04:34:33.0

198,MARY,KEITEL,2006-02-15 04:34:33.0

199,JULIA,FAWCETT,2006-02-15 04:34:33.0

200,THORA,TEMPLE,2006-02-15 04:34:33.0

现在模拟在表中插入部分新增数据

mysql> insert into actor values (201,'Zhangsan','Zhang',' 2006-02-15 04:34:12');

Query OK, 1 row affected (0.02 sec)

mysql> insert into actor values (202,'Lisi','Lo',' 2006-02-15 04:34:12');              

Query OK, 1 row affected (0.01 sec)

mysql> flush privileges;

Query OK, 0 rows affected (0.03 sec)

mysql>

|      201 | Zhangsan    | Zhang        | 2006-02-15 04:34:12 |

|      202 | Lisi        | Lo           | 2006-02-15 04:34:12 |

+----------+-------------+--------------+---------------------+

现在执行

sqoop import --connect jdbc:mysql://hadoop-server03:3306/sakila --username sqoop --password hive#2018 --table actor  --target-dir '/mysql/actor9' --fields-terminated-by ',' -m 1 --check-column "actor_id" --incremental append --last-value 200

[root@hadoop-server01 lib]# hadoop fs -cat /mysql/actor9/part-m-00001  

201,Zhangsan,Zhang,2006-02-15 04:34:12.0

202,Lisi,Lo,2006-02-15 04:34:12.0

可以看出,新的输出文件中只增加了我们在mysql中新增的两条数据,这里 --last-value 200值增量的检查列的值,这里的200就是增量actor_id=201前一个值


猜你喜欢

转载自blog.51cto.com/2951890/2173703