FAQ-SQOOP数据倾斜
FAQ-SQOOP数据倾斜
场景:
假设MySQL的表的字段orderid的数据如下表所示,orderid的10000到20000是连续的,但orderid从2直接跳到了10000,从20000直接跳到了100000
orderid |
1 |
2 |
10000 |
10001 |
10002 |
...... |
20000 |
100000 |
1、运行boundary-query来找出表的最小最大值。
select min(orderid),max(orderid) from order;
查出最小值1,最大值100000
2、进行切分并拉取数据,由于并发为10,此时会产生10个query,分别如下:
select * from order where orderid>=1 and orderid<10000; — 2行数据
select * from order where orderid>=10000 and orderid<20000; – 10000行数据
select * from order where orderid>=20000 and orderid<30000; – 1行数据
select * from order where orderid>=30000 and orderid<40000; – 0行数据
......
select * from order where orderid>=90000 and orderid<100000; – 1行数据
可以看出并行度为10点时候,只有与第2个查询会有10000行数据,其他的查询的数据都非常少,甚至没有。
3、jdbc连上MySQL后,获取数据到HDFS。
如何排查数据倾斜:
1、被用于切分的字段倾斜严重。如上面的场景所描述。
2、切分键的字段为非整形,如果字段是字符串型,SQOOP会先hash之后再切分,内部算法较为复杂,且不能保证切分均匀。
解决方案:
1、合理选择切分键,尽量保证均匀;
2、尽量选择整形字段进行切分;
3、尽量保证选择的切分键有索引。
4、一些奇怪的用法:假如一张表有一个字段是int,其他全是varchar,而这个int字段又不均匀,也可以考虑将split-by的字段改成 right(xx,1),这样相当于一定把数据切分为了10份。而且最大值是9,最小值是0。此时可以指定参数:
--boundary-query "select 0,9 from dual" --split-by "right(id,1)"
以上内容对您是否有帮助?