MapReduceについて人々が話すとき、あなたはGoogleとHadoopについて考えます。しかし、MapReduce自体とは何ですか?それはどのように機能しますか?私はこれに遭遇しました ブログ投稿 これはHadoopなしでMapReduceだけを説明しようとしていますが、それでもいくつかの質問があります。
記事で説明されているように、MapReduceには本当にgroupingという中間フェーズがありますか?
グループ化フェーズも並行して実行できますか、それともマップと削減フェーズのみを実行できますか?
記事で説明されているマップとリデュースの操作は、提案されている問題(キーワードでWebページにインデックスを付ける)に対して意味がありますか?彼らは私にはあまりにも単純に見えます。
大量のデータにインデックスを付ける場合、MapReduceの主な目的は本当に並列化だけですか?
MapReduceの基本を理解せずにHadoopを知っている人が多すぎると思いますか?それって問題ですか?
MapReduceには、実際にはグループ化フェーズがあります。マップフェーズは基本的に、入力を(キー、値)要素のペアに変換することです。削減フェーズは、同じキーに関連付けられたすべての値を「集約」することで構成されるため、削減フェーズの前にすべての値をキーでグループ化する必要を回避できません。クラスター全体で値をシャッフルする必要があるため、これには多くの時間が必要になる場合があります。
グループ化フェーズは並行して行うことができます。基本的に、クラスターノードは生成された各キーに関連付けられます。次に、生成された(キー、値)のすべてのペアが、それらのキーに関連付けられたノードに送信されます。これは通常、重要なネットワークの過負荷につながり、このフェーズはネットワーク境界と見なされます。
キーワードによるWebページのインデックス作成は、MapReduceの典型的なアプリケーションです。より一般的には、辞書の逆転は、ほとんど直接MapReduceタスクとして説明できます。これは、基本的な検索エンジンを構築するプロセスとして見ることができます。特定のキーワードを含むWebサイトを検索したいとします。着信クエリごとにすべてのサイトを参照する時間がないため、(キーワード、ウェブサイト)の逆引き辞書を準備する必要があります。
MapReduceは、インデックス作成タスクに限定されていません。 mapおよびreduceタスクは、インデックス付けに必要なタスクよりも複雑な場合があります。複数のマップを組み合わせて、より複雑なデータ処理を実行するためのタスクを削減することもできます。たとえば、Apache Pigは「複雑な」MapReduceジョブを記述するためのSQLに似た言語を提供します。
基礎を習得せずにHadoopを(直接)正しく使用できるとは思いません。フレームワークが送信されたデータを処理するためにそれをどのように使用するかを理解していない場合、マップまたはリデュースタスクを正しく記述することができません。 MapReduceメカニズムを深く理解すると、ジョブに時間がかかる理由、またはCPUを追加しても処理時間が短縮されない理由を理解するのにも役立ちます。
しかし、MapReduce自体とは何ですか?
基本から始めるのが最善だと思います:
map
は、単一引数関数を一連の入力に適用して、同じサイズの一連の出力を生成する演算です。
たとえば、一連の入力_[1, 2, 3]
_および関数f(x) => x * 2
があるとします。出力は_[2, 4, 6]
_になります。
map
に純粋な関数(副作用のない関数)が指定されている限り、この操作は完全に並列化できます。
reduce
は、2つの引数の関数を一連の入力に適用する演算です。シーケンスの要素ごとに、1つの引数は前の呼び出しからの戻り値で、2番目の引数は要素です。
たとえば、シーケンス_[2, 4, 6]
_および関数f(x,y) => x + y
について考えてみます。出力は_12
_になります(x
の初期値が0であると想定)。
reduce
は前の出力に依存しているので、この操作は順次的です(知っているように、リンクされた記事では、reduceは並列化可能であると説明しています。
それはどのように機能しますか?
それは実装に依存します。完全にメモリ内で発生する可能性があります(たとえば、 Java8 Streamフレームワーク )。または、Hadoopの場合のように、配布することもできます。後者を意味すると思います。
Hadoopの基本的な考え方は、入力(通常はファイルのグループ)をシーケンスのシーケンスに分割し、それを並列map
で処理することです。操作。ただし、Hadoopと上で説明したmap-reduce操作にはいくつかの違いがあります。
map
オペレーションの出力は実際にはシーケンスであり、Hadoopはそれをフラット化します(つまり、上記の例は_[1, 2, 3]
_を取り、_[[1,2,3], [2,4,6], [3,6,9]]
_を生成します。Hadoopはこれを_[1, 2, 2, 3, 2, 4, 6, 3, 6, 9]
_に変換します)。map
オペレーションの出力をキーごとに分割するため、マッパーによって生成されるキーごとにreduce
オペレーションが1回呼び出されます(並列化できるため)。それで、Hadoopが WordCount サンプルプログラムを処理する方法を(おおまかに)示します
map
操作と考えることができます)。map
オペレーションと考える場合、フレームワーク自体はreduce
を実行します...そのパスをたどらないことがおそらく最善です)。グループ化フェーズも並行して実行できますか、それともマップと削減フェーズのみを実行できますか?
いいえ。Hadoopレデューサーは一連の値を処理し、レデューサーを呼び出す前にすべての値を知っている必要があるためです。
Except... Hadoopでは、「コンバイナ」を定義することもできます。これは、不完全な結果を取得し、その後、実際の削減ステップに渡されます。 WordCountの例はこれを実行します。キー(Word)と値のシーケンス(カウント)を受け取り、それらを合計します。
コンバイナは中間結果に必要なスペースを減らすのに役立ちますが、最終的にはすべての結果が利用可能であることを知る必要があります。ただし、最終的なreduceステージを呼び出す前に、特定のキーの結果のallを同じ場所に配置したことを知る必要があります。
大量のデータにインデックスを付ける場合、MapReduceの主な目的は本当に並列化だけですか?
「Hadoopなどのフレームワークの主な目的は、大量のデータに対する並列処理の分散と調整を簡素化することである」と言い換えます。
たとえば、ハーバード図書館システムで1,800万冊すべてをスキャンしたとします。これでたくさんの画像ができたので、OCRを使用してそれらをテキストに翻訳したいとします。一連のマシン間でファイルを手動で分割し、それらの各マシンでOCRタスクを手動で開始できます。そして必然的に、一部のマシンが他のマシンより先にタスクを完了することがわかります。あるいは、マシンの1つにハードウェア障害があり、それが何を完了しているかを把握し、それが持っていないものを再配布する必要があります。
または、容量のあるマシンにファイルを配布するフレームワークを使用することもできます(分散されたmap
、reduce
なし)。ただし、必要に応じて、これらのすべての翻訳済みファイル(map
とともに別のreduce
)のキーワードインデックスを自動的に生成することもできます。
MapReduceを使用すると、分散データセンターで実行するプログラムを作成できます。
プログラムは2つのフェーズに分かれています。 1つ目は、データがあるサーバーに送信され、事前計算を行います。このフェーズの結果は、プログラムの後半に送信され、統合されます。
これは、最初の部分の結果が小さいデータ処理で最適に機能します。たとえば、select account、count(*)を各ノードで実行して、小さい部分的な結果を生成し、合計の合計である統合のためにサーバーに送信できます。そのような多かれ少なかれ:
Hadoopは簡単に分割できないものでも機能しますが、それほど効率的ではありません。グレーソートの競争に参加してください。 Hadoopはソートが高速ですが、競合他社よりも多くのハードウェアを必要とします。
Hadoopは、直接合計、結合なしの選択、および多くのデータ分析に効果的です。 Hadoopは、sort、count(distinct)、joinなどにはそれほど効率的ではありません。数学的に言えば、数学の分散特性が機能する場合に最もよく機能します。
MapReduceは分割統治戦略であり、分割および集約ポリシーにいくつかの制約があります。
すべてのMapReduce問題は、問題の各部分が均一または「同じ」であるように、割り切れる必要があります。これにより、すべてのワーカーが問題のサブチャンクに取り組むことができます。
すべてのMapReduceの結果は、同じ「タイプ」またはレコード構造を共有する必要があります。したがって、次のような結果を生成できます
(a, b, c)
(null, b, c)
(a, b, null)
どこ a, b, c
は互換性のあるデータ型ですが、次のような出力は生成できません。
(a, b, c)
(a, d, c)
(a, b)
2つの結果セットを集約できる関数を宣言する必要があります。
f(R1, R2) = R3
r1とR2のすべてのフィールドが出力レコードセットR3で適切に結合されるようにします。この関数は対称でなければなりません、つまり
f(R1, R2) = R3
f(R2, R1) = R3
レコードのすべてのセットに当てはまります。 (または、実行全体で安定した出力が得られることは決してありません)
これらの制約により、ステージの多くが並行して行われるマルチステージ処理が可能になります。
各「問題ソルバー」には入力の「ビット」があり、すべての入力なしで「出力チャンク」の作成に取り組むことができるため、ネットワーク上の複数のマシンに作業を簡単に分散させることができます。次に、各「結合」ワーカーは、すべての作業のチャンクが集約されるまで、「問題ソルバー」の結果を集約します。