スパークAPI - スパークパーティション

まず、パーティションの概念

並列コンピューティングRDDで、RDDデータセットは、論理的に複数のスライスに分割されているセル内部パーティションを算出し、各スライス形式がパーティションと呼ばれ、並列計算の大きさ、および各パーティションの値を決定します計算は(正確な仕事の最後のRDDする)ので、タスク、だけでなく、RDDにより、タスクの数にパーティションの決定の数を実施しています。

第二に、なぜ分割する必要があります

 データ・パーティションは、分散クラスタでは、ネットワーク通信のコストが大幅にネットワークトラフィックを削減大幅に性能を向上させることができます。パフォーマンスの支出は、主のMapReduce IOやネットワーク伝送、IOの枠組みの中によるファイルの読み取りの数が多いためと書き込み、それは避けられないですが、ネットワーク伝送は、これにより、ネットワークトラフィックを減らし、より小さなファイルサイズの大きいファイルの圧縮を避けているが、追加されますCPU負荷計算。

  スパーク IO内部のは避けられないが、最適化されたネットワーク伝送スパーク:

  並列コンピューティング・クラスタに分割(スライス)、RDDスパーク。RDD同じフラグメント100、ノード10、ノード10のパーティション和演算の種類、各パーティションの第1の和を実行し、その後グローバルメインルーチンシャッフル合計値sumに伝達平均、それほどネットワーク伝送のための和演算の種類は非常に小さいです。計算の種類に参加するときには、あなたは、データ自体シャッフル、大規模なネットワークのオーバーヘッドを必要としています。

スパークは、この問題を最適化する方法ですか?

  キーと値のRDDスパークのhashCodeキーで仕切られた場合、およびRDD重合プロセスのために重要な変更は、我々はシャッフルのMapReduceを実行する計算を行った理由をシャッフルする必要がないように、同じキーは、同じノードに格納されていることを確実にするために?、ネットワーク伝送のMapReduceは、主に舞台をシャッフルすることを意味し、根本的な原因は、重合キーをシャッフルしていた時間に応じて、異なるノード上で同じシャッフルキーが存在していますシャッフルは、同じキーに一緒に来ることができる前に、ネットワークの影響は、それがネットワークに混在するすべてのデータを行くべきです。するために行ってシャッフルは、意思決定を格納しています。

  スパーク10ポイントの100トンにデータを分割するための時間ですので、インスピレーションで、この教訓から取得し、スパークキーは、パーティションのキーハッシュコードである、分割され、同じキー、ハッシュコードは、同じでなければなりません、セクションごとに10 tは、同じ鍵が内部パーティション上になければならないことを保証することができ、それは同一の鍵蓄積時間が同じノード上に存在できることを確認することができます。同じキーで実際に存在し、例えば、RDDは100部、10個のクラスタノード、各ノードのメモリ10個の部分に分かれ、それぞれが各パーティションと呼ばれる、同じノードの存在を確実にするために同じ鍵を火花パーティション。

  の多くの重要な意思決定といくつかの小さなパーティションの偏在。パーティションは完全に等しい保証することはできませんが、それは近距離でのことを確認します。だから、内部のいくつかの作業を行うMapReduceの火花がアップシャッフルする必要はありません、火花アドレス基本原理は、ネットワーク伝送のこの作品です。

  2つのテーブルを結合する場合、2つのテーブルが大きなテーブルは、小さなテーブルシャッフル処理、それに関連付けられた小さなテーブルパーティションに頻繁に前で通常と、良好な分割することは不可能です。

  大きなテーブルは、シャッフルする必要はありません。
  

  変換は、ノード間のデータは、作業が大幅にパーティションの恩恵を受けるシャッフルが必要です。このような変換は、groupWith、参加、leftOuterJoin、rightOuterJoin、groupByKey、reduceByKey、combineByKeyとルックアップコグループです。

   パーティションは限りRDDは、キーと値のペアに基づいていることができる、構成可能です

三、スパークゾーニングの原則と方法

RDDのパーティションパーティション原理:できるだけ得点領域の数は、コアクラスターの数に等しいです。

それはローカルモード、スタンドアロンモード、またはモードYARN Mesosモードであるかどうか、私たちがすることができ、デフォルトのspark.default.parallelismでパーティションの数を設定し、この値を設定しない場合、この値は、クラスタ環境に依存して決定されます

3.1ローカルモード

(1)デフォルト

パーティション上で次のようにデフォルト

 

 結果

 

 

(2)手動設定

複数のパーティションを設定し、いくつかのパーティションであります

 

 結果

 

 

(3)ローカル[N]との関連

nが少数のいくつかのデフォルトのパーティションに等しいです

そうN場合= *パーティション数のCPUコアの数に等しいです。

 

 

結果

 

 「ライトマネジメント - - 」デバイスマネージャ - 「プロセッサのローカルコンピュータのCPUコア、自分のコンピュータをチェック

 

 

 

(4)パラメータ制御

 

 

結果

 

3.2 YARNモード

 

 

この方法は、defaultParallelismに入りました

 

 この方法は、defaultParallelismに続きます

 

 

 

実装クラスであるこの特性、(Ctrlキー+ H)

 

 クラスメソッドにdefaultParallelismを探すTaskSchedulerImpl

 

 

 DefaultParallelismは、メソッドに継続するだけでなく、特性、その実装クラスを参照してください

 

 

 

実装クラスSchedulerBackendクラスを参照するには、Ctrl + hを

 

 

 defaultParallelismを見つけるCoarseGrainedSchedulerBackend入力します。

 

 

totalCoreCount.get()は、大きな値の比較に使用されるすべてのコア・エグゼキュータの和、及び2

通常の状況下ならば、あなたはどのくらいに設定します

 

第四に、パーティショナ

データは内部HDFSから読み出されている場合(1)、パーティショナを必要としません。HDFSので、すでに多くのエリアに分割。

    私たちは、パーティションの数を制御することができますが、デバイスを分割する必要はありません。

(2)非キー値RDDパーティション、パーティションは設ける必要がありません

らtestRDD = sc.textFile( "C:\\ユーザー\\管理\\ IdeaProjects \\ myspark \\ SRC \\メイン\\ hello.txt")
  .flatMap(ライン=> line.split( ""))
  .MAP(ワード=>(単語、1))。partitionBy(新しいHashPartitioner(2))

  

  設定するだけでなく、ラインを設定する必要がありますする必要はありません。

(3)時間の形式でキーと値を、我々は必要があります。

HashPartitioner

testRDD.reduceByKey resultRDD =ヴァル(新新HashPartitioner(2)、(X:INT、Y:INT)=> X + Y)
//デフォルトが設定されていない場合HashPartitoiner、spark.default.parallelismのようなパーティションの数
のprintln(resultRDD.partitioner )
のprintln( "resultRDD" + resultRDD.getNumPartitions)

  ランクパーティション

 

ヴァルresultRDD = testRDD.reduceByKey((X:INT、Y:INT)=> X + Y)
ヴァルnewresultRDD = resultRDD.partitionBy(新しいRangePartitioner [文字列、INT](3、resultRDD))
のprintln(newresultRDD.partitioner)
のprintln(」 newresultRDD "+ newresultRDD.getNumPartitions)

  

注:それは文字列である場合、範囲に従って分割、その後、辞書のオーダーの範囲で割りました。それは分割の範囲からのデータによれば、デジタルである場合

カスタムパーティショニング

我々は2つのメソッドを実装する必要があります

クラスMyPartitoiner(ヴァルのnumParts:int)がパーティショナ{延び
  ます。int = numParts DEF numPartitionsをオーバーライド
  のInt = {:オーバーライドgetPartition DEF(キー:任意)
    ヴァルドメイン=新しいURL(key.toString).getHost 
    domain.hashCode%(= valのコードnumParts)
    IF(コード<0){ 
      コード+ numParts 
    }他{ 
      コード
    } 
  } 
} 

オブジェクトDomainNamePartitioner { 
  DEFメイン(引数:配列[文字列]):単位= { 
    。ヴァル・CONF =新しいSparkConf()setAppName( "ワードカウント" ).setMaster( "ローカル")

    ヴァルSC =新しいSparkContext(CONF)

    ヴァルurlRDD = sc.makeRDD(SEQ(( "http://baidu.com/test"、2)"http://baidu.com/index"、2)、( "http://ali.com"、3)、(「HTTP: 「//baidu.com/tmmmm、4)、 
      (「HTTP: 「//baidu.com/test、4)))
    //配列[配列[(文字列、INT)]] 
    // =配列(配列()
    //配列((http://baidu.com/index、 2)、(http://baidu.com/tmmmm,4)、
    //(http://baidu.com/test,4)、(http://baidu.com/test,2)、(HTTP: //ali.com,3)))
    ヴァルhashPartitionedRDD = urlRDD.partitionBy(新しい新しいHashPartitioner(2))
    hashPartitionedRDD.glom()。コレクト()

    パーティ火花シェル--jarマナージャーパッケージの使用//導入は、その後、次のコードをテストする
    シェルスパークスパーク--master //を://マスター:7077 --jarsスパーク-1.0-SNAPSHOT.jarにRDD- 
    ヴァルpartitionedRDD = urlRDD.partitionBy(新しい新しいMyPartitoiner(2))
    ヴァル配列= partitionedRDD.glom()。(コレクト)

  } 
}

  

 

 

 

おすすめ

転載: www.cnblogs.com/tesla-turing/p/11489262.html
おすすめ