这段代码理解:
- List<InputSplit> splits = new ArrayList<InputSplit>();
- for (FileStatus file: listStatus(job)) {
- Path path = file.getPath();
- FileSystem fs = path.getFileSystem(job.getConfiguration());
- long length = file.getLen();
- BlockLocation[] blkLocations = fs.getFileBlockLocations(file, 0, length);
- if ((length != 0) && isSplitable(job, path)) {
- long blockSize = file.getBlockSize();
- long splitSize = computeSplitSize(blockSize, minSize, maxSize);
- long bytesRemaining = length;
- while (((double) bytesRemaining)/splitSize > SPLIT_SLOP) {
- int blkIndex = getBlockIndex(blkLocations, length-bytesRemaining);
- splits.add(new FileSplit(path, length-bytesRemaining, splitSize,
- blkLocations[blkIndex].getHosts()));
- bytesRemaining -= splitSize;
- }
- if (bytesRemaining != 0) {
- splits.add(new FileSplit(path, length-bytesRemaining, bytesRemaining,
- blkLocations[blkLocations.length-1].getHosts()));
- }
- } else if (length != 0) {
- splits.add(new FileSplit(path, 0, length, blkLocations[0].getHosts()));
- } else {
- //Create empty hosts array for zero length files
- splits.add(new FileSplit(path, 0, length, new String[0]));
- }
- }
- LOG.debug("Total # of splits: " + splits.size());
- return splits;
- }
需要split跨block的话,调整下splitSize就行了,比如可以将splitSize设为blockSize的1.5倍就行了。
这里代码的理解:
就是在剩余的字节数大于SPLIT_SLOP时不断生成新split, 剩余字节不超过1.1个split时作为一个split处理,这样能够利用split的跨块读取,且节省资源。
由于我其他的处理逻辑需要分的很清, 不能1.1(SPLIT_SLOP默认1.1), 即使剩余不到10%,也要作为一个新块处理, 因此改为1.0我的问题就解决了!
split的作用主要有两个:1是作为逻辑单元,便于分布式处理,不像block只能在单个节点上,而是对于不完整的记录能够跨块读取,方便很多。