複数のreduce関数で分析する大規模なデータセットがあります。
すべてのreduceアルゴリズムは、同じmap関数によって生成された同じデータセットに対して機能します。大規模なデータセットを毎回読み取るにはコストがかかりすぎます。1 回だけ読み取って、マップされたデータを複数のreduce関数に渡す方がよいでしょう。
Hadoop でこれを行うことはできますか? 例とインターウェブを検索しましたが、解決策が見つかりませんでした。
たぶん簡単な解決策は、reduce関数を持たないジョブを書くことでしょう。したがって、マップされたすべてのデータをジョブの出力に直接渡すことになります。ジョブのレデューサーの数をゼロに設定するだけです。
次に、そのデータを処理するさまざまなreduce関数ごとにジョブを記述します。ただし、これは、マップされたすべてのデータをHDFSに保存することを意味します。
別の方法として、すべてのreduce関数を1つのReducerに結合し、関数ごとに異なる出力を使用して、複数のファイルに出力することもできます。この記事では、Hadoop0.19の複数の出力について説明しています。この機能は、0.20.1でリリースされた新しいmapreduce APIで壊れていると確信していますが、古いmapredAPIでも引き続き使用できます。
複合キーを使用できます。「R1」と「R2」という 2 種類のレデューサーが必要だとします。これらの ID をプレフィックスとしてマッパーの o/p キーに追加します。そのため、マッパーでは、キー「K」が「R1:K」または「R2:K」になります。
次に、レデューサーで、プレフィックスに基づいて R1 または R2 の実装に値を渡します。
チェーンで異なるレデューサーを実行したいと思います。Hadoop では、「複数のレデューサー」とは、同じレデューサーの複数のインスタンスを実行することを意味します。一度に 1 つのレデューサーを実行し、最初のものを除くすべてのレデューサーに簡単なマップ機能を提供することをお勧めします。データ転送の時間を最小限に抑えるために、圧縮を使用できます。
次のシーケンスを使用できる問題はまだわかりません。
database-->map-->reduce (要件に応じて cat または None を使用) し、抽出したデータ表現を保存します。メモリに収まるほど小さいと言っている場合は、ディスクに保存することは問題になりません。
また、特定の問題に対する MapReduce パラダイムの使用は正しくありません。単一の map 関数と複数の「異なる」reduce 関数を使用しても意味がありません。map を使用してデータを別のマシンに渡して別のことを行うだけであることを示しています。そのための Hadoop やその他の特別なアーキテクチャは必要ありません。
もちろん、複数のレデューサーを定義できます。ジョブ (Hadoop 0.20) の場合は、次を追加するだけです。
job.setNumReduceTasks(<number>);
しかし。インフラストラクチャは複数のレデューサーをサポートする必要があります。つまり、
そしてもちろん、あなたの仕事はいくつかの仕様に一致する必要があります。あなたが正確に何をしたいのかわからないので、私は大まかなヒントを与えることしかできません:
job.setPartitionerClass(...)
たとえば、ランダム パーティショナーを使用して ...レデューサーごとに 1 つずつ、複数の出力ファイルが得られます。ソートされた出力が必要な場合は、すべてのファイルを読み取り(今回は複数のマップタスク...)、1つのリデューサーのみでソートして書き込む別のジョブを追加する必要があります...
ローカルのReducerである Combiner-Class も見てください。これは、マップによって出力された部分データに対して、既にメモリ内に集約 (縮小) できることを意味します。非常に良い例は WordCount-Example です。Map は各単語をキーとして出力し、そのカウントを 1: (単語, 1) として出力します。コンバイナーは、マップから部分的なデータを取得し、ローカルで (, ) を出力します。Reducer はまったく同じことを行いますが、一部の (結合された) 単語数が既に 1 を超えています。帯域幅を節約します。