MapReduce と MapReduce スライスを使用する理由

MapReduce的由来

おなじみの例である WordCount を取り上げます。これは、各単語の出現回数をカウントします。ロジックも非常に単純です - ファイル内のデータの各行を読み取り、特定のルールに従って分割し、それを HashMap に入れます. 存在する場合、値は +1 になり、存在しない場合は、それを入れます値は 1 になります。

実装ロジックは非常にシンプルですが、データ量が多い場合、スタンドアロン版の実装は現実的ではありません。次の問題があります。

1) ファイルの保管。スタンドアロン マシンのストレージは限られており、ファイル サイズは上限なしで大きくなる可能性があります。たとえば、ログ ファイルを毎日出力しても、ログ ファイルの合計サイズは依然として大きくなり、サイズは範囲内に収まる可能性があります。 2Tから10Tなど、スタンドアローンで保存することはできません.HDFSは大量の大きなファイルを保存できるため、現時点ではHDFSにのみ保存できます.たとえば、HDFSには100ノードがあり、各ノードは 8T のハードディスクをマウントできるので、800T あります. 各ファイルを 3 つのコピーで保存し、各ファイルのサイズに応じて 2T とすると、少なくとも 100 以上のファイルを保存できます。

2) 上記の手順に従って HDFS にファイルを保存すると、各ノードにはファイルのいくつかのブロックが含まれます. このマシンで実行すると、得られる結果は部分的なデータのみです. このとき、書き込みを特化する必要があります.クライアント、プログラムはクライアント上で実行され、クライアントはすべてのノードに移動して、対応するファイルのすべてのブロックを取得し、ブロックのデータを読み取り、ブロックのデータをカウントするため、サブルーチンはスタンドアロン バージョンになります。繰り返しますが、この実装では、いくつかの中間データを保存する必要があるため、メモリが十分ではありません。さらに、これらのデータをネットワークから継続的に削除する必要があり、非常に遅くなるため、この実装方法は無理です。

データを計算に移動するのではなく、計算をデータに移動して、統計のためにクラスタ内の各 DataNode にプログラムを分散できるかどうか疑問に思うかもしれません。 . しかし、このようにも問題があり、操作が分散化され、それぞれの操作結果がローカルの結果になるため、現時点では次のような問題もあります。

1) 多くのマシンで実行するためのコードの配布方法、起動環境の構成方法、および起動方法。これには、リソース配布と Java 起動プログラム専用の巨大なシステムが必要になることは間違いありませんが、このシステムの開発の難易度、時間、およびコストは非常に高くなります。

2) データは HDFS に配置されますが、各 DataNode がデータのこの部分の内容を持っているわけではありません。クラスタが非常に大きいため、ファイルが格納されるときにノードの一部しか占有しない場合があります。他のノードにはデータがありません.これらのノードにコードを配置すると実行できますが、データはネットワークから取得する必要があるため、効率は非常に低くなります. したがって、データが格納されているノードにコードを配布する必要がありますが、これには戦略的な問題が必要です.この戦略的な問題を解決した後、特定のノードのダウンタイムも考慮する必要があります.このとき、集計結果は正しくありません. 、そしてそれをリアルタイムで監視する必要がありますプログラムの実行ステータス、どのノードが正常で、どのノードがそうでないか。

3) 上記の問題が解決されたと仮定すると、各ノードの統計データは中間結果に過ぎず、この時点でまだ要約する必要があります。つまり、データを要約用のマシンに転送する必要があります (すべての単語は統計)、またはさまざまなノードのさまざまな部分のデータを集計します(これらの単語はこのマシンでカウントされ、他の単語は別のマシンでカウントされます)。前者の場合、集約マシンの負荷が非常に高くなり、後者の場合、中間データのスケジューリング システムを作成する必要があります。

このようにして、単純なものを見つけて分散実行プログラムに変換すると、他の多くの問題、つまりロジックとは関係のない問題に直面することになり、多くの場合、これらの問題はロジックを解決するよりもはるかに複雑になります。

この時点で、先ほど説明したすべての問題とロジックをカプセル化した MapReduce が表示され、独自のロジックを記述するだけで済みます。

MapReduce の理解 

MapReduce には、分割統治の考え方という基本的な考え方があります。問題は最初に分割されて処理され、次にマージされて統合されて最終的な処理が行われます。したがって、MapReduce も Map と Reduce の 2 つの部分に分けられます。

1) マップ: 特定のマップ関数に従って一連のデータを新しいデータにマップするマッピング プロセス。つまり、複雑な問題をいくつかの「単純な」問題に分解します。

2) リデュース: いくつかのグループのマッピング結果をまとめて出力するリダクション プロセス。

MapReduce ジョブ (Job) には、入力データ、MapReduce プログラム、構成情報の 3 つの部分が含まれます。Hadoop は、これらのジョブをいくつかのタスクに分割して実行します。これには、map タスクと reduce タスクの 2 種類のタスクが含まれます。タスクはクラスターのノードで実行され、Yarn を介してスケジュールされます。タスクが失敗した場合、別のノードで実行するように自動的に再スケジュールされます。

MapReduce の入力データを操作する前に、入力分割操作を実行します. このステップでは、入力データを同じ長さの小さなデータ ブロックに分割します。各シャードは Map タスクに対応し、タスクはユーザー定義の Map 関数を実行して、シャード内の各レコードを処理します。

1) なぜスライス操作なのか?

コンピュータがデータの各シャードを処理するのにかかる時間は、入力データ全体を処理するのにかかる時間よりも短いことを知ることは難しくありません。したがって、各シャードが並行して処理され、各シャードのデータが比較的小さい場合、全体的な処理の負荷バランスが向上します。

2) スライスのサイズ

MapReduce ジョブの実行時間は、シャードのサイズにも密接に関係しています。シャードが小さすぎる場合、シャードを管理するための合計時間とマップ タスクを構築するための合計時間が、ジョブの全体的な実行時間を決定します。一般的に、適切なフラグメント サイズは HDFS のブロックのサイズである傾向があり、デフォルトでは 128 MB ですが、このデフォルト値を手動で設定できます。ブロックと同じサイズを設定する理由は、1 つのノードに格納できる最大の入力ブロックのサイズであるためです. シャードが 2 つのデータ ブロックにまたがる場合、1 つの HDFS ノードに対しては基本的に不可能です. 両方を格納します.同時にデータブロック。

マップ タスクは通常、データが保存されているノードで実行されます。これは、貴重なクラスター帯域幅リソースを使用しないため、最高のパフォーマンスが得られるためです。これは、いわゆる「データ ローカリゼーションの最適化」です。ただし、Map タスクの入力フラグメントの場合、フラグメントの HDFS データ ブロックのコピーを保存するすべてのノードが他の Map タスクを実行している可能性があります。Map タスクのフラグメント化を実行するには、空いている Map スロットを見つけてください。これは非常にまれにしか発生せず、ラックからラックへのネットワーク トラフィックが発生します。

 

おすすめ

転載: blog.csdn.net/qq_35363507/article/details/113307668