一步一步学会sqoop.split-by及数据倾斜

声明:本内容已经在百度阅读由本人发布成书,若需转载请标明来自百度阅读《一步一步学会sqoop》

 https://yuedu.baidu.com/ebook/44b5eb201fd9ad51f01dc281e53a580216fc5098


---------------------------------------正文-------------------------------------------------------------------

导语

        参数--split-by一般要结合并行度来使用。另外--split-by指定的列需要为主键。


1,原理

  1)--split-by的原理
        设置并行--num-mappers=4,加--split-by的情况会根据主键先查最大值和最小值,即:select min(key_id),max(key_id) from tb_oracle_stock_info_key。

        如tb_oracle_stock_info_key(股票信息表)中 key_id(主键)最小值为300,最大值为400,那么4个并行度的切片情况如下:

        

        并行度实现的sql如下:

select * from tb_oracle_stock_info_key where key_id between 300 and 325;

select * from tb_oracle_stock_info_key where key_id between 325 and 350;

select * from tb_oracle_stock_info_key where key_id between 351 and 375;

select * from tb_oracle_stock_info_key where key_id between 376 and 400;


        综上所述,加--split-by参数后,使用大于1个并行时,效果理论上优于没有加--split-by参数作业。

  2)数据倾斜

        假设oracle的表tb_oracle_stock_info_key(股票信息表)主键为key_id,sqoop根据max(key_id)来平均分配4份。假设min(key_id)=1,max(key_id)=400,那么导数的时候会按400切割生4份,即 :

select * from tb_oracle_stock_info_key where key_id between 1  and 100;

select * from tb_oracle_stock_info_key where key_id between 101 and 200;

select * from tb_oracle_stock_info_key where key_id between 201 and 300;

select * from tb_oracle_stock_info_key where key_id between 301 and 400;


        但是由于数据特殊的原因,key_id=[1,100]分区内自由1条数据,key_id=[101,300]内完全没有数据,99%数据都是key_id=[301,400],这样就会产生数据倾斜,也就是4个并行中,有3个不耗费时间,有1个花了大部分时间,这样的并行效果相当的不好:

        

        因此,在使用并行度的时候需要了解主键的分布情况是是否有必要的。
 3)注意事项
       一般数据库表的关键字以数字类型为准,若为字符类型,最好能转换为数字类型,否则会报错或者切片不均。

2,数据准备

       还记得第三章第四节的股票信息表tb_oracle_stock_info。该表数据量月500万,目前我们需要把数据翻倍且增加主键key_id,同时key_id的取值范围在1000万到2000万之间。建tb_oracle_stock_info_key1表:

create table tb_oracle_stock_info_key1

(

  key_id           number(16) primary key, --关键字id

  stock_code       varchar2(16),   --股票代码     

  timest           varchar2(8) ,   --日期

  open_price       number(30,2),   --开盘价元

  top_price        number(30,2),   --最高价元

  lowest_price     number(30,2),   --最低价元

  cloce_price      number(30,2),   --收盘价元

  deal_money       number(30,2),   --成交价元

  deal_volume      number(30,2)    --成交量股

) ;


      插入目标数据(只取主键1000万-2000万间的数据):

/*本语句的作用是

  1)把tb_oracle_stock_info表翻4倍

  2)ROWNUM 由1 自动递增,达到唯一,作为主键

  3)取主键1000万-2000万间的数据

*/

insert into tb_oracle_stock_info_key1 nologging

select t.*

  from (

        select ROWNUM as key_id,a.*

          from (select * from  tb_oracle_stock_info w

                union all

                select * from  tb_oracle_stock_info x

                union all

                select * from  tb_oracle_stock_info y

                union all

                select * from  tb_oracle_stock_info z

                ) a  

        ) t

 where key_id >10000000

   and key_id <=20000000

;

       

         数据验证,表 tb_oracle_stock_info_key1供有1000万条数据,最小的key_id为10000001,最大的key_id为20000000:



  3,--split-by参数实例

       执行如下代码:

sqoop import \

--connect "jdbc:oracle:thin:@ser_db:1521:orcl" \

--username db_oracle_user \

--password db_oracle_pass \

--table TB_ORACLE_STOCK_INFO_KEY \

--split-by key_id \

--target-dir /data/sqoop_datas/TB_ORACLE_STOCK_INFO_KEY0 \

--num-mappers 2 ;

   

        运行效果:

       

        可以看到,作业是00:21:46分开始,之后两个map分别在00:24:46和0:24:49完成。不难理解,因为两个map数据量平均都是500万,因此完成两个map的完成时间很接近,且都大概花了3分钟左右。原因很简单,表 tb_oracle_stock_info_key1供有1000万条数据,最小的key_id为10000001,最大的key_id为20000000,作业又只分了2个并行度,因此在sqoop并行时分两个切片:
并行片1:只抽tb_oracle_stock_info_key1.key_id =[10000001,15000001]
并行片2:只抽tb_oracle_stock_info_key1.key_id =[15000001,20000000]
两个片的数据量基本相等,所以两个并行的map耗费的时候十分相近。


 4,数据倾斜实例

    1)数据准备

        目前tb_oracle_stock_info_key1的key_id为主键,目前key_id的取值范围为[10000001,20000000],即key_id<1000 万的情况是没有的。为了测试数据倾斜,插入一条key_id=1 的情况。

/*本语句的作用是

  1)把tb_oracle_stock_info表随机抽取1条

  2)ROWNUM 只取1,并把key_id 设置为1

  3)最后把这条数据插入到tb_oracle_stock_info_key1

*/

insert into tb_oracle_stock_info_key1 nologging

select 1 as key_id, a.*

  from tb_oracle_stock_info a

 where rownum =1

;

commit;


2)目前的数据分布情况:


       如上表格,数据大部分都倾斜到[10000001,12000000]的区间。


3)实例

          设置两个并行度,并以key_id主键切片:

sqoop import \

--connect "jdbc:oracle:thin:@ser_db:1521:orcl" \

--username db_oracle_user \

--password db_oracle_pass \

--table TB_ORACLE_STOCK_INFO_KEY1 \

--split-by key_id \

--target-dir /data/sqoop_datas/TB_ORACLE_STOCK_INFO_KEY3 \

--num-mappers 2 ;


4)运行结果分析

        由于min(key_id)=1和max(key_id)=2000万,那么两个并行的切片如下:
        并行片1:只抽tb_oracle_stock_info_key1.key_id =[1,1000000]
        并行片2:只抽tb_oracle_stock_info_key1.key_id =[10000001,20000000]
        所以并行片1只抽取1条数据,而并行片1需要抽取1000万条数据,最终执行情况如下:

       


        作业开始执行时间为19:56:20,然后分了2个并行度,因此有2个map,第一个map在19:56:50就执行完成,即只用了30秒就完成,原因很简单因为并行片1只有1条数据。第二个map在19:59:43完成,用了3-4分钟。这就是数据倾斜,2个并行度中,大部分数据在一个执行。




  • 5
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值