RDD常用的transformation及分區詳解

常用的transformation(轉換,延遲加載)

創建RDD有兩種方法:

1.通過driver端,也就是spark-shell端通過集合來創建。

2.可以通過集羣上的數據來創建。


通過driver端創建的集合通過parallelize並行化集合可以轉換爲RDD

scala> val arr = Array(1,2,3,4,5)
arr: Array[Int] = Array(1, 2, 3, 4, 5)

scala> val rdd1 = sc.parallelize(arr)
rdd1: org.apache.spark.rdd.RDD[Int] = ParallelCollectionRDD[91] at parallelize at <console>:26

在RDD中存在分區,例如將一個集合並行化爲一個RDD後,在經過一系列轉化,最後存入hdfs。儘管最後存入的數據爲空,但是在hdfs上會產生固定的文件數量,我的一直是4個。

scala> val arr = Array(1,2,3,4,5)
arr: Array[Int] = Array(1, 2, 3, 4, 5)

scala> val rdd1 = sc.parallelize(arr)
rdd1: org.apache.spark.rdd.RDD[Int] = ParallelCollectionRDD[91] at parallelize at <console>:26

scala> val rdd2 = rdd1.filter(_%2==0)
rdd2: org.apache.spark.rdd.RDD[Int] = MapPartitionsRDD[92] at filter at <console>:28

scala> val rdd3 = rdd2.map(_ * 10)
rdd3: org.apache.spark.rdd.RDD[Int] = MapPartitionsRDD[93] at map at <console>:30

scala> rdd1.collect
res11: Array[Int] = Array(1, 2, 3, 4, 5)

scala> rdd2.collect
res12: Array[Int] = Array(2, 4)

scala> rdd3.collect
res13: Array[Int] = Array(20, 40)

scala> rdd3.saveAsTextFile("hdfs://slave1.hadoop:9000/spark/tmp")
                                                                                

這是存入hdfs的文件

[root@slave1 spark-2.2.0]# hadoop fs -ls /spark/tmp
Found 5 items
-rw-r--r--   2 root supergroup          0 2018-08-30 21:21 /spark/tmp/_SUCCESS
-rw-r--r--   2 root supergroup          0 2018-08-30 21:21 /spark/tmp/part-00000
-rw-r--r--   2 root supergroup          3 2018-08-30 21:21 /spark/tmp/part-00001
-rw-r--r--   2 root supergroup          0 2018-08-30 21:21 /spark/tmp/part-00002
-rw-r--r--   2 root supergroup          3 2018-08-30 21:21 /spark/tmp/part-00003

然後繼續查看數據的分區,爲什麼是四個呢。

//查看分區
scala> rdd1.partitions.length
res15: Int = 4

scala> rdd2.partitions.length
res16: Int = 4

scala> rdd3.partitions.length
res17: Int = 4

其實這是跟執行運算的總核數有關係的,我的每臺機器分配了兩個核,一共兩臺worker,所以總核數就是4.

RDD也可以指定分區,在RDD生成的時候可以指定。sc.parallelize(arr,2),這樣生成的RDD就是有兩個分區。如果不指定的話RDD分區數量就跟EXECUTOR的總核數有關。上面的例子是沒有指定分區的情況,下面演示指定分區的情況:

scala> val arr = Array(1,2,3,4,5)
arr: Array[Int] = Array(1, 2, 3, 4, 5)

scala> val rdd1 = sc.parallelize(arr, 2)
rdd1: org.apache.spark.rdd.RDD[Int] = ParallelCollectionRDD[103] at parallelize at <console>:26

scala> rdd1.partitions.length
res23: Int = 2

如果RDD是通過集羣上的數據生成的,RDD的分區就跟文件的切片有關係。假如hdfs目錄下有兩個小文件,那麼讀取的數據轉換成RDD就是有兩個分區,因爲文件較小,所以一個文件就是一個切片。

hdfs的spark文件夾下面有兩個數據:

[root@slave1 ~]# hadoop fs -ls /spark
Found 2 items
-rwxrwxrwx   2 root supergroup         42 2018-08-24 20:11 /spark/a.txt
-rw-r--r--   2 root supergroup         44 2018-08-30 22:09 /spark/b.txt

那麼讀取該數據後生成的RDD爲幾個分區呢!以下例子進行展示:

scala> val rdd1 = sc.textFile("/spark")
rdd1: org.apache.spark.rdd.RDD[String] = /spark MapPartitionsRDD[105] at textFile at <console>:24

scala> rdd1.partitions.length
res26: Int = 2

scala> 

結果爲2,跟想象中的一樣。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章