スパークカスタムの並べ替えとゾーニング
はじめに:
情報化時代の継続的な発展に伴い、データは倍のテーマとなっており、我々はデータの海にさまよい、今日;によるデータの爆発的な成長には、さまざまなデータ計算エンジンは、この時代の影響を急増しました。今日最も主流のコンピューティング・エンジンの1スパークはまた、時代のすべての側面の彼らの力を示します。スパークのデータ処理やデータ分析の両方を、鉱業側面がリードする強力な能力を示しています。その分散コンピューティング機能は、ますます人気があります。この記事では説明火花発注とパーティションのを。
、スパークカスタムの並べ替え
で火花定義されたが、先輩の多くのカプセル化APIを、私たちの日常の開発でそれらを使用するAPI 利便性の多くを得ることができます。しかし、時には、これらのデフォルトのルールでは、我々は、基本的な原理を理解して我々のニーズに適した処理ロジックのセットを準備する必要があり、現時点では、私たちの目標を達成するのに十分ではありません。コード簡単に従うことにより火花をどのようにカスタムの並べ替え。
インポートorg.apache.spark.rdd.RDD インポートorg.apache.spark {SparkConf、SparkContext}。 オブジェクトCustomSort1 { DEFメイン(引数:配列[文字列]):単位 = { ヴァルCONF = 新しい新。SparkConf()setAppName( " CustomSort1「)setMaster(」ローカル[*]「) ヴァルSC = 新しい新しいSparkContext(CONF) // 照合:降順で最初のカラー値、カラー値が等しい場合、年齢、次いで昇順 ヴァルユーザー =配列(」laoduan 99 30 "" 29 laozhao 9999 "" 28 Laozhang 98 "" 28 laoyang 99 " ) // データドライバ端並列はRDDなる RDD [文字列]:ヴァル行 = sc.parallelize(ユーザ) // カットあなたのデータポイントを整理 userRDDヴァル:RDD [ユーザー] = lines.map(行=> { バルフィールド = line.split( "" ) のVal名称 =フィールド(0 ) ヴァル年齢 =フィールド(1。).toInt ヴァルのFv =フィールド(2 )。オーバーライド: // (名前、年齢、IV) 新しい新しいユーザー(名前、年齢、IV) }) // 要件を満たしていない // falseに、tpRDD.sortBy(TP => tp._3は) // RDDは、ユーザータイプの中にありましたソートデータ ヴァルソート:RDD [ユーザー] = userRDD.sortBy(U => U) ヴァルR&LT = sorted.collect() のprintln(r.toBuffer) sc.stop() } } クラスのユーザ(ヴァル名:文字列、ヴァル年齢:INT、ヴァルFV:int)が延びているシリアライズ{順序付け[ユーザー] のInt:(:ユーザーこと)を比較DEFオーバーライド = { 場合(この .fvが== that.fvを){ この .age - that.age } 他{ - (この .fv - that.fv) } } オーバーライドデフのtoString:文字列 = s "の名:$名、年齢:$年齢、FV:$のFV" }
カスタムのためにさまざまな方法を発注します:
1は、ユーザクラスが継承し順序そのユーザーソート可能なクラスへのクラス。で火花我々は地元の試験で試験されているが、彼はクラスタモデルをシミュレートしますので、我々自己定義があるため、オブジェクトの実行時のシャッフルは、伝送ネットワークを有する配列の問題を伴います。だから、それが必要である継承シリアライズ。
2、使用した場合、クラスのサンプル・クラス:
ケース クラス男性(年齢:INT、FV:intは)延び順序[人] {}
シリアライゼーションクラスを継承する必要はありません、ケースクラスのデフォルトの直列化が達成されています。
図3に示すように、照合の暗黙的な定義の例
オブジェクトSortRules { 暗黙オブジェクトOrderingUserが延び注文[ユーザー] { DEF比較オーバーライド(X:ユーザ、Y:ユーザー)のInt = { 場合(x.fv == y.fv){ x.age - y.age } 他{ y.fv - x.fv } } } }
メインプログラムコード:
// セグメンテーションデータ照合 ヴァルtpRDD:RDD [(文字列、INT、INT)] = lines.map(行=> { バルフィールド = line.split( "" ) のVal名称 =フィールド(0 ) ヴァル年齢 =フィールド( 1 ).toInt ヴァルのFv =フィールド(2 ).toInt (名前、年齢、IV) }) // ソート(照合通過は、データの形式を変更しないことのみ)の順変わる インポートSortRules.OrderingUser ヴァルをソート:RDD [(文字列、INT、INT)] = tpRDD.sortBy(TP =>ユーザ(tp._2、tp._3))
4は、いくつかの特殊なデータ型は、ネイティブ使用して、カスタムを必要としない APIを簡単に。
// 比較ルールタプルをフルに活用する、比較ルールをタプル:第一、第二等しいよりも長く、第一より ヴァルソート:RDD [(文字列、INT、INT)] = tpRDD.sortBy(TP =>( - tp._3、tp._2))
図5は、照合変換世捨て人に添加しました
// 注文[(INT、INT)]最終規則形式の比較 // ON [(文字列、INT、INT)先行未比較データ形式に // (T =>( - t._3、t._2))どのようにあなたがのルール比較したい形式に変換する 暗黙ヴァルルールを [(String、int、int)に]の[(INT、INT)]注文=(T =>( - 。t._3、t._2)) ヴァルソート:RDD [(文字列、INT、INT)] = tpRDD.sortBy(TP => TP)
二、スパークカスタムパーティショナ
1、combineByKey
reduceByKey 、GroupByKey 及び他のオペレータが基づいているcombineByKeyのオペレータの実装。これは、低レベルのオペレータは、あなたがより柔軟なルールの一部をカスタマイズすることができます。
Rdd.combineByKey(X => X、(M:INT、N:INT)=> M + N(:INT、B:INT)=> A + B、新しい HashPartition(2)、真、NULL)
パラメータの説明:
(1)は、同じキー値パーティションに
(2)部分重合
(3)、全体的な重合
(4)、パーティション番号(パーティションの数が設けられていてもよいです)
(5)かどうか、マップ端子部分重合
(6)、シーケンスパラメータ
conbineByKeyは、比較的低レベルであるAPI 、それは通常の状況下で使用することはできません、しかし、いくつかの時に先輩のAPI 私たちは便利な私たちを提供し、それを解決するためのニーズを満たすことができないとき。
2、カスタムパーティショナ
でスパーク計算は必然的に伴うシャッフルし、データはすべてのパーティションに配布される異なる規則に従って異なるパーティションです。したがって、パーティションは、下流上り伝送データを決定します。別の専門家のコンピューティング異なる専門の学生の学力で生徒データ。グループは取るのtopNを:
( 1 )、カスタムパーティショナ
// カスタムパーティショナ:メジャー:プロコレクション クラス MajorParitioner(メジャー:配列[文字列])に延在するパーティション分割{ // (ときに新しいバック実行される)メインコンストラクタに対応 // ルールマップを記憶するため のValルール = 新しい新しいmutable.HashMap [文字列、INT]() VAR I = 0 のための(主要< - メジャー){ // ルール(メジャー)=私は (私は、メジャー)rules.put I + = 1。 } // パーティションを返します数(パーティションの数次のRDD) オーバーライドDEFのnumPartitionsます。int = majors.length // 渡された符号分割キーから計算// キーがタプルである(文字列、文字列) DEF getPartitionオーバーライド(キー:任意)のInt = { // キー取得 ヴァル主 = 。key.asInstanceOf [(文字列、文字列)] ._ 1 //が規則に従って分割数を算出 ルール(メジャー) } }
( 2 )カスタムパーティショナを使用して
//は、パーティション、カスタムパーティションを呼び出し、指定されたパーティション用 ヴァルmajorPatitionerは = 新しい新しいMajorParitioner(被験者); // 指定されたpartitionByに従ってパーティション分割ルール // キーであるpartitionBy RDD(文字列、String)を呼び出すとき 分配ヴァル:RDD [((文字列、文字列)、INT)] = reduced.partitionBy(majorPatitioner) // もしタイムアウトパーティション(パーティションのデータを操作する) ヴァルソート:RDD [((文字列、文字列)、INT)] = partitioned.mapPartitions(IT => { // イテレータリストに変換された後、ソート、イテレータへの変換が返さ it.toList.sortBy(_._ 2).reverse.take(のtopNに )。 反復子 }) // のVal R&LT:配列[((文字列、文字列)、INT)] = sorted.collect()
カスタム後部隔壁によって、データがシャッフル各パーティション内のデータは、生徒データの後に、パーティションの前に除去された後のデータを並べ替えるであるNの第望ましい結果です。しかし、時にあまりにも多くのデータプログラムがまだ問題になり、彼らは我々がへのデータであるため、メモリオーバーフローを引き起こす可能性があるリストの並べ替え、およびリストがメモリに保存されています。これは、メモリ・オーバーフローにつながります。だから、どのように我々はまだこのような状況を回避することができます。私たちはできるmapPartitions 内部定義のセット、すべてのデータをロードしません。、数サイクル後に残りの最小値は、最終的なセットにより除去される。このセットを注文した後、各時間は、所望の結果です。
第三に、要約
それは一種またはパーティションであるかどうか、火花が高度なカプセル化されたAPI 我々が使用する合計が、彼はすべての状況では適用されません、とだけこれらを通じて、いくつかの例を適用するAPI 根本的なルールを理解達成するためにカスタマイズすることができます我々のニーズに適したプログラムを編集します。この方法は、それを大幅に効率を向上させることができます。何も機知が勝つための方法である、すべてをフィットすることはできません。