更改Hadoop作业的拆分数

时间:2017-05-22 14:49:15

标签: java hadoop input split

我目前正在编写代码以使用Hadoop处理单个图像,因此我的输入只是一个文件(.png)。我有运行代码的工作代码,但它不运行顺序mappers,而是只运行一个mapper,并且永远不会生成其他mappers

我创建了自己的FileInputFormatRecordReader类扩展,以便创建(我认为是)" n"自定义splits - > " N" map任务。

我一直在疯狂地搜索网络以寻找这种性质的例子,但我所能找到的只是将整个文件用作分割的例子(意思是一个{ {1}})或每mapper个任务使用文本文件中固定数量的行(例如,3)。

我尝试做的是向每个map发送一对坐标((x1, y1), (x2, y2)),其中坐标对应于图像中某个矩形的左上角/右下角像素。

非常感谢任何建议/指导/示例/示例链接。

自定义FileInputFormat

mapper

自定义RecordReader

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;
    }
}

ImagePreprocessor类(用于自定义RecordReader - 仅显示必要信息)

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")
        );
    }
}

感谢您的时间!

1 个答案:

答案 0 :(得分:1)

您应该覆盖public InputSplit[] getSplits(JobConf job, int numSplits)课程中的方法FileInputFormat1。使用带有矩形坐标的InputSplit创建自己的类,因此在FileInputFormat内,您可以获取此信息以将正确的键/值对返回给映射器。 可能在getSplits中实施FileInputFormat可以帮助您see here