Hadoop自定义linereader,实现按行分块

最近想用Hadoop实现一个A的转置乘以A的矩阵运算,假设A是100w*100的矩阵,想把100w行特征分成100个map,每个map处理1w行,每个map一次性处理1w行,而不是一行一行处理。
hadoop0.21.0这个版本已经实现了NLineInputFormat这个方法

job.setInputFormatClass(NLineInputFormat.class);
NLineInputFormat.addInputPath(job, in);
NLineInputFormat.setNumLinesPerSplit(job,10000); 

这样可以实现每个map处理10000行的需求,100万行就是100个map,而不是默认的按物理块大小分配map,但是这个接口内部调用map方法的时候,仍是一行一行处理的,map方法会被执行10000次,现在改写linereader,让map方法只执行一次,每次处理10000行。

首先定义myLineInputFormat类,将job的读入方式设成myLineInputFormat。

job.setInputFormatClass(myLineInputFormat.class);
myLineInputFormat.addInputPath(job, in);
myLineInputFormat.setNumLinesPerSplit(job,10000);

myLineInputFormat的源码直接拷贝NLineInputFormat的源码,myLineInputFormat这个类里面的RecordReader返回的LongWritable, Text返回的是每个map方法里的文件偏移量和文本内容,每次读10000行,偏移量就是10000行的偏移量,text自然是10000行的文本内容。
重写myLineInputFormat类里的RecordReader方法:

public RecordReader<LongWritable, Text> createRecordReader(
      InputSplit genericSplit, TaskAttemptContext context) 
      throws IOException {
    context.setStatus(genericSplit.toString());
    return new mylinereader();
  }

定义myLineReader类,先源码拷贝LineRecordReader类,getFilePosition方法就是返回的每次文本的偏移量,每次的偏移量根据LineReader的readLine方法来确定,所以myLineReader的LineReader引用自己的LineReader,把import的类包改一下就成。
定义LineReader类,放在自定义的package里面,源码拷贝原先hadoop里的LineReader类,修改readLine方法:

      if(appendLength > 0)
         appendLength = (appendLength+1) * 10000 ;
      if (appendLength > 0) {
        str.append(buffer, startPosn, appendLength);
        txtLength += appendLength;
      }

第一个if是修改文件的长度,自己添加,第二个if是原来方法里的,如果10000行内容太多,这里append会报数组越界,所以修改LineReader的构造方法,如下,DEFAULT_BUFFER_SIZE是类属性,值也可以自己修改

 public LineReader(InputStream in, Configuration conf) throws IOException {
    //this(in, conf.getInt("io.file.buffer.size", DEFAULT_BUFFER_SIZE));
      this(in, DEFAULT_BUFFER_SIZE);
  }

同时修改readLine方法的返回值,原始是返回一行的偏移量,现在改成返回10000行的偏移量

  return (int)bytesConsumed * 10000 ;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值