【问题标题】:Hadoop mapreduce with input size ~ 2Mb slowHadoop mapreduce 输入大小 ~ 2Mb 慢
【发布时间】:2014-03-18 10:40:59
【问题描述】:

我尝试使用 hadoop 分发计算。

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

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

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

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

我在本地使用 hadoop 2.2.0,在 amazon elastic 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());
    }
}
}

【问题讨论】:

  • 我们不会看到输入小到 2MB,甚至只有 100MB 或几 GB 的任何显着改进。与在没有 hadoop 的情况下运行相同任务相比,创建 map、reduce 任务和所有 diff 线程来运行 Job 的开销可能更多。除非我们拥有数 GB、TB 级别的数据并真正运行分布式作业,否则我们可能看不到 hadoop 的好处。
  • mapper的输出(键,值)对是什么?有什么代码可以帮助我们更好地理解?

标签: java hadoop mapreduce amazon writable


【解决方案1】:

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

【讨论】:

  • 是的,这就是我一直在徘徊的。将中间值存储在文件(?)而不是内存中是一个巨大的开销。但即使数据量很小,这个计算也需要在一台计算机上运行 16 个小时,这就是我们寻找集群解决方案的方式。我当然可以自己划分数据,运行代码并将结果合并在一起。它需要在节点上进行配置和安装,这在 hadoop 中大多是避免的。
【解决方案2】:

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

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

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

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

【讨论】:

    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 2012-06-16
      • 1970-01-01
      • 1970-01-01
      • 2017-04-30
      • 1970-01-01
      • 1970-01-01
      • 2012-10-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多