1

マッパークラスとレデューサークラスの間で変数を共有したいという要件があります。シナリオは次のとおりです。-

入力レコードのタイプがA、B、Cであるとします。これらのレコードを処理しているため、map関数でoutput.collectのキーと値を生成しています。しかし同時に、レコードA、B、Cのタイプのカウントを維持するために、マッパークラスで3つの静的int変数も宣言しました。これらの変数はさまざまなマップスレッドによって更新されます。すべてのマップタスクが完了したら、これらの3つの値をReduce関数に渡します。

これはどのように達成できますか?close()メソッドをオーバーライドしようとしましたが、すべてのマップ関数の実行が完了したときではなく、すべてのマップ関数が実行された後に呼び出されます。または、変数を共有する他の方法はありますか。表示している処理済みの出力とともに、各タイプのレコードの総数を出力したいと思います。

4

2 に答える 2

3

カウンターは特定の理由で存在します。たとえば、「NUMBER_OF_RECORDS_DISCARDED」などの特定の状態のカウントを保持します。これらのカウンターをインクリメントすることしかできず、任意の値に設定することはできないと思います(ここでは間違っている可能性があります)。ただし、メッセージパサーとして使用できることは確かですが、より良い方法があります。それは、ジョブ構成を使用して変数をシームレスに設定することです。ただし、これはカスタムメッセージをマッパーまたはレデューサーに渡すためにのみ使用でき、マッパーでの変更はレデューサーでは使用できません。

古いmapredAPIを使用したメッセージ/変数の設定

JobConf job = (JobConf) getConf();
job.set("messageToBePassed-OR-anyValue", "123-awesome-value :P");

新しいmapreduceAPIを使用したメッセージ/変数の設定:

Configuration conf = new Configuration();
conf.set("messageToBePassed-OR-anyValue", "123-awesome-value :P");
Job job = new Job(conf);

MapperおよびReducerで古いAPIを使用してメッセージ/変数を取得する:configure()をMapperおよびReducerクラスに実装する必要があります。その後、map()内で使用できるように、値をクラスメンバーに割り当てることができます。 reduce()

...
private String awesomeMessage;
public void configure(JobConf job) {
    awesomeMessage = Long.parseLong(job.get("messageToBePassed-OR-anyValue"));
}
...

その後、変数awesomeMessageをmapおよびreduce関数で使用できます。

MapperとReducerの新しいAPIを使用してメッセージ/変数を取得する:ここでsetup()で同様のことを行う必要があります。

Configuration conf = context.getConfiguration();
String param = conf.get("messageToBePassed-OR-anyValue");
于 2013-01-07T21:26:57.253 に答える
1

解決策を得ました。

中古カウンター。MapperとReducerの両方のレポータークラスからアクセスできます。

于 2013-01-07T14:45:18.133 に答える