クラスタ構造:SPARK_WORKER-コア:必要は64 SPARK_WORKER_CORESの数を指定すると、コンピュータは、デュアルスレッドコア32であります
SPARK_WORKER_MEMORY:
ジョブ送信:
./spark-submit --masterノード:ポート--executor-コア--class ..jar XXX
--executor-コア:コア各エグゼキュータに使用される番号を指定し
--executor-メモリ:各エグゼキュータまで使用メモリを指定します。
--total-エグゼキュータ - コア:使用スタンドアロンクラスタ総コアスパークアプリケーション
--num-エグゼキュータ:スパークアプリケーション実行の開始のための糸
--driver-コア:コアドライバを使用
--driver-メモリ:メモリのドライバを使用します
上記パラメータは、火花送信タスクはまた、火花defaults.xmlに構成することができる提出時に指定されています
スパーク並列のチューニング:(一般時間を試験するために使用されます)
sc.textFile(XX、メモリ)
sc.parallelize(SEQ、NUM)
sc.makeRDD(SEQ、NUM)
sc.parallelizePairs(リスト、NUM)
オペレータレベルの並列度を向上させます。
ReduceByKey(楽しい、NUM)、参加(xxは、NUM)、明確な(NUM)、groupByKey(NUM)
配分は、並列処理を増加させることができます。
配分(NUM)/合体()配分(NUM)=合体(かシャッフル= NUM)
spark.default.parallelism:ローカルモードデフォルトの並列度は、ローカル[デジタル]スタンドアロン/糸である:現在のすべてのコアの数は、executorを使用
spark.sql.shuffle.partitions 200
カスタムパーティショニングは、
sparkStreaming:
受信機模式:spark.streaming.blockInterval = 200msの
ダイレクトモード(spark2.3の+):パーティション番号の読み取りトピックと一致
コードのチューニング:
1、重複RDDを作成しないように、同じRDDを再利用しよう
持続性のための2、RDD複数回使用
持久化的算子:
キャッシュ():RDDの使用を横切るジョブは、データをキャッシュに入れることができ、メモリのデフォルトのデータ
持続():
MEMORY_ONLY:メモリに直接データを置きます
大量のデータは、データをシリアル化することができる時間の後にメモリに配置する:MEMORY_ONLY_SERを
MEMORY_AND_DISK:ディスクにデータを置くこと
MEMORY_AND_DISK_SER:
チェックポイント()
3、オペレータシャッフルクラスを避けるために:
演算子+クラスマップではなく、光可変にし得る参加します
4、最終用途マップ予備シャッフルクラスオペレータがあります
reduceByKey:
aggregateByKey:
コードは示しています。
パッケージcom.optimize.study.sparkする 。インポートorg.apache.spark {SparkConf、SparkContext} オブジェクトaggregateByKey { DEFメイン(引数:配列[文字列]):単位 = { ヴァルのCONF = 新規。SparkConf()setMaster(" ローカル").setAppName(" 試験" ) のValのSC = 新しいSparkContext(CONF) ヴァルユニット = sc.parallelize(配列[(文字列、INT)]( (" zhangsan "、18 )、 (" zhangsan "、19)、 (" リシ"、20 )、 (" wangwu "、21 )、 (" zhangsan "、22 )、 (" リシ"、23 )、 (" wangwu "、24 )、 (" wangwu "、25 ) ) 、2 ) ヴァル結果 = unit.aggregateByKey(" ")((S:文字列、I:INT)=> {S + " $ " + I}、(S1:文字列、S2:文字列)=> {S1 + " #" + S2}) 結果。foreachの(のprintln) } }
combineByKey:
コードは示しています。
パッケージcom.bjsxt.myscalacodeの インポートorg.apache.spark.rdd.RDD インポートorg.apache.spark {SparkConf、SparkContext} オブジェクトMyCombineByKey { DEFメイン(引数:配列[文字列]):単位 = { ヴァルのCONF = 新しい SparkConf ().setMaster(" ローカル").setAppName(" 試験" ) のValのSC = 新しいSparkContext(CONF) ヴァルRDD1 = sc.parallelize(配列[(文字列、INT)]( (" zhangsan "、18 )、 (" zhangsan" 19 )、 (" リシ" 20 )、 (" wangwu " 21 )、 (" zhangsan " 22 )、 (" リシ" 23 )、 (" wangwu " 24 )、 (" wangwu 」、25 ) )、2 ) / * * *パーティションインデックス= 0、値=(zhangsan、18である。)=>(zhangsan、hello18)=>(zhangsan、hello18#19) *パーティションインデックス= 0、値=(zhangsan ,. 19) *パーティションインデックス= 0、値= (リージ、20)=>(リージ、hello20)=>(リージ、hello20) *パーティションインデックス= 0、値=(wangwu、21である。)=>(wangwu、hell21)=>(wangwu、hell21) * =>( zhangsna、hello18#19 @ hello22) * =>(リージ、hello20 @ hello23) * =>(wangwu、hello21 @ hello24#25) *パーティションインデックス= 1、値=(zhangsan、22)=>(zhangsna、hello22)=>(zhangsna、hello22) *パーティションインデックス= 1、値=(リージ、23)=>(リージ、hello23)=>(リージ、hello23) *パーティションインデックス= 1、値=(wangwu、24)=>(wangwu、hello24)=>(wangwu、hello24#25) *パーティションインデックス= 1、値=(wangwu、25) * / ヴァル部:RDD [(文字列、文字列)] = rdd1.combineByKey((I:INT)=> { " ハロー" + I}、(S:文字列、I:INT)=> {S + " #" + I}、( S1:文字列、S2:文字列)=> {S1 + " @ " + S2}) ユニット。foreachの(のprintln) // rdd1.mapPartitionsWithIndex((インデックス、ITER)=> { // ヴァルtransIter = iter.map(1 => // S "パーティションインデックス= $ {索引}、値= $ 1" // }) // transIter / / })。foreachの(のprintln) } }
つまり(直接重合の利点に対して:最初の重合に直接、データを引き出し、その後終了時に重合を低減するが、各マップの重合の終了時に予備重合を実施し、場合マップ予備端は利点を有します重合は)データマージプルを行いました
マップ側のシャッフルのデータ量を削減
引っ張っ終わりを減らすためにデータ量を削減
重合還元末端の数を減らします
を利用するには4、パフォーマンス演算子:
代わりのforeachを使用してのForeachPartition
代わりにmappartitionsマップを使用しての
フィルタリング後のデータパーティションを大量に減らすためにCOALESCEを使用します
代わりにreduceByKey GroupByKeyを使用します
ソートの代わりに、操作の再区分及び種類の使用RepartitionAndSortWithinPartitions
5、変数放送の使用
変数は、放送終了エグゼキュータのメモリを削減するために使用することができます
6、スパーク使用シリアライゼーション場所の最適化されたシーケンスKryoのパフォーマンスを使用して
、RDD <カスタムタイプ>
B、タスクがシリアライズ
C、RDDの永続性をシリアル化することができMEMOYR_AND_DISK_SER
スパークKryoシリアル化メカニズムを使用してください。デフォルトのJavaのシリアライズ機構たくさん速くよりKryoの直列化機構、利用の少ない、およそ1/10 Javaの直列化によって使用されるメモリのため、Kryo後の配列の配列によって占有メモリ後のデータ、データは、より少ないネットワークを介して送信されることを可能にする、クラスタ内のより少ないメモリ資源を消費します
スパークkryo直列化機構を使用して登録する必要があります。
SparkConf.set( "spark.serializer"、 "org.apache.spark.serializer.KryoSerializer")。registerKryoClasses(新しいクラス[]()SpeedSortKey.class)
7、データ構造の最適化:
スパークの代わりにネイティブデータ型の列を使用してみてください
代わりにスパークを利用するためにStringオブジェクト
アレイの代わりにスパークのセットを使用してみてください
8、コードの最適化:
メモリ使用量を削減
ノード間のデータ伝送を減らします。
ディスクIOを削減
図9に示すように、ローカライズされた調整データ - データの局所性レベル
、PROCESS_LOCAL:現在のタスク実行のメモリで処理されたデータ
B、NODE_LOCAL:現在のノードのディスク、現在のノード上のまたは他のメモリエグゼキュータのデータ処理タスク
C、NO_PREF:外部データベースにおけるタスク処理データ
D、RACK_LOCAL:ワーカー内の他のノードのメモリまたはディスクラック上のタスク実行処理データ
E、ANY:別のフレーム上のタスク処理データ
チューニングパラメータ:
spark.locality.process 3S - 時間ノードを待って必要なレベルにプロセスレベルから降格を指し
spark.locality.nodeの3S - 時間県待機必要なレベルまで、ノードレベルから降格を指し
spark.locality.rack - ラックダウングレードを待つために必要な時間を指し、
タスクが3秒5の再試行を待っているときに、タスクがまだ実行されていない場合は、タスクに局在の最高レベルに応じてデータを送信する最初のドライバを送信し、ドライバタスクは、ターンダウングレードでは、同じトークンを送信するためにダウングレードされます
10、メモリチューニング
、実行するために、最終的にはGCまたはFULL GC分髪につながる、GCが頻繁に発生するのを避けるために十分なメモリをタスクに、JVMは動作を停止します
少ないメモリおよび少ない集約とブロードキャストRDD変数記憶メモリをシャッフル
パラメータ:
スタティックメモリ:
spark.shuffle.memoryFraction 0.2を減らします
spark.storage.memoryFraction 0.6を減らします
ユニファイド・メモリ:
spark.memory.fraction 0.6
11、シャッフル規制
spark.reducer.maxSizeInFlight:48 Mのデフォルトサイズごとにのみデータの量を引っ張っ
spark.shuffle.io.maxRetries:デフォルトの再試行回数を引っ張って、データを失敗しました
spark.shuffle.io.retryWait:再試行の待ち時間
spark.shuffle.sort.bypassMergeThreshold:200
12、外部メモリヒープ調整
ノード間の接続のための長い待ち時間:--conf spark.core.connection.ack.wait.timeout = 300
通常時には、タスクを減らすmaptaskからデータを引っ張るれます。
ネットワークを介してデータの第一、カードJVMバッファへJVMストレージを引くためのデータ、及び格納データは、その後、送信
ネットワークカードのデータバッファにディスクから直接JVMプロセス・ダンプ・データを、その後のデータが外方に転送され、ヒープは、外側メモリをした後、スキップ
、10分の1である各エグゼキュータのメモリサイズのヒープメモリサイズをほとんどの場合、メモリ2G以上の大きさに調整する必要がオフ火花
外部メモリヒープ調整パラメータ:
糸は次のとおりです。
--conf spark.yarn.executor.memoryOverhead = 2048 M
スタンドアロンは次のとおりです。
--conf spark.executor.memoryOverhead = 2048 M
13、傾斜データ処理
データチルト:
MR:データ処理タスクは、他のデータ処理タスクよりも大きく、
ハイブ:非常に同じキーのテーブルのフィールドの下では、非常に少ない量に対応する他のキーデータ
スパーク:他のパーティション内のデータ量よりも大きいパーティション内のRDDデータ
解決するために傾斜してデータ:
ハイブETLプロセス:
シーン:スパークハイブが傾斜テーブルデータの頻繁な操作を必要とし、操作が傾きに応じて各フィールドに関連付けられます
ソリューション:スパークは、データ・スキュー「一時的な解決策を」存在しないように、ビジネスが起こるハイブに前方に傾斜させることができるかどうかのクールなキノコすることができます
少数チルトキーをフィルタします:
シーン:スパークビジネスインパクトに少数チルトキーかどうかを推定し、ビジネスにはほとんど影響場合、あなたは、直接これらのキーをフィルタリングすることができ、ビジネスの分析に行きます
解決策:これらの傾斜のキーをフィルタリングするために直接、フィルタ演算子を使用することができます
並列度を上げます:
シーン:大量のデータを、より少ないパーティション、異なるマルチキーは、並列度を直接上昇させることができます
解決策:演算子は、直接使用する並列度を上げることができます
ツイン重合:
シーン:データの少ない、同じキーを複数、大容量を分割
解像度:接頭辞が同じランダムキー、重合、および削除重合結果の接頭辞に追加することができるが、重合により得られた最終的な結果に行きます
参加マッピングするために参加削減変換します。
シーン:二RDD。結合操作のRDD大、小RDDは、傾斜データは、2つのRDDを必要
溶液:端に回復小さなRDDドライバは、次に大きいクラスマップ算術演算子ためRDDで放送データが、これは完全に傾斜データがない、フロー生成シャッフルを回避します
傾いサンプリングと分割鍵は、結合操作:
シーン:二RDD。RDD比較的大きい、傾斜データ、別のRDDが比較的大きい、RDDは、2つの結合操作を使用して、上述の動作を最適化することができません
ソリューション:拡張前後の傾斜分割鍵、ランダムな接頭辞、とのサンプリングと分析、そして傾斜での問題を解決するためのデータが加入
ランダムプレフィックスと拡張RDD参加します
シーン2つのRDD、大RDD、傾斜データKEY大量の、別のRDDは、二つのRDDに対して行われた操作に参加するために、比較的大きいです
ソリューション:ランダムな接頭辞を使用して拡張RDDが作動し、大きなメモリ空間を必要条件とします