MapReduce使用TableMapper读取HBase表自定义设置mapper任务数的方法

最近在使用MapReduce读取HBase表时遇到一个问题,mapper读取时总是只有一个mapper任务,在尝试网
上一些解决方法仍然不见成效,后面抽空看了源码和MapReduce原理,终于明白问题的原因,特别记录下来。

1.mapTask并行度的决定机制

一个job的map阶段并行度由客户端在提交job时决定,而客户端对map阶段并行度的规划的基本逻辑为:
将待处理数据执行逻辑切片,划分成逻辑上的多个split,然后每一个split分配一个mapTask并行实例处理
这段逻辑由InputFormat实现类的getSplits()方法完成。

2.TableInputFormat

1)TableMapper类

当使用MapReduce读取Hbase表中的数据时,对应的Mapper实现类需要继承TableMapper类,此类是MR专门为读取Hbase数据表而定制的。使用此类如果要设置job中的mapper实现类,与传统的job.setMapperClass()不同,需要使用TableMapReduceUtil类,进入到TableMapReduceUtil.initTableMapperJob()方法中,发现有多个重载类,当用户未设置InputFormat时,会有个默认的TableInputFormat类。

2)TableInputFormat类

TableInputFormat继承了TableInputFormatBase,TableInputFormatBase继承InputFormat并实现了getSplits()方法,此方法就是定义了分片逻辑,至此知道了TableMapper默认的分片逻辑,源码中getSplits()方法是如何实现的我不在这详说,请看参考文件【1】中的博客,解释了TextInputFormat、TableInputFormat中getSplits方法的实现。

这里我直接说结论,在TableInputFormat的getSplits()方法实现的是源表有一个region就对应一个InputSplit分片,进而对应一个Mapper任务,所以我的开发环境中的表因为只有一个region,所以每次跑mapper都只有一个mapper任务。

3.解决方案

1)设置一个region对应N个mapper任务

重新实现一个TableInputFormat类,重写其中的getSplits()方法,可以自定义实现一个region对应N个Mapper任务,具体实现可以参考参考文件【2】。

2)设置任意个mapper任务,与region无关

研究了下mr任务分片部分的源码,发现可以不局限于按region分map,可以做到与region无关,根据scan出来的数据做任意个分片,下面具体说下实现思路:

上面说过分片主要是TableInputFormat的getSplits方法去实现,此方法返回一个List,列表中有多少个InputSplit就有产生几个map,InputSplit在这里的具体实现类是TableSplit。

一开始我以为无法做到分片与region无关,因为TableSplit有个字段叫regionLocation,保存的是region的地址,我以为map会根据这个字段去对应地址取数据,

实际上不是这样。其实这个字段的在分配map任务时发挥作用, JobTracker会根据TaskTracker的地址来选择一个regionLocation与之最接近的TableSplit所对应的Map任务,其实就是希望region所在地址与map任务执行地址一样,这样可以减少网络开销。所以regionLocation只是split期望被执行的地址,与实际被执行的地址无关,那么这个参数其实可以不设置。

根据这个结论,重写了getSplit方法,将regionLocation设置为空,实现了map数与region无关,经测试可以运行,当然这样做有可能会增加网络开销。

再简单说下个人对源码中设置一个region对应一个map的理解,因为可以直接通过api获取region的startRow和endRow,这样分片速度最快,而我是把符合要求的row都取出来,再根据分片数设定每个分片的start和end,分片这一步也会消耗很多时间。
然而源码的写法也可能会造成启用无用的map任务,当所查询的数据不在此region的时候。

4)参考文献

【1】https://www.cnblogs.com/lxf20061900/p/3812812.html
【2】https://blog.csdn.net/anhuidelinger/article/details/16991337

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值