良いプログラマビッグデータ学習ルートは、弾力性、分散データセットRDDを共有します

  ビッグデータの学習ルートは弾力性の分散型データセットのRDDを共有良いプログラマは、RDDはスパークが表す最も基本的なデータ抽象化され、分散データ・セットと呼ばれ、RDD(弾力性のある分散型データセット)を定義した(データおよびメタデータ)不変の、あなたが分割することができ要素内の並列コンピューティング・コレクション。

RDDは特徴:自動フォールトトレランス、位置認識スケジューリングおよびスケーラビリティを

RDDプロパティ

1.スライス

データセットの基本単位。RDDのために、各スライスは、コンピューティングタスクを処理すること、および粒子サイズ並列計算を決定するであろう。指定されていない場合、ユーザはRDD RDDの作成におけるスライスの数を指定することができ、それが値をデフォルト設定されます。デフォルト値は、CPUコアのプログラムに割り当てられた番号です。

2.関数は、各パーティションに対して計算されます。

スパークRDD計算は、関数のそれぞれは、RDDは、この目的を達成する計算するために、スライス単位に基づいています。イテレータは機能複合体を計算し、各計算の結果を保存する必要はありません。

3.RDD間の依存関係。

RDD各変換器が新しいRDDを生成し、それが前部と後部との間のRDD同じ依存性のような行を形成することになります。

フォールトトレランス:パート分割データの損失は、スパークは、すべてのパーティションのRDDが再計算されたのではなく、この依存関係によって失われたパーティションのデータを再計算することができたとき。

4. Aパーティショナ、パーティ

すなわち、RDDスライス機能。現在フラグメンテーション関数の二種類に実装スパークハッシュベースHashPartitioner、他基づくRangePartitionerの範囲です。のみRDDのキーと値のために、RDD Parititioner非キー値の値がNone、パーティショナを持つことになります。パーティショナ機能は断片RDD自体の数を決定するだけでなく、とき、親RDDシャッフル出力フラグメントの数を決定していないだけ。

5.リスト

(好ましい位置)のそれぞれのパーティションのメモリアクセス優先順位。 - >近接原理

HDFSファイルのため、このリストの保存は、各パーティションのブロック位置ですタスクのスケジューリングを実行するとき、「モバイルコンピューティングほど良好で移動データ」の概念によれば、スパークは、タスクが処理されるべきデータブロックの格納位置に割り当て算出することが可能となります。

RDDタイプ

1.Transformation - >計算用記録(記録パラメータの算出方法)

変更

意味

マップ(FUNC)

新しいRDD、RDDは、変換関数func後の各入力要素の組成によって返します。

フィルタ(FUNC)

入力要素FUNC組成がtrueの後にそれは計算する関数によって返された新しいRDD、RDDを返します。

flatMap(FUNC)

(それはむしろ、単一の要素よりも、配列を返すべき機能)を同様のマップが、各入力要素は、ゼロ以上の出力要素にマッピングすることができます

mapPartitions(FUNC)

FUNC関数型はイテレータ[T] =>イテレータ[U]でなければならない場合、同様のマップが、しかしこのようRDD型Tを実行して、RDDの各スライス上で独立して実行

mapPartitionsWithIndex(FUNC)

操作の種類RDD T上のように、関数func型がなければならないので、同様のmapPartitionsが、指標パラメータの値とFUNC整数は、スライスを示し

(INT、イテレータ[T])=>イテレータ[U]

サンプル(にwithReplacement、分数、種子)

比率指定画分に応じたサンプルデータは、シード乱数発生器のシードを指定するため、交換する乱数を使用するかどうかを選択することができ

労働組合(otherDataset)

ソースRDDとRDDのパラメータと要件は、新しいRDDリターンを設定した後、

交差点(otherDataset)

差分 - > SET違い

RDDソースパラメータとの交差点の後に新しいRDD RDDを返します。

異なる([numTasks]))

         [パーティションの数を変更します]

ソースの後RDDは新しいRDDへの再復帰しました

groupByKey([numTasks])

(K、V)RDD呼の、それはRDDの(K、イテレータ[V])を返しますで

reduceByKey(FUNC、[numTasks])

RDDコールの(V K)、RDDの(V Kなど)を返し、指定された機能を低下させるが、同じキー値が同様groupByKeyと共に重合さで、タスクの数が第2によって実行することができる減らしますオプションのパラメータを設定します

aggregateByKey(zeroValue)(seqOp、combOp、[numTasks])


sortByKey([昇順]、[numTasks])

呼び出しRDDの(V K)において、Kは、順序付きインターフェースがソートRDDの鍵(K、V)によれば返し実装しなければなりません

SORTBY(FUNC、[昇順]、[numTasks])

そしてsortByKey似ていますが、より柔軟

参加(otherDataset、[numTasks])

RDD呼のタイプ(K、V)、及び(K、W)の一方の全ての要素を返し、同じキーは、(K、(V、W))を一緒にRDDに対応

コグループ(otherDataset、[numTasks])

在类型为(K,V)和(K,W)的RDD上调用,返回一个(K,(Iterable<V>,Iterable<W>))类型的RDD

cartesian(otherDataset)

笛卡尔积

pipe(command, [envVars])


coalesce(numPartitions)


repartition(numPartitions)

 重新分区

repartitionAndSortWithinPartitions(partitioner)


2.Action  -> 触发生成job(一个job对应一个action算子)

动作

含义

reduce(func)

通过func函数聚集RDD中的所有元素,这个功能必须是可交换且可并联的

collect()

在驱动程序中,以数组的形式返回数据集的所有元素

count()

返回RDD的元素个数

first()

返回RDD的第一个元素(类似于take(1))

take(n)

取数据集的前n个元素组成的数组

takeSample(withReplacement,num, [seed])

返回一个数组,该数组由从数据集中随机采样的num个元素组成,可以选择是否用随机数替换不足的部分,seed用于指定随机数生成器种子

takeOrdered(n[ordering])

takeOrdered和top类似,只不过以和top相反的顺序返回元素

saveAsTextFile(path)

将数据集的元素以textfile的形式保存到HDFS文件系统或者其他支持的文件系统,对于每个元素,Spark将会调用toString方法,将它装换为文件中的文本

saveAsSequenceFile(path

将数据集中的元素以Hadoop sequencefile的格式保存到指定的目录下,可以使HDFS或者其他Hadoop支持的文件系统。

saveAsObjectFile(path


countByKey()

针对(K,V)类型的RDD,返回一个(K,Int)的map,表示每一个key对应的元素个数。

foreach(func)

在数据集的每一个元素上,运行函数func进行更新。

创建RDD

Linux进入sparkShell:

/usr/local/spark.../bin/spark-shell \

--master spark://hadoop01:7077 \

--executor-memory 512m \

--total-executor-cores 2

或在Maven下:

object lx03 {

  def main(args: Array[String]): Unit = {

    val conf : SparkConf = new SparkConf()

      .setAppName("SparkAPI")

      .setMaster("local[*]")


    val sc: SparkContext = new SparkContext(conf)

    //通过并行化生成rdd

    val rdd1: RDD[Int] = sc.parallelize(List(24,56,3,2,1))

    //对add1的每个元素乘以2然后排序

    val rdd2: RDD[Int] = rdd1.map(_ * 2).sortBy(x => x,true)


    println(rdd2.collect().toBuffer)

    //过滤出大于等于10的元素

//    val rdd3: RDD[Int] = rdd2.filter(_ >= 10)


//    println(rdd3.collect().toBuffer)

  }

练习2

val rdd1 = sc.parallelize(Array("a b c", "d e f", "h i j"))

//将rdd1里面的每一个元素先切分在压平

val rdd2 = rdd1.flatMap(_.split(' '))

rdd2.collect

//复杂的:

val rdd1 = sc.parallelize(List(List("a b c", "a b b"), List("e f g", "a f g"), List("h i j", "a a b")))

//将rdd1里面的每一个元素先切分在压平

val rdd2 = rdd1.flatMap(_.flatMap(_.split(" ")))

练习3

val rdd1 = sc.parallelize(List(5, 6, 4, 3))

val rdd2 = sc.parallelize(List(1, 2, 3, 4))

//求并集

val rdd3 = rdd1.union(rdd2)


//求交集

val rdd4 = rdd1.intersection(rdd2)

//去重

rdd3.distinct.collect

rdd4.collect

练习4

val rdd1 = sc.parallelize(List(("tom", 1), ("jerry", 3), ("kitty", 2)))

val rdd2 = sc.parallelize(List(("jerry", 2), ("tom", 1), ("shuke", 2)))

//求join

val rdd3 = rdd1.join(rdd2)  -> 相同的key组成新的key,value

//结果: Array[(String,(Int,Int))] = Array((tom,(1,1)),(jerry,(3,2)))

rdd3.collect

//求左连接和右连接

val rdd3 = rdd1.leftOuterJoin(rdd2)

rdd3.collect

val rdd3 = rdd1.rightOuterJoin(rdd2)

rdd3.collect

//求并集

val rdd4 = rdd1 union rdd2

//按key进行分组

rdd4.groupByKey

rdd4.collect

//分别用groupByKey和reduceByKey实现单词计数

val rdd3 = rdd1 union rdd2

rdd3.groupByKey().mapValues(_.sum).collect

rdd3.reduceByKey(_+_).collect

groupByKey和reduceByKey的区别

reduceByKey算子比较特殊,它首先会进行局部聚合,再全局聚合,我们只需要传一个局部聚合的函数就可以了

图片1.png

练习5

val rdd1 = sc.parallelize(List(("tom", 1), ("tom", 2), ("jerry", 3), ("kitty", 2)))

val rdd2 = sc.parallelize(List(("jerry", 2), ("tom", 1), ("shuke", 2)))

//cogroup

val rdd3 = rdd1.cogroup(rdd2)

//注意cogroup与groupByKey的区别

rdd3.collect


val rdd1 = sc.parallelize(List(1, 2, 3, 4, 5))

//reduce聚合

val rdd2 = rdd1.reduce(_ + _)


//按value的降序排序

val rdd5 = rdd4.map(t => (t._2, t._1)).sortByKey(false).map(t => (t._2, t._1))

rdd5.collect

//笛卡尔积

val rdd3 = rdd1.cartesian(rdd2)


计算元素个数

scala> val rdd1 = sc.parallelize(List(2,3,1,5,7,3,4))

rdd1: org.apache.spark.rdd.RDD[Int] = ParallelCollectionRDD[0] at parallelize at <console>:27


scala> rdd1.count

res0: Long = 7  

top先升序排序在取值

scala> rdd1.top(3)

res1: Array[Int] = Array(7, 5, 4)                                               


scala> rdd1.top(0)

res2: Array[Int] = Array()


scala> rdd1.top(100)

res3: Array[Int] = Array(7, 5, 4, 3, 3, 2, 1)

take原集合前N个,有几个取几个

scala> rdd1.take(3)

res4: Array[Int] = Array(2, 3, 1)


scala> rdd1.take(100)

res5: Array[Int] = Array(2, 3, 1, 5, 7, 3, 4)


scala> rdd1.first

res6: Int = 2

takeordered倒序排序再取值

scala> rdd1.takeOrdered(3)

res7: Array[Int] = Array(1, 2, 3)


scala> rdd1.takeOrdered(30)

res8: Array[Int] = Array(1, 2, 3, 3, 4, 5, 7)

                             

生成RDD的两种方式

1.并行化方式生成 (默认分区两个)

手动指定分区

scala> val rdd1 = sc.parallelize(List(1,2,3,5))

rdd1: org.apache.spark.rdd.RDD[Int] = ParallelCollectionRDD[5] at parallelize at <console>:27


scala> rdd1.partitions.length  //获取分区数

res9: Int = 2


scala> val rdd1 = sc.parallelize(List(1,2,3,5),3)

rdd1: org.apache.spark.rdd.RDD[Int] = ParallelCollectionRDD[6] at parallelize at <console>:27


scala> rdd1.partitions.length

res10: Int = 3

2.使用textFile读取文件存储系统里的数据  

scala> val rdd2 = sc.textFile("hdfs://hadoop01:9000/wordcount/input/a.txt").flatMap(_.split(" ")).map((_,1)).reduceByKey(_+_)

rdd2: org.apache.spark.rdd.RDD[(String, Int)] = ShuffledRDD[11] at reduceByKey at <console>:27


scala> rdd2.collect  //调用算子得到RDD显示结果

res11: Array[(String, Int)] = Array((hello,6), (beijing,1), (java,1), (gp1808,1), (world,1), (good,1), (qianfeng,1))


scala> val rdd2 =  sc.textFile("hdfs://hadoop01:9000/wordcount/input/a.txt",4).flatMap(_.split(" ")).map((_,1)).reduceByKey(_+_)

rdd2: org.apache.spark.rdd.RDD[(String, Int)] = ShuffledRDD[26] at reduceByKey at <console>:27


scala> rdd2.partitions.length    //也可以自己指定分区数

res15: Int = 4


おすすめ

転載: blog.51cto.com/14479068/2431397