我尝试使用hadoop分发计算。
我正在使用Sequence输入和输出文件以及自定义Writable。
输入是一个三角形列表,最大大小为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());
}
}
}
答案 0 :(得分:4)
只有2MB的数据,你不会从hadoop中获得任何好处。 Hadoop就是大数据。将2MB分配给10个节点需要花费更多时间,而只需在单个节点上完成工作。真正的好处从大量节点和大量数据开始。
答案 1 :(得分:1)
如果处理真的很复杂,那么您应该能够从使用Hadoop中获益。
小文件的常见问题是,Hadoop将为每个文件运行一个java进程,这将导致必须启动许多进程并减慢输出的开销。在你的情况下,这听起来并不适用。更有可能的是,您遇到的问题是只有一个Mapper正在尝试处理您的输入,并且此时集群的大小并不重要。使用输入分割听起来像正确的方法,但由于您的用例是专门的并且明显偏离常规,您可能需要调整许多组件以获得最佳性能。
因此,您应该能够从Hadoop Map Reduce中获得所需的好处,但它可能需要进行大量调整和自定义输入处理。
那说很少(从不?)MapReduce比专用解决方案更快。它是一个非常有用的通用工具,它可用于分发和解决许多不同的问题,而无需为每个问题编写专用的解决方案。
答案 2 :(得分:0)
所以最后我想出了一种不在可写入中存储中间值的方法,只在内存中存储。这样它更快。 但是,在这个用例中,非hadoop解决方案是最好的。