我输入的内容包含很多文件。它们的大小比blockSize大。每个文件在处理后,会诱导至少一个InputSplit来处理它。
问题是:是否可以在一次拆分中处理多个文件?
基于FileInputFormat代码,它不是:
for (FileStatus file: files) {
337 Path path = file.getPath();
338 long length = file.getLen();
339 if (length != 0) {
340 BlockLocation[] blkLocations;
341 if (file instanceof LocatedFileStatus) {
342 blkLocations = ((LocatedFileStatus) file).getBlockLocations();
343 } else {
344 FileSystem fs = path.getFileSystem(job.getConfiguration());
345 blkLocations = fs.getFileBlockLocations(file, 0, length);
346 }
347 if (isSplitable(job, path)) {
348 long blockSize = file.getBlockSize();
349 long splitSize = computeSplitSize(blockSize, minSize, maxSize);
350
351 long bytesRemaining = length;
352 while (((double) bytesRemaining)/splitSize > SPLIT_SLOP) {
353 int blkIndex = getBlockIndex(blkLocations, length-bytesRemaining);
354 splits.add(makeSplit(path, length-bytesRemaining, splitSize,
355 blkLocations[blkIndex].getHosts()));
356 bytesRemaining -= splitSize;
357 }
所以,可能,我们应该使用另一个InputFormat或创建我们自己的。任何解决方案?
答案 0 :(得分:2)
在一个拆分中处理几个大文件在Hadoop中没有意义,其目标是通过不同的拆分同时并行计算数据,而不是使用相同的容器顺序处理它们。但是,如果您仍希望在一个拆分中处理大文件,则可以使用 CombineTextInputFormat 并将足够大的值设置为 mapreduce.input.fileinputformat.split.maxsize 属性。 CombineTextInputFormat的正常使用是通过同一容器处理几个小文件。这里有一个使用示例:https://github.com/lalosam/HadoopInExamples/blob/master/src/main/java/rojosam/hadoop/CombinedInputWordCount/DriverCIPWC.java