介绍
当导入的数据较多时,要设置并行度,通过执行多个任务进行导入
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需要知道根据哪一列拆分数据
其原理是:
先查出split column的最小值和最大值
然后根据
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
查看数据
查看目录:/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