我正在研究hadoop map-reduce框架并遵循Hadoop- The Definitive指南。
如书中所述,我已经实现了Map-reduce任务,它将整个输入文件读取并将输出分配给SequenceFileOutputFormat。以下是我实施的课程:
SmallFilesToSequenceFileConverter.java
public class SmallFilesToSequenceFileConverter extends Configured implements Tool {
static class SequenceFileMapper extends Mapper<NullWritable, BytesWritable, Text, BytesWritable>{
private Text filenameKey;
@Override
protected void setup(Mapper<NullWritable, BytesWritable, Text, BytesWritable>.Context context)
throws IOException, InterruptedException {
// TODO Auto-generated method stub
InputSplit split = context.getInputSplit();
Path path = ((FileSplit)split).getPath();
filenameKey = new Text(path.getName());
}
@Override
protected void map(NullWritable key, BytesWritable value,
Mapper<NullWritable, BytesWritable, Text, BytesWritable>.Context context)
throws IOException, InterruptedException {
// TODO Auto-generated method stub
context.write(filenameKey, value);
}
}
public int run(String[] args) throws Exception {
Job job = new Job(getConf());
job.setInputFormatClass(WholeFileInputFormat.class);
job.setOutputFormatClass(SequenceFileOutputFormat.class);
WholeFileInputFormat.setInputPaths(job, new Path(args[0]));
SequenceFileOutputFormat.setOutputPath(job, new Path(args[1]));
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(BytesWritable.class);
job.setMapperClass(SequenceFileMapper.class);
job.setNumReduceTasks(2);
return job.waitForCompletion(true) ? 0 : 1;
}
public static void main(String[] args) throws Exception{
String argg[] = {"/Users/bng/Documents/hadoop/inputFromBook/smallFiles",
"/Users/bng/Documents/hadoop/output_SmallFilesToSequenceFileConverter"};
int exitcode = ToolRunner.run(new SmallFilesToSequenceFileConverter(), argg);
System.exit(exitcode);
}
}
WholeFileInputFormat.java
public class WholeFileInputFormat extends FileInputFormat<NullWritable, BytesWritable>{
@Override
protected boolean isSplitable(JobContext context, Path file) {
return false;
}
@Override
public RecordReader<NullWritable, BytesWritable> createRecordReader(
InputSplit split, TaskAttemptContext context) throws IOException,
InterruptedException {
WholeFileRecordReader reader = new WholeFileRecordReader();
reader.initialize(split, context);
return reader;
}
}
WholeFileRecordReader.java
public class WholeFileRecordReader extends RecordReader<NullWritable, BytesWritable>{
private FileSplit fileSplit;
private Configuration conf;
private BytesWritable value = new BytesWritable();
private boolean processed = false;
@Override
public void initialize(InputSplit split, TaskAttemptContext context) throws IOException, InterruptedException {
// TODO Auto-generated method stub
this.fileSplit = (FileSplit) split;
this.conf = context.getConfiguration();
}
@Override
public boolean nextKeyValue() throws IOException, InterruptedException {
if(!processed){
byte[] contents = new byte[(int)fileSplit.getLength()];
Path file = fileSplit.getPath();
FileSystem fs = file.getFileSystem(conf);
FSDataInputStream in = null;
try{
in = fs.open(file);
IOUtils.readFully(in, contents, 0, contents.length);
value.set(contents, 0, contents.length);
}catch(Exception e){
e.printStackTrace();
}finally{
IOUtils.closeStream(in);
}
processed = true;
return true;
}
return false;
}
@Override
public NullWritable getCurrentKey() throws IOException, InterruptedException {
// TODO Auto-generated method stub
return NullWritable.get();
}
@Override
public BytesWritable getCurrentValue() throws IOException, InterruptedException {
// TODO Auto-generated method stub
return value;
}
@Override
public float getProgress() throws IOException, InterruptedException {
// TODO Auto-generated method stub
return processed ? 1.0f : 0.0f;
}
@Override
public void close() throws IOException {
}
}
正如SmallFilesToSequenceFileConverter.java中所指定的那样,当我使用单个reduce任务时,一切正常,我按预期获得输出如下:
//part-r-00000
SEQorg.apache.hadoop.io.Text"org.apache.hadoop.io.BytesWritable������xd[^•MÈÔg…h#Ÿa������a���
aaaaaaaaaa������b���
bbbbbbbbbb������c���
cccccccccc������d���
dddddddddd������dummy���ffffffffff
������e����������f���
ffffffffff
但问题是当我使用两个reduce任务时,我得到了两个reduce任务处理的输出结果。如果有两个reduce任务,这里是输出。
//part-r-00000
SEQorg.apache.hadoop.io.Text"org.apache.hadoop.io.BytesWritable������ÓÙE˜xØÏXØâÆU.êÚ������a���
aaaaaaaaaa������b�
bbbbbbbbbb������c
cccccccccc������e����
//part-r-00001
SEQorg.apache.hadoop.io.Text"org.apache.hadoop.io.BytesWritable������π¸ú∞8Á8˜lÍx∞:¿������b���
bbbbbbbbbb������d���
dddddddddd������dummy���ffffffffff
������f���
ffffffffff
这表明数据&#34; bbbbbbbbbb&#34;正在处理两个reduce任务。 这可能是什么问题?或者这个结果好吗?或者我犯的任何错误?
作为参考,输入目录包含六个输入文件名a至f,每个输入文件包含与文件名相对应的数据,例如,文件命名为包含数据&#34; aaaaaaaaaaa&#34;和其他文件包含类似的数据,除了e文件是空的。并且有一个名为dummy的文件,其中包含数据&#34; ffffffffff&#34;。
答案 0 :(得分:0)
我没有弄清楚这个的确切原因。
但是删除hdfs-site.xml中指定的名称节点和数据节点目录并重新启动hdfs,yarn和mr服务为我解决了这个问题。