私はHadoopを使用して、データの非常に不均一な分布を分析しています。一部のキーには数千の値がありますが、ほとんどのキーには1つしかありません。たとえば、IPアドレスに関連付けられたネットワークトラフィックには、いくつかの会話型IPに関連付けられた多くのパケットと、ほとんどのIPに関連付けられた少数のパケットが含まれます。別の言い方をすれば、ジニ係数は非常に高いということです。
これを効率的に処理するには、各レデューサーは、ほぼ均等な負荷がかかるように、いくつかの大音量のキーまたは多数の低音量のキーを取得する必要があります。パーティションプロセスを作成している場合、これをどのように行うかを知っています。keys
マッパーによって生成された(すべての重複キーを含む)ソートされたリストと、レデューサーの数を取得N
し、
split[i] = keys[floor(i*len(keys)/N)]
レデューサーは、 forおよびforのようなi
キーを取得します。k
split[i] <= k < split[i+1]
0 <= i < N-1
split[i] <= k
i == N-1
Javaで独自のパーティショナーを作成するつもりですが、Partitioner <KEY、VALUE>クラスは、リスト全体ではなく、一度に1つのKey-Valueレコードにしかアクセスできないようです。Hadoopはマッパーによって生成されたレコードをソートすることを知っているので、このリストはどこかに存在する必要があります。複数のパーティショナーノードに分散されている可能性があります。その場合、サブリストの1つで分割手順を実行し、その結果を他のすべてのパーティショナーノードに何らかの方法で伝達します。(選択したパーティショナーノードにランダム化されたサブセットが表示されると仮定すると、結果はほぼ負荷分散されます。) ソートされたキーのリストが格納されている場所と、それにアクセスする方法を知っている人はいますか?
2つのmap-reduceジョブを作成したくありません。1つは分割を見つけるためのもので、もう1つは実際にそれらを使用するためのものです。(マッパーは同じ仕事を2回行う必要があります。)これは一般的な問題のようです。不均一な分布はかなり一般的です。