我目前正在编写代码以使用Hadoop
处理单个图像,因此我的输入只是一个文件(.png
)。我有运行代码的工作代码,但它不运行顺序mappers
,而是只运行一个mapper
,并且永远不会生成其他mappers
。
我创建了自己的FileInputFormat
和RecordReader
类扩展,以便创建(我认为是)" n"自定义splits
- > " N" map
任务。
我一直在疯狂地搜索网络以寻找这种性质的例子,但我所能找到的只是将整个文件用作分割的例子(意思是一个{ {1}})或每mapper
个任务使用文本文件中固定数量的行(例如,3)。
我尝试做的是向每个map
发送一对坐标((x1, y1), (x2, y2))
,其中坐标对应于图像中某个矩形的左上角/右下角像素。
非常感谢任何建议/指导/示例/示例链接。
mapper
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.mapreduce.InputSplit;
import org.apache.hadoop.mapreduce.JobContext;
import org.apache.hadoop.mapreduce.RecordReader;
import org.apache.hadoop.mapreduce.TaskAttemptContext;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import java.io.IOException;
public class FileInputFormat1 extends FileInputFormat
{
@Override
public RecordReader createRecordReader(InputSplit inputSplit, TaskAttemptContext taskAttemptContext) throws IOException, InterruptedException {
return new RecordReader1();
}
@Override
protected boolean isSplitable(JobContext context, Path filename) {
return true;
}
}
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.mapreduce.InputSplit;
import org.apache.hadoop.mapreduce.RecordReader;
import org.apache.hadoop.mapreduce.TaskAttemptContext;
import java.io.IOException;
public class RecordReader1 extends RecordReader<KeyChunk1, NullWritable> {
private KeyChunk1 key;
private NullWritable value;
private ImagePreprocessor IMAGE;
public RecordReader1()
{
}
@Override
public void close() throws IOException {
}
@Override
public float getProgress() throws IOException, InterruptedException {
return IMAGE.getProgress();
}
@Override
public KeyChunk1 getCurrentKey() throws IOException, InterruptedException {
return key;
}
@Override
public NullWritable getCurrentValue() throws IOException, InterruptedException {
return value;
}
@Override
public boolean nextKeyValue() throws IOException, InterruptedException {
boolean gotNextValue = IMAGE.hasAnotherChunk();
if (gotNextValue)
{
if (key == null)
{
key = new KeyChunk1();
}
if (value == null)
{
value = NullWritable.get();
}
int[] data = IMAGE.getChunkIndicesAndIndex();
key.setChunkIndex(data[2]);
key.setStartRow(data[0]);
key.setStartCol(data[1]);
key.setChunkWidth(data[3]);
key.setChunkHeight(data[4]);
}
else
{
key = null;
value = null;
}
return gotNextValue;
}
@Override
public void initialize(InputSplit inputSplit, TaskAttemptContext taskAttemptContext) throws IOException, InterruptedException {
Configuration config = taskAttemptContext.getConfiguration();
IMAGE = new ImagePreprocessor(
config.get("imageName"),
config.getInt("v_slices", 1),
config.getInt("h_slices", 1),
config.getInt("kernel_rad", 2),
config.getInt("grad_rad", 1),
config.get("hdfs_address"),
config.get("local_directory")
);
}
}
感谢您的时间!
答案 0 :(得分:1)
您应该覆盖public InputSplit[] getSplits(JobConf job, int numSplits)
课程中的方法FileInputFormat1
。使用带有矩形坐标的InputSplit
创建自己的类,因此在FileInputFormat
内,您可以获取此信息以将正确的键/值对返回给映射器。
可能在getSplits
中实施FileInputFormat
可以帮助您see here。