1

我尝试使用 hadoop 分发计算。

我正在使用序列输入和输出文件以及自定义可写文件。

输入是一个三角形列表,最大大小为 2Mb,但也可以更小 50kb 左右。中间值和输出是自定义 Writable 中的 map(int,double)。这是瓶颈吗?

问题是计算比没有hadoop的版本慢很多。此外,将节点从 2 个增加到 10 个,并不会加快进程。

一种可能性是由于输入尺寸小,我没有得到足够的映射器。我进行了更改的测试mapreduce.input.fileinputformat.split.maxsize,但它变得更糟,而不是更好。

我在本地使用 hadoop 2.2.0,并在亚马逊弹性 mapreduce 上使用。

我忽略了什么吗?或者这只是应该在没有 hadoop 的情况下完成的任务?(这是我第一次使用 mapreduce)。

您想查看代码部分吗?

谢谢你。

public void map(IntWritable triangleIndex, TriangleWritable triangle, Context context) throws IOException, InterruptedException {           
        StationWritable[] stations = kernel.newton(triangle.getPoints());
        if (stations != null) {
            for (StationWritable station : stations) {
                context.write(new IntWritable(station.getId()), station);
            }
        }
    }    


class TriangleWritable implements Writable {

private final float[] points = new float[9];

@Override
public void write(DataOutput d) throws IOException {
    for (int i = 0; i < 9; i++) {
        d.writeFloat(points[i]);
    }
}

@Override
public void readFields(DataInput di) throws IOException {
    for (int i = 0; i < 9; i++) {
        points[i] = di.readFloat();
    }
}
}

public class StationWritable implements Writable {

private int id;
private final TIntDoubleHashMap values = new TIntDoubleHashMap();

StationWritable(int iz) {
    this.id = iz;
}

@Override
public void write(DataOutput d) throws IOException {
    d.writeInt(id);
    d.writeInt(values.size());
    TIntDoubleIterator iterator = values.iterator();
    while (iterator.hasNext()) {
        iterator.advance();
        d.writeInt(iterator.key());
        d.writeDouble(iterator.value());
    }
}

@Override
public void readFields(DataInput di) throws IOException {
    id = di.readInt();

    int count = di.readInt();
    for (int i = 0; i < count; i++) {
        values.put(di.readInt(), di.readDouble());
    }
}
}
4

3 回答 3

4

只有 2MB 的数据,您不会从 hadoop 中获得任何好处。Hadoop 是关于大数据的。将 2MB 分配给 10 个节点比仅在单个节点上完成工作要花费更多时间。真正的好处始于大量节点和海量数据。

于 2014-02-18T15:23:24.203 回答
1

如果处理真的那么复杂,您应该能够意识到使用 Hadoop 的好处。

小文件的常见问题是,Hadoop 将为每个文件运行一个 java 进程,这将因必须启动许多进程而产生开销并减慢输出速度。在您的情况下,这听起来并不适用。您更有可能遇到相反的问题,即只有一个 Mapper 正在尝试处理您的输入,而此时您的集群有多大并不重要。使用输入拆分听起来是正确的方法,但由于您的用例是专门化的并且与规范有很大差异,您可能需要调整许多组件以获得最佳性能。

因此,您应该能够从 Hadoop Map Reduce 中获得您正在寻求的好处,但它可能需要大量的调整和自定义输入处理。

也就是说,MapReduce 很少(从不?)会比专门构建的解决方案更快。它是一个有用的通用工具,因为它可用于分发和解决许多不同的问题,而无需为每个问题编写专门构建的解决方案。

于 2014-03-03T20:47:39.240 回答
0

所以最后我想出了一种不将中间值存储在可写文件中的方法,只在内存中。这种方式速度更快。但是,在这个用例中,非 Hadoop 解决方案仍然是最好的。

于 2014-03-03T16:29:33.510 回答