1

Hadoopを使って計算を分散してみました。

シーケンスの入力ファイルと出力ファイル、およびカスタム Writable を使用しています。

入力は三角形のリストで、最大サイズは 2Mb ですが、50kb ほど小さくすることもできます。中間値と出力は、カスタム Writable の map(int,double) です。これがボトルネックですか?

問題は、計算が Hadoop なしのバージョンよりもはるかに遅いことです。また、ノードを 2 から 10 に増やしても、プロセスは高速化されません。

1 つの可能性は、入力サイズが小さいために十分なマッパーを取得できないことです。を変更してテストを行いました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());
    }
}
}
4

3 に答える 3

1

処理が本当に複雑な場合は、Hadoop を使用するメリットを実感できるはずです。

小さなファイルに共通する問題は、Hadoop がファイルごとに 1 つの Java プロセスを実行するため、多くのプロセスを開始する必要があるためオーバーヘッドが発生し、出力が遅くなることです。あなたの場合、これは当てはまらないようです。入力を処理しようとしているマッパーは 1 つだけであり、その時点でのクラスターの大きさは問題にならないという逆の問題を抱えている可能性が高くなります。入力分割を使用することは正しいアプローチのように思えますが、ユース ケースが特殊化されており、標準から大幅に逸脱しているため、最高のパフォーマンスを得るには多くのコンポーネントを微調整する必要がある場合があります。

そのため、Hadoop Map Reduce から求めている利点を得ることができるはずですが、おそらくかなりのチューニングとカスタムの入力処理が必要になるでしょう。

つまり、MapReduce が専用のソリューションよりも高速になることはめったにありません (絶対にありませんか?)。これは、それぞれに専用のソリューションを作成する必要なく、多くの多様な問題を配布および解決するために使用できるという点で便利な汎用ツールです。

于 2014-03-03T20:47:39.240 に答える
0

そのため、最後に、中間値を書き込み可能ファイルに保存せず、メモリにのみ保存する方法を見つけました。この方法はより高速です。それでも、このユースケースでは非 Hadoop ソリューションが最適です。

于 2014-03-03T16:29:33.510 に答える