ゼロ、この講義の学習目標
- RDDチェックポイントメカニズムの特性と有用性を理解する
- 共有変数のタイプ、特性、および使用法を理解する
1.RDDチェックポイント
(1)RDDチェックポイントメカニズム
- RDDチェックポイントメカニズム(チェックポイント)は、RDDデータのスナップショットを作成するのと同じです。これにより、頻繁に使用されるRDDを特定のファイルシステム、できればHDFSなどの共有ファイルシステムにスナップショットできます。マシンの故障によりメモリまたはディスクのRDDデータが失われた場合、RDDの依存関係に基づいて最初から計算を実行しなくても、指定したRDDをスナップショットからすばやく回復できるため、計算効率が大幅に向上します。
(2)RDD永続性との違い
- cache()またはpersist()は、マシンのローカルメモリまたはディスクにデータを保存します。マシンに障害が発生した場合、データリカバリは実行できませんが、チェックポイントはRDDデータを外部共有ファイルシステム(HDFSなど)に保存します。 、共有ファイルシステムのコピーメカニズムにより、データの信頼性が保証されます。
- Sparkアプリケーションの実行が終了すると、cache()またはpersist()に保存されているデータは空になりますが、チェックポイントに保存されているデータは影響を受けず、手動で削除しない限り保持されます。したがって、チェックポイントデータは次のSparkアプリケーションで使用できますが、cache()またはpersist()データは現在のSparkアプリケーションでのみ使用できます。
(3)RDDチェックポイントケースのデモンストレーション
- パッケージにオブジェクトを
net.huawei.rdd
作成するCheckpointDemo
package net.huawei.rdd
import org.apache.spark.rdd.RDD
import org.apache.spark.{
SparkConf, SparkContext}
object CheckpointDemo {
def main(args: Array[String]): Unit = {
System.setProperty("HADOOP_USER_NAME", "root")
val conf = new SparkConf()
conf.setAppName("Spark-CheckpointDemo")
conf.setMaster("local[2]")
conf.set("spark.testing.memory", "2147480000")
val sc = new SparkContext(conf)
sc.setCheckpointDir("hdfs://master:9000/spark-ck")
val rdd: RDD[Int] = sc.parallelize(List(1, 1, 2, 3, 5, 8, 13))
val resultRDD = rdd.filter(_ >= 5)
resultRDD.cache()
resultRDD.checkpoint()
val result: String = resultRDD.collect().mkString(", ")
println(result)
val count = resultRDD.count()
println(count)
sc.stop()
}
}
- 上記のコードは、checkpoint()メソッドを使用してRDDをチェックポイントとしてマークします(マークされるだけで、アクション演算子が実行されます)。最初のアクション計算では、チェックポイントとしてマークされたRDDのデータが、setCheckpointDir()メソッドで指定されたファイルシステムディレクトリにファイルとして保存され、このRDDのすべての親RDD依存関係が削除されます。 RDDが計算され、依存関係に基づいて再計算することなく、データがファイルシステムから直接読み取られます。
- RDDのデータが永続化されている場合、SparkはチェックポイントとしてマークされたRDDのデータをファイルシステムに書き込むために別のタスクを開始するため、RDDをチェックポイントとしてマークする前にRDDをメモリに永続化することをお勧めします。 〜メモリ内では、データはメモリから直接読み取られ、データ書き込みの効率を向上させるために書き込まれます。そうでない場合、RDDのデータを繰り返し計算する必要があります。
- データを保存するためのチェックポイントディレクトリを作成します
- プログラムを実行し、コンソールで結果を表示します
- HDFSチェックポイントディレクトリを表示するには、次のコマンドを実行します。
hdfs dfs -ls -R /spark-ck
2.共有変数
- 通常、Sparkアプリケーションの実行中、Sparkオペレーターの関数func(map(func)やfilter(func)など)は実行のために複数のリモートワーカーノードに送信されます。オペレーターがA特定のを使用する場合
外部变量
、変数はワーカーノードの各タスクタスクにコピーされ、変数に対する各タスクタスクの操作は互いに独立しています。変数によって格納されるデータの量が非常に多い場合(大規模なコレクションなど)、ネットワーク送信とメモリのオーバーヘッドが増加します。したがって、Sparkは、ブロードキャスト変数とアキュムレータの2種類の共有変数を提供します。
(1)ブロードキャスト変数
- ブロードキャスト変数は、変数を各タスクタスクに送信するのではなく、ブロードキャストによって各ワーカーノードのキャッシュに送信することであり、各タスクタスクは変数のデータを共有できます。したがって、ブロードキャスト変数は読み取り専用です。
1.デフォルトで渡される変数
- 外部変数arrは、map()演算子によって渡される関数で使用されます
scala> val arr = Array(1, 2, 3, 4, 5)
scala> val lines = sc.textFile("data.txt")
scala> val result = lines.map((_, arr))
scala> result.collect()
- 上記のコードでは、map()演算子に渡された関数は
(_, arr)
実行のためにエグゼキューター側に送信され、変数arr
はに送信Worker节点
され所有Task任务
ます。変数arrを渡すプロセスを次の図に示します。
arr
変数に格納されるデータの量が多いと仮定すると、各タスクタスクはコピー100MB
を維持する必要があります。タスクタスクがエグゼキュータで開始されると、エグゼキュータはメモリを消費します。100MB
3
300MB
2.ブロードキャスト変数を使用する場合の変数の送信
- ブロードキャスト変数は、実際には通常の変数のカプセル化です。分散関数で
value
は、ブロードキャスト変数の値は、Broadcastオブジェクトのメソッドを介してアクセスできます。
- ブロードキャスト変数を使用して、配列arrをmap()演算子に渡します
scala> val arr = Array(1, 2, 3, 4, 5)
scala> val broadcastVar = sc.broadcast(arr)
scala> val lines = sc.textFile("data.txt")
scala> val result = lines.map((_, broadcastVar))
scala> result.collect()
- 上記のコードは、1回だけ送信され、オブジェクトである
broadcast()
ブロードキャスト変数を返すメソッドを使用して、読み取り専用変数をクラスターに送信(ブロードキャスト)します。ブロードキャストオブジェクトは読み取り専用であり、クラスターの各ワーカーノードにキャッシュされます。次の図に、ブロードキャスト変数を使用した変数送信のフローを示します。broadcastVar
org.apache.spark.broadcast.Broadcast
- ワーカーノードの各タスクタスクは、一意のブロードキャスト変数を共有します。これにより、ネットワーク送信とメモリのオーバーヘッドが大幅に削減されます。
- 出力結果データ
(2)アキュムレータ
1.アキュムレータ機能
- アキュムレータは、ワーカーノードの値をドライバーに集約する機能を提供します。これを使用して、カウントと合計を実装できます。
2.アキュムレータを使用しないでください
- 整数の配列を合計する
- 上記のコードは、
sum
変数Driver
がで定義されており、累積演算sum = sum + x
がに送信されるExecutor
ため、出力結果が正しくありません。
3.アキュムレータを使用する
- 整数の配列を合計する
scala> val myacc = sc.longAccumulator("My Accumulator")
scala> val rdd = sc.makeRDD(Array(1, 2, 3, 4, 5))
scala> rdd.foreach(x => myacc.add(x))
scala> println("sum = " + myacc.value)
- 上記のコードは、SparkContextオブジェクトのメソッドを呼び出すことによってタイプ
longAccumulator ()
のアキュムレータを作成します。Long
デフォルトの初期値は0
です。タイプのアキュムレータは、doubleAccumulator()
メソッドを使用して作成することもできます。Double
Driver端定义
アキュムレータは、、にのみ存在できますExecutor端更新
。エグゼキュータ側はアキュムレータの値を読み取ることができないため、属性Driver端
を使用して読み取る必要があります。value