sqoop1.4.7 导入时设置并行度(--split by 和 --m参数)

介绍

当导入的数据较多时,要设置并行度,通过执行多个任务进行导入

Sqoop并行化是启动多个 map task 实现的

参数 -m 或 --num-mappers

通过设置 -m (或 --num-mappers )参数指定 map task数量,默认是4个

当该参数指定为 1 时,可以不用设置 split-by 参数

不指定该参数时,默认为 4,所以当不指定或者参数大于1时,需要指定 split-by 参数

参数 --split-by

该参数指定 split column

在执行并行操作时(多个map task),Sqoop需要知道根据哪一列拆分数据

其原理是:

  1. 先查出split column的最小值和最大值

  2. 然后根据 map task 数对(max-min)之间的数据进行均匀的范围切分

注意1

Sqoop不能在多列字段上进行拆分,如果没有索引或者有组合键,必须显示设置 split column

默认的主键作为 split column

注意2

表里没有主键或者没有指定 --split-by,就要设置 -m ,这样就只会启动一个 map task

注意3

如果 split column 不是自动增长的话,其值就不是均匀分布的,各个map分配的数据是不均衡的,可能会有些map很忙,有些map几乎没有数据处理的情况,导致数据倾斜

数据多的时候,会拉数据的时候数据库出现奔溃的情况

注意4

当 split-by 不是 int等数字类型 时,各个map分配的数据是不均衡的,可能会有些map很忙,有些map几乎没有数据处理的情况,数据多的时候,会拉数据的时候数据库出现奔溃的情况

目前想到的解决办法是:将 -m 设置为1,split-by不设置,即只有一个map运行

优化

并行度 不是设置的越大越好,因为:

  • map task 的启动和销毁都会 消耗资源
  • 过多的数据库连接对数据库本身也会造成压力

在并行操作里,要确保每个map处理的 数据量大致相同 且 数据不重复

并行数量

一般RDBMS的导出速度控制在 60~80MB/s,每个 map 任务的处理速度 5~10MB/s 估算,即 -m 参数一般设置 4~8,表示启动 4~8 个 map task 并发抽取。

原理

将表中的 id 列作为 split column

执行下面sql:

select max(id),min(splitidby) from 表

得到该列最小值是 0、最大值 1000

如果设置 4个map数,就分成4个区域:

0, 250
250, 500
500, 750
750, 1001

每个map task执行的查询语句类似于:

SELECT * FROM 表 WHERE id >= 0 AND id < 250
SELECT * FROM 表 WHERE id >= 250 AND id < 500
SELECT * FROM 表 WHERE id >= 500 AND id < 750
SELECT * FROM 表 WHERE id >= 750 AND id < 1001

每个map各自执行各自的SQL,并将查询出的数据进行导入

例子

改造 sqoop1.4.7 从MySQL导入数据到HDFS 中的例子,

bin/sqoop import \
--connect jdbc:mysql://hadoop1:3306/scott \
--table dept \
--username root \
--password root \
--target-dir /test_sqoop_dept_split \
--fields-terminated-by '\t' \
--null-string '' \
--m 2 \
--split-by deptno

查看数据

访问 http://hadoop1:9870/

查看目录:/test_sqoop_dept_split,有2个文件:

  • part-m-00000
  • part-m-00001

参数:
https://blog.csdn.net/u010003835/article/details/106604085
https://blog.csdn.net/jim8973/article/details/103960711
https://blog.csdn.net/duyuanhai/article/details/103066861


原文出处:/show_1IX89MbrJa1E.html