MapReduceたたはメモリずプロセッサの胜力を超える蚈算zaumiなしで詊したす

MapReduceに぀いお長い間お話ししたかったのですが、どのように芋おも、それは単玔に恐怖を感じるほどの考えですが、実際には倚くの目的にずっお非垞にシンプルで䟿利なアプロヌチです。 そしお、それを自分で実珟するこずはそれほど難しくありたせん。



MapReduceが䜕であるかを理解しおいない人のために、私はすぐに蚀わなければなりたせん。 考え出した人のために-ここでは有甚なものは䜕もありたせん。



MapReduceのアむデアが個人的にどのように生たれたのかから始めたしょうそのように呌ばれおいるこずは知りたせんでしたが、もちろん、Googleよりもずっず埌で私に䌝わりたした。



たず、圌女がどのように生たれたのかアプロヌチが間違っおいた、次にそれを正しく行う方法に぀いお説明したす。



りィキペディア䞊のすべおの単語を数える方法間違ったアプロヌチ



そしお圌女は、おそらくどこにでも生たれたした-通垞の蚘憶が十分でないずきに単語の頻床を数えるためにりィキペディア䞊のすべおの単語の頻床を数えるため。 「頻床」ずいう蚀葉の代わりに「出珟回数」があるはずですが、簡単にするために「頻床」のたたにしたす。



最も単玔なケヌスでは、ハッシュdict、map、hash、連想配列、PHPのarrayを䜜成し、その䞭の単語を読み取るこずができたす。



$dict['word1'] += 1







しかし、ハッシュの䞋のメモリが終了し、すべおの単語の100分の1だけをカりントした堎合はどうすればよいでしょうか



メモリがなくなるたで単語の䞀郚をカりントし、ハッシュをディスクに保存しお、この問題を解決したした。 ぀たり、ファむルに察しお1行ず぀盎接



aardvark | 5

aachen | 2








問題がありたした-これらのファむルをマヌゞする方法は 結局のずころ、それぞれがRAM 党䜓を占有したす。



最初は、各ファむルから最も人気のある1,000,000語のみを取り出しお結合するずいうアむデアがありたした。これはRAMに収たり、少なくずもリストの䞀番䞊最も人気のある語をカりントしたす。 これはもちろん機胜したしたが、数癟䞇の䞋䜍の単語が倱われ、さらに倚くの単語があったこずが刀明したした。



ファむルを゜ヌトするずいうアむデアが生たれたした。



次に、20個の゜ヌトされたファむルを取埗し、それらのそれぞれから最初の1000行を読み取りたす。それらはほが同じ単語゜ヌトされたファむルになりたす。 芁玄しお新しいハッシュを䜜成したす。「aaa ...」などで始たる単語のみが含たれ、新しいファむルに保存されたす。 次の1000行をすべお読み取りたす。 そこには、ほずんどすべおのファむルに「aab ...」ずいう蚀葉がありたす。



したがっお、新しいファむルははるかに小さく圢成されたす。 しかし、それでも蚀葉は繰り返されたす。 もう䞀床䞊べ替え、1000行で読み、合蚈したす。 ほが正しいファむルであるこずがわかりたす䞀郚の単語はただ1000行を超えおいる可胜性がありたす。数回繰り返したす...最終的に、゚ラヌが非垞に少ないファむルを取埗したすただし、゚ラヌはありたす。



退屈な、長いが、より良いオプションは発生したせんでした。



間違ったアプロヌチの匱点


このアプロヌチには1぀の匱点がありたした。぀たり、元の20個のファむルを結合するこずです。 改善する方法は



問題は、䞀郚の単語が䞀郚のファむルに存圚しないか、1000行の異なるブロックに存圚するずいう事実から発生したす。 ぀たり、最初の1000行ではなく、1行だけで、同じ単語で20ファむルすべおから取埗できれば、20ファむルすべおを1぀のパスに結合できたす。







どうやっおやるの 䞀般的に、これはMergeSortアルゎリズムの最埌のステップです↑゜ヌトされたリストを結合したす。 わかっおいる堎合は、スキップしおください。



20個すべおのファむルの最初の行を取埗し、最小の最初の芁玠単語を探したす。ファむルを䞊べ替えたので、䞀般的にすべおの芁玠で最小になりたす。 これが「aardvark」ずいう単語だずしたしょう。この20の行すべおから、この単語「aardvark」に関連するものだけを読み取りたす。 そしおそこから、それを削陀する堎所から-それらのファむルでのみ、2行目を読みたす。 繰り返しになりたすが、これら20個の最小倀を探しおいたす。類掚するず、さらに、すべおのファむルの最埌に到達するたでです。



最も単玔な圢匏のMapReduce



実際、10幎前にGoogleが私たちの前で発明したものをMapReduceず呌んでいたす。



自転車の発明は今日たで続いおいたす。



そのため、 "foo bar baz bar"



ずいう行があり"foo bar baz bar"



。



出力で受け取る必芁がありたす { foo: 1, bar: 2, baz: 1 }



。



最初のステップでは、 行を取埗しおそれを単語に分割し、そのような配列を䜜成したすたたは、「タプル」-「タプル」。



[ 'foo', 1 ]

[ 'bar', 1 ]

[ 'baz', 1 ]

[ 'bar', 1 ]








次に、明確になる堎合は括匧ず匕甚笊を省略したす

それらを受け取り、゜ヌトしたす。



bar, 1

bar, 1

baz, 1

foo, 1








barは2回連続しお衚瀺されるため、次の圢匏で結合したす。



bar, (1,1)

baz, (1)

foo, (1)








(1,1)



は䞀皮のネストされた配列です。぀たり、技術的には- ["bar", [1,1]]



です。



次に、配列の2番目の芁玠を远加したす 。 取埗するもの



bar, 2

baz, 1

foo, 1








たさに圌らが望んだもの。



䞻な質問は、ダギのボタンのアコヌディオンのために䜕ですか...たたは私たちはここで䜕をしたのですか



過去に戻る



2行のみが収たり、1分あたり1行に1぀の操䜜しか実行できないコンピュヌタヌがあるず想像しおください。 笑いを止めるには、少なくずも1回りィキペディアのすべおの単語を数えた埌、蚭定されたメモリ制限で笑う暩利がありたす。ギグがいく぀あるずしおも、それはただ適合したせん。



 "foo bar baz bar"



この方法で2぀のファむルを䜜成できたす。



file1.txt

[ 'bar', 1 ]

[ 'foo', 1 ]



file2.txt

[ 'bar', 1 ]

[ 'baz', 1 ]









メモリには2行ありたす。すべおが正垞であり、メモリの制限に適合しおいたす。



MergeSortの手順を䜿甚しお、これらのファむルを行ごずに結合できたす。



bar, (1,1)

baz, (1)

foo, (1)








同時に、メモリには2぀のファむルの2行のみが保存されたす-必芁以䞊ではありたせん。



実際、私たちが行ったこずはすでにMapReduceです。



単語 , 1



 , 1



配列を生成するステップ - このステップは「マップ」ず呌ばれたす。

(1,1)



を芁玄するステップは、 「瞮小」ステップです。



残りのステップは、アルゎリズム自䜓によっお実行されたすMergeSortを介した䞊べ替えず結合。



マップ、削枛 これは䜕ですか





これらのステップ自䜓は、「マップ」の堎合はナニットの発行、「リデュヌス」の堎合は折り畳みで構成されるずは限りたせん。 これらは、単に䜕かを受け入れたり、提䟛したりできる機胜です。 目的に応じお。



この堎合、「Map」は、1぀の単語を取り、 (, 1)



を生成する、䜜成した関数です。



たた、「Reduce」は、配列(, (1,1))



を取り、 (, 2)



を生成する、䜜成した関数です。



単玔にPythonに入れる



  words = ["foo"、 "bar"、 "baz"]
 def map1単語
   return [word、1]

 arr = ["foo"、[1,1]]
 def reduce1arr
   return [arr [0]、sumarr [1]] 




たたはPHP



  $単語=配列 "foo"、 "bar"、 "baz"
関数map1$ word{
   return array$ word、1;
 }

 arr =配列 "foo"、配列1,1
関数reduce1arr{
   return array$ arr [0]、array_sum$ arr [1];
 } 




したがっお、メモリ制限をバむパスしたしたが、速床制限をバむパスする方法はありたすか



このようなコンピュヌタヌが2台あるず想像しおください。 それらのそれぞれに最初の行を䞎え、最初に蚀いたすより正確には、MapReduceは蚀いたす奇数の堎所で単語だけを数え、そしお2番目の-偶数の堎所でのみ単語を数えたす。



最初の生成物

"foo bar baz bar":

foo, 1

baz, 1








2番目は以䞋を生成したす。

"foo bar baz bar":

bar, 1

bar, 1








䞊蚘のようにより正確にはMapReduce䞡方から結果を取埗し、゜ヌトしおからMergeSortを実行したす。



bar, (1,1)

baz, (1)

foo, (1)








1台のコンピュヌタヌを数えたずきずたったく同じ結果です



MapReduceは2台のコンピュヌタヌに再床配垃しおいたす。1行目は奇数行のみを提䟛し、2行目は偶数行を提䟛し、各コンピュヌタヌにReduceステップ2桁目を远加を䟝頌したす。



実際、これらの行が互いに独立しおいるこずは明らかなので、結果は再び必芁なものになりたす。



䞻なこずは、2台のコンピュヌタヌが䞊行しお動䜜し、そのため、 1台のコンピュヌタヌの2倍の速床で動䜜するこずですただし、1台のコンピュヌタヌから別のコンピュヌタヌぞのデヌタ転送にかかる時間のロスは陀く



早退



ふふ したがっお、MapReduce-より高速に実行する必芁があるか、十分なメモリがないたたはそのいずれかものを読み取るために必芁です。



より興味深い䟋は、人気による䞊べ替えカスケヌドです。



りィキペディア䞊の単語の数を数えながら、同時に人気の高いものから最も人気のないものたで、その人気の逆順でリストを䜜成したいずしたす。



りィキペディアのすべおの単語がメモリに収たらないこずは明らかです。そしお、戻り倀の゜ヌトのために、この巚倧な配列はメモリに収たりたせん。 MapReduceのカスケヌドが必芁です。最初のMapReduceの結果は、2番目のMapReduceの入力に送られたす。



正盎に蚀うず、「カスケヌド」ずいう蚀葉が正しいかどうかはわかりたせん。具䜓的にはMapReduceに圓おはたりたす。 私はこの蚀葉を他の人にはできないように説明しおいるので、この蚀葉を自分で䜿っおいたす蚀葉の滝の結果はMapReduceに萜ち、すぐに2番目のMapReduceに流れたす。



さお、単語を数える方法-私たちはすでに知っおいたす



「フヌバヌバズフヌ」



私たちが曞いたMapステップは以䞋を生成したす。

foo, 1

bar, 1

baz, 1

foo, 1








さらにMapReduceはプログラマずしおのあなたではなく、それ自䜓それらを以䞋に結合したす

bar, (1)

baz, (1)

foo, (1,1)








そしお、私たちが曞いたReduceステップは以䞋を生成したす

bar, 1

baz, 1

foo, 2








ここで、りィキペディア党䜓を怜蚎し、この配列には䜕十億もの単語が含たれおいるず想像しおください。 メモリ内で䞊べ替えるこずはできたせん。 別のMapReduceを芋おみたしょう。今回はMapがこのトリックを実行したす。



[, 15]



-> map戻り倀-> [-15, ]





[2, 15]



-> map戻り倀-> [-15, 2]





[3, 120]



-> map戻り倀-> [-120, 3]





[4, 1]



-> map戻り倀-> [-1, 4]







これは䜕のためですか



MapReduceは、Reduceに進む前に、これらのすべおの配列を配列の最初の芁玠負の数に等しいで䞊べ替えたす。 MapReduceは、デヌタの党量がメモリに収たらない堎合でも゜ヌトするこずができたす。これが玠晎らしい点です。 りィキペディアのすべおの単語に぀いお、 arsort($words)



実行するこずはできたせんが、MapReduceは実行できたす。



数字の前にマむナスがあるのはなぜですか



MapReduceは垞に昇順で゜ヌトされたすが、降順で゜ヌトする必芁があるためです。 それでは、昇順で䞊べ替えを䜿甚しお、数倀を降順に䞊べ替える方法はありたすか ゜ヌトの前にマむナス1を掛け、再床マむナス1を掛けたす。



昇順の正の数1、15、120

昇順の負の数 -120, -15, -1



必芁なのはマむナス蚘号のみで、-1を掛けお単玔に削陀したす



次のこずがReduceの入力になりたす



-120, (3)

-15, (, 2) <-- - MergeSort !

-1, (4)








玠敵ですが、2぀の単語の「頻床」は15で、MergeSortによっおグルヌプ化されたした。 修正したす。



ここで、Reduceでは、最初の数倀に-1を掛けるだけで、最初の行に1぀の配列、2番目に2぀の配列、3番目に1぀の配列を生成するだけです。



実際、MapReduceを䜿甚する実斜圢態によっおは、必芁な出力配列が1぀だけであるため、Reduceステップで2぀の配列を出力できない堎合がありたす。その埌、プログラムのReduceステップの埌に実行しおください。



取埗するもの



120, 3

15, ,

15, 2

1, 4








矎人 必芁なもの。



繰り返したすが、ここで回避した䞻なものは、䟋が4行であり、Wikipediaには蚘憶に収たらない数十億の単語があるこずを思い出しおください。



簡単なMapReduceを䜜成しお遊ぶ方法は



PHPの堎合  最も単玔な䟋 。

Pythonは 最も単玔な䟋です Pythonバヌゞョンに぀いおは以䞋を参照。



コヌドでは、ファむルずMergeSortの意味で、黒で倚かれ少なかれ完党なMapReduceを䜜成するために䜕をどこに眮くべきかを瀺したした。 ただし、これはいわば、MapReduceがどのように動䜜するかを理解するための参照実装です。 これはただMapReduceです。具䜓的には、メモリの芳点から芋たこの実装は、通垞のハッシュよりも有益ではありたせん。



PHPを遞択したしたが、ほずんどのプログラマヌがPHPを読み、目的の蚀語に翻蚳するのが簡単になるため、これらの目的には最も劥圓ではありたせん。



ヒントずチヌト



はい、配列json_encodeのJSON衚珟を1行ず぀保存するこずをお勧めしたす-単語のスペヌス、Unicode、数字、デヌタ型の問題は、次のようになりたす。

["foo", 1]

["bar", 1]

["foo", 1]








ヒント-Python では、 MergeSortがすでに実装しおいる最埌のステップはheapq.merge(*iterables)



です。



぀たり、10個のファむルをJSON衚珟で接続するだけで十分です。



  items = listファむル内のファむル名のitertools.imapjson.loads、openfilename
 heapq.merge内のアむテム*アむテム
   .... reduceitem.... 




MergeSortを実装したPHPでは、50行にわずらわなければならないず思いたす。 もちろん、コメントの䞭でより良い遞択肢を教えおくれる人がいない限り。



Pythonでは、MapReduceのyield



ず__iter__



非垞に興味深いこずを行うこずができたす たずえば、次のずおりです。



  x = MapReduce
 「foo bar bar」の単語の堎合.split
    x.sendword、1

単語の堎合、xにあるもの
   印刷語、合蚈1 




class MapReduce



-あなたは自分でそれを曞かなければなりたせん最も単玔な䜜業フォヌムで24行以内に保たれたかもしれたせん-倚分少ないです-iter_groupを単玔化するこずはPHPの䟋のgroup_tuples_by_first_element関数に類䌌しおいたす。



泚意-この方法はMapReduceにずっお叀兞的ではなく、倚くのマシンで䞊列化するこずは困難ですただし、この方法では、䜿甚可胜なメモリ以䞊のデヌタボリュヌムで䜜業するこずは非垞に簡単です。 map1ずreduce1が関数であるmap_reduce(source_data, map1, reduce1)



メ゜ッドmap_reduce(source_data, map1, reduce1)



、より正確です。



HadoopでのMapReduceの実装は、最も䞀般的な゜リュヌションです。 私はそれを詊しおいないが、最も人気があるものを知っおいるだけだ。



あずがき



だから、ここで、ZaumiのないMapReduceに぀いおの私の話が圹に立぀こずを願っおいたす。



MapReduceは、倧芏暡な蚈算に非垞に圹立ちたす。 SQLク゚リのほずんどは、いく぀かのテヌブルにさえ、MapReduce + join_iteratorに分解するのはそれほど難しくありたせん詳现は埌ほど説明したす。



匷みがある堎合-次のトピックでは、MapReduceを䜿甚しお䞀般的な単語よりも興味深いタスクを怜蚎する方法に぀いお説明したす-たずえば、むンタヌネット䞊のリンクの読み方、他の単語の文脈での単語の頻床、郜垂の人々、数癟の䌁業の䟡栌衚による補品など。



はい、みんなここにいたす MapReduceはGoogleが特蚱を取埗しおいたすが、保護の目的で䜿甚されおいたす。この方法を公匏に蚱可したHadoopず同じです。 だから-泚意しお扱っおください。



パヌト2より高床な䟋



ペむハゞ

い぀ものように、Habrから

2010



い぀か簡単に説明するこずを孊びたす....



All Articles