赞
踩
/* getFormatMinSplitSize() : 返回1 getMinSplitSize(job) :如果配置了mapreduce.input.fileinputformat.split.minsize参数返回参数设置的值 否则返回默认值1 */ long minSize = Math.max(getFormatMinSplitSize(), getMinSplitSize(job)); /* 如果设置了mapreduce.input.fileinputformat.split.maxsize参数那么返回该参数设置的值 否则返回Long.MAX_VALUE */ long maxSize = getMaxSplitSize(job); //该集合用来存放切片信息(一个切片就是一个对象) //放入到该集合的对象是FileSplit 但是泛型是InputSplit 说明FileSplit和InputSplit有继承关系 //FileSplit是InputSplit的子类 List<InputSplit> splits = new ArrayList<InputSplit>(); //获取输入目录中所有的文件或目录状态 List<FileStatus> files = listStatus(job); //获取文件的路径 Path path = file.getPath(); //获取文件的大小 long length = file.getLen(); //块大小 long blockSize = file.getBlockSize(); /* 切片大小 默认 : 片大小 = 块大小 需求: 片大小 > 块大小 :修改minSize大小 片大小 < 块大小 :修改maxSize大小 protected long computeSplitSize(long blockSize, long minSize, long maxSize) { return Math.max(minSize, Math.min(maxSize, blockSize)); } */ long splitSize = computeSplitSize(blockSize, minSize, maxSize); //剩余文件大小 long bytesRemaining = length; /* 开始切片 : ((double) bytesRemaining)/splitSize > SPLIT_SLOP : 剩余文件大小 / 切片大小 > 1.1 (为了防止最后1片太小) */ while (((double) bytesRemaining)/splitSize > SPLIT_SLOP) { int blkIndex = getBlockIndex(blkLocations, length-bytesRemaining); /* makeSplit : 创建FileSplit对象 参数length-bytesRemaining :片的起始位置 参数splitSize :切片大小 将FileSplit对象放入到splits集合中 */ splits.add(makeSplit(path, length-bytesRemaining, splitSize, blkLocations[blkIndex].getHosts(), blkLocations[blkIndex].getCachedHosts())); //重新计算剩余文件大小 :将片大小从剩余文件大小减掉 bytesRemaining -= splitSize; } //将剩余文件大小整体切一片 if (bytesRemaining != 0) { int blkIndex = getBlockIndex(blkLocations, length-bytesRemaining); splits.add(makeSplit(path, length-bytesRemaining, bytesRemaining, blkLocations[blkIndex].getHosts(), blkLocations[blkIndex].getCachedHosts())); } not splitable //如果文件不可切整个文件是1片 splits.add(makeSplit(path, 0, length, blkLocations[0].getHosts(), blkLocations[0].getCachedHosts()));
一 InputFormat : 抽象类 作用 :①切片 ②读取数据 //切片 public abstract List<InputSplit> getSplits(JobContext context ) throws IOException, InterruptedException; //创建RecordReader对象 该对象用来读取数据 public abstract RecordReader<K,V> createRecordReader(InputSplit split, TaskAttemptContext context ) throws IOException, InterruptedException; 二 InputFormat的继承树 |-----InputFormat 抽象类 |------FileInputFormat 抽象类 |-------TextInputFormat 默认使用的InputFormat的类 三 FileInputFormat 抽象类 1.FileInputFormat是抽象类 继承了 InputFormat 2.FileInputFormat实现了父类的getSplits方法 四 TextInputFormat 默认使用的InputFormat的类 1.TextInputFormat是默认使用的InputFormat的类 继承了FileInputFormat 2.TextInputFormat实现了createRecordReader方法 3.createRecordReader方法返回了LineRecordReader,LineRecordReader是RecordReader的子类 4.LineRecordReader是真正用来读取文件中的数据的那个对象的所属类 public RecordReader<LongWritable, Text> createRecordReader(InputSplit split, TaskAttemptContext context) { return new LineRecordReader(recordDelimiterBytes); }
conbineTextInputFormat切片机制
将大量的小文件合并成一个大的Map Task的过程
虚拟存储过程 切片过程
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。