十七.Hadoop部分问题思考

1.关于切片的时候保证数据完整性的问题

MapReduce在进行切片的时候有几个参数,一个是最小切片大小(mapred.min.split.size),一个是最大切片大小(mapred.min.split.size)。

如何决定每个map输入长度呢? 首先获取输入目录下所有文件的长度和, 除以mapred.map.tasks(这个属性是我们可以再程序中设置的)得到一个推荐长度goalSize, 然后通过公式: Math.max(minSize, Math.min(goalSize, blockSize))决定map输入长度。 这里的minSize为mapred.min.split.size, 这个属性是我们在配置文件中配置的,blockSize为相应文件的block长度。这公式能保证一个map的输入至少大于mapred.min.split.size, 对于推荐的map长度,只有它的长度小于blockSize且大于mapred.min.split.size才会有效果. 由于mapred.min.split.size默认长度为1, 因此通常情况下只要小于blockSize就有效果,否则使用blockSize做为map输入长度.最后个块的大小只有大于切片的小的1.1倍才会进行重新分片。

但是又有一个问题那就是如果完全按照大小进行切分怎么保证每个块最后一条数据的完整性呢?会不会有半条数据的出现?

实际上是不会的,LineRecordReader.java中有一段代码

// If this is not the first split, we always throw away first record

// because we always (except the last split) read one extra line in

// next() method.

if (start != 0) {

  start += in.readLine(new Text(), 0, maxBytesToConsume(start));

}

this.pos = start;

实际上Hadoop每次进行切分的时候每个块都会多读取一条数据,如果是第一个块那么就从0开始读取,如果不是第一个块那么就将第一条数据丢弃

你可能感兴趣的:(十七.Hadoop部分问题思考)