目標:
- RDDがSPARKクラスターでどのように分散されているかを説明します。
- SPARKがファイルベースのRDDをパーティション分割する方法を分析します。
- SPARKがRDD操作を並行して実行する方法を説明する
- パーティショニングを通じて並列制御を実現する方法を説明する
- タスクとステージを表示および監視する方法を分析します。
最初に、クラスターモードでSparkがどのように機能するかを見てみましょう。
火花クラスター
クラウドモードでのSparkプログラムの実行プロセスを以下に示します。
ユーザーはSpark-submitを介してスパークジョブを送信できます。スパークジョブが送信されると、Sparkcontextドライバーが開き、プログラムがクラウド管理ノードに渡されます(クラスターマネージャー:ヤーン、スタンドアロン、メソ、ローカル、k8など)。私の理解では、タスクによってトリガーされたドライバーのみがここに送信されます。実際のスパークプログラム(データを処理する方法の一部は、通常、パッケージ化された形式で、指定された場所(dfsまたはnfsなど)にアップロードされます)についてはこちらそして、クラスターのマスターノードに送信しませんでした。
クラスターマスターノードは、このプログラム(ドライバープログラム)に従って作業ノードにコンテナーを作成します。次に、ワーカーノードのエグゼキューターがコンテナーに従って作成され、ドライバープログラムのsparkContextを介して対話します。
SPARK CLUSTERのRDD
RDD(弾力性のある分散データセット)では、sparkはワーカーノード間でデータをパーティション分割します。作成するパーティションの数を制御することもできます。
単一ファイルのパーティションの概念を理解してみましょう
ファイルパーティション:単一ファイル
パーティションはファイルサイズに基づきます。また、目的のテキストファイルのパーティション(ファイル、minPartitions)の最小数を指定することもできます。デフォルトでは、sparkクラスターで実行されているファイルは2つの部分に分かれています。パーティションが多いほど、並列処理の度合いが高くなります。
ファイルパーティション:複数のファイル
コマンドを使用してください:sc.textFile( 'mydir / *')、各ファイルは少なくとも1つのパーティションです。XMLの解析など、各パーティションでファイルベースの操作を実行できます。
次のコマンド:sc.wholeTextFiles( "mydir")このコマンドは、多くの小さなファイルを分割するために使用され、キーと値のペアのRRDを作成するためにも使用できます(キーはファイル名を表し、値はファイルの内容を表します)
ほとんどのRDD操作はRDDの各要素に作用し、少数は各パーティションに作用します。パーティションに作用するいくつかのコマンドは次のとおりです。
foreachPartition ----各パーティションの関数を呼び出すために使用されます
mapPartitions ---現在のRDDの各パーティションで関数を実行して新しいRDDを作成するために使用されます
mapPartitionsWithIndex ---このコマンドは、パーティションのインデックスを含むことを除いて、mapPartitionsに似ています。
注:パーティション操作の関数はイテレーターを使用します。よりよく理解するために、RDDの例を見てみましょう。
最初に例を通してforeachPartitionを理解する
foreachPartition
次の例では、各パーティションの最初の行を計算する関数printFirstLineを作成しました。
myrddという名前のRDDを作成したとします。作成した関数printFirstLineを、パーティションの最初の行を計算する必要があるforeachPartitionに渡します。
パーティショニングのコマンドを理解したので、次の章では、例を通してHDFSとローカルデータの概念を理解することを試みます。
HDFSとローカルデータ(データの局所性)
この図では、複数のデータノードを見ることができます。
これで、hdfs dfs -put mydataを介してmydataファイルをhdfsにプッシュできます。ファイルが3つのブロックの形でhdfsディスクに格納されていると仮定します。
データがHDFSディスクに保存されたら、スパークでプログラミングできます。プログラムを開始すると、Sparkコンテキストが取得され、エグゼキュータがデータノードで開始されます。(sparkプログラムによって実行されているクラスターマネージャーは、yarnであり、yarnはスケジューラーを対応するデータノードにコピーして実行します)
sc.textfileコマンドを使用すると、mydataファイルをエグゼキューターにプッシュできます。これは単なる変換ステップなので、RDDは空のままです。
アクショントリガーを使用して実行され、エグゼキューターのタスクは、ブロックからパーティションにデータを読み込みます。その後、操作が値をドライバに返すまで、データは実行中のプログラム間で分散されます。
パーティションでの並列操作(パーティションでの並列操作)
RDD操作は、各パーティションで並行して実行できます。タスクはデータストレージワーカーノードで実行されます。
map、flatMap、filter、distinctなど、一部の操作ではパーティションが保持されます。reduceByKey、sortByKey、join、groupByKeyなどの一部の操作が再分割されました。
次に、ステージの操作を理解します
段階的な運用
ステージ上の操作は同じパーティションで実行できます(同じパーティションで実行できる操作はステージで実行されます)。同じステージ上のタスクは、パイプラインによって結合されます。開発者は、パフォーマンスを向上させるためにステージ操作を認識する必要があります。
Sparkの用語は次のとおりです。
ジョブ:振る舞いの実行タスクのセットです(個人的理解とは、ある目的のためのすべてのタスクのコレクションであり、dagとして理解できます)
ステージ:ジョブで並行して実行できるタスクのセットです(個人的な理解とは、単一のパーティションから実行されるタスクのセットであり、最適化されたDAGとして理解できます)。
タスク:エグゼキューター(個人的には関数として理解されます)に送信される単一の実行単位。
アプリケーション:単一のドライバーによって管理される複数のジョブのコレクションです(単一のプログラムスクリプトとして理解できます)。
次に、sparkがステージを計算する方法を確認します。
Sparkがステージを計算する方法
Sparkは、RDD依存関係の有向非循環グラフまたはDAGを構築します。これらの依存関係には2つのタイプがあります
狭い依存
依存関係が狭いとは、子RDDの各パーティションが親RDDの1つのパーティションにのみ依存することを意味します。別のエグゼキュータでシャッフルする必要はありません。RDDを作成するノードは、ステージに分割できます(例:マップ、フィルター)。
広い依存またはシャッフル依存
広い依存関係またはシャッフル依存関係。多くの子RDDパーティションは、親RDDの各パーティションに依存しています。wide-k依存関係は、新しいステージを定義します(例:reduceByKey、join、groupByKey)次に、並列処理制御のプロセスを確認します。
ReduceByKeyパーティションのRDD結果など、広く依存する操作。より多くのパーティション、より多くの並列タスク。パーティションが少なすぎると、sparkクラスターが十分に活用されません。
パーティションの数は、関数呼び出し中にnumPartitionsparameterオプションによって制御できます。localhost:4040を介してSparkアプリケーションUIを表示でき、UIですべてのSparkジョブを表示できます。
要約:
RDDSはSPARKエグゼキューターのメモリに保存されます
仮想マシンとJVMSデータはゾーンに分割されます
個別のエグゼキューターRDD内の各パーティションは、並行して操作を実行します
同じパーティションに基づく操作は、ステージのパイプラインで一緒に制約されます
複数のパーティションに依存する操作は、ステージで個別に実行されます