2

私はHadoopでJavamap/ reduce APIを学び、map/reduceで考えることに頭を悩ませようとしています。これが私がapachehttpサーバーのログファイルに対して書いているサンプルプログラムです。これには2つのフェーズがあります(それぞれがM / Rジョブとして実装され、次にチェーンされます)。

  1. 各IPアドレスがサーバーにアクセスした回数を数えます
  2. 上位5つのIPアドレスを検索する(ほとんどのリクエスト)

    フェーズ1は非常に簡単なようです。これは、map / reduceでの単純なカウントの実装であり、次のようなものを出力します。

    192.168.0.2  4
    10.0.0.2  7
    127.0.0.1  3
    ...etc
    

この出力は、2番目のmap/reduceジョブのマッパーにフィードされます。

今、私はトップ5を並行して実装する方法について混乱しています。レデューサーは本質的にシーケンシャルなので、完全なリストに反してソートするレデューサーは1つだけだと思いますよね?ステップ2を並行して解決するにはどうすればよいですか?

4

1 に答える 1

2

まず、最初のジョブの出力が小さいため並列化する必要がない場合は、次のことを考慮してください。

hadoop fs -cat joboutput/part-* | sort -k2 -n | head -n5

多くの場合、これはすべてを 1 つのレデューサーに送信するよりも高速です。


レデューサーを 1 つだけ使用することから逃れようとすると、Hadoop での並べ替えはかなり荒くなります。並べ替えに興味がある場合は、TotalOrderPartionerを調べてみてください。Web を検索すると、いくつかの例が見つかるはずです。基本的な解決策は、カスタム パーティショナーを使用して、値を昇順の値のビンに分割する必要があることです。次に、各ビンが自然にソートされます。出力すると、ソートされたセットが得られます。

難しいのは、データをどのビンに入れるかを考え出すことです。


特にトップ 5 (またはトップ 50 など) に興味がある場合は、興味深い方法があります。基本的な前提は、各マッパーの上位 5 を取得する場合、リデューサーの上位 5 のうち上位 5 を取得することです。各マッパーは効果的にトップ 5 をレデューサーに送信し、トーナメントのような真のトップ 5 を競います。レデューサーでトップ 5 を取得することが保証されています。それらのいくつかを取り除く必要があるだけです。

マッパーとリデューサーの両方でトップ 5 を追跡するには、TreeMap. 基本的に、値を挿入し続け、上位 5 件まで切り捨てます。Mapper#cleanupメソッドでは、上位 5 件のレコードを書き出します (途中で書き出さないでくださいmap)。減速機についても同じことを行います。


このようなもののために、ここに Apache Pig をプラグインします。上記のオプションほど効果的ではないかもしれませんが、コーディングが容易であることは間違いありません。

loaded = LOAD 'joboutput/' USING PigStorage('\t') AS (ip:chararray, cnt:int);
sorted = ORDER loaded BY cnt DESC;
top = LIMIT sorted 5;
dump top;

並べ替えのような単純なことは、Hadoop で想像したほど簡単ではありません。簡単にできることもあれば (例: IP カウント)、難しいこともあります (並べ替え、結合)。まさに獣の本性。

于 2012-05-13T04:42:44.363 に答える