Spark之RDD編程常用算子代碼例子

RDD

1、RDD(Resilient Distributed Datasets)彈性的分佈式數據集,又稱Spark core,它代表一個只讀的、不可變、可分區,裏面的元素可分佈式並行計算的數據集。

2、RDD主要有兩大類操作,分別爲轉換(Transformations)和行動(Actions),轉換操作通過某種函數將一個RDD轉換爲一個新的RDD,但是轉換操作是懶操作,不會立即執行計算。而行動操作是用於觸發轉換操作的操作,這個時候纔會真正開始計算。

3、常用的Transformations函數

函數 描述
map(func) 對RDD數據集中的每個元素都使用func,返回一個新的RDD
filter(func) 對RDD數據集中的每個元素都使用func,返回使func爲true的元素構成的RDD
flatMap(func) 和map類似,但是flatMap生成的是多個結果
union(otherDataset) 返回一個新的dataset,包含源dataset和給定dataset的元素的集合
grouplyKey(num Tasks) 返回( K,Seq[V] ),根據相同的鍵分組
reducclykey(func [numTasks]) 用一個給定的func作用在grouplyKey 而產生的(K,Seq[V),比如求和

4、常用的Actions函數

函數 描述
reduce( func) 通過函數func聚集數據集中的所有元素。func函數接收兩個參數,返回一個值
collect() 返回數據集中所有的元素
count() 返回數據集中所有元素的個數
first0) 返回數據集中的第一個元素
take(n) 返回前n個元素
saveAsTextFile(path) 將數據集的元素以textfile的形式保存到本地文件系統、hdfs或者任何其他Hadoop支持的文件系統。Spark將會調用每個元素的toString方法,並將它轉換爲文件中的一行文本
foreach(func) 對數據集中的每個元素都執行函數func

一、創建RDD

1、從對象集合創建RDD

spark可以通過parallelize()或makeRDD()方法將一個對象集合轉化爲RDD

scala> val rdd=sc.parallelize(List(1,2,3,4,5,6))
rdd: org.apache.spark.rdd.RDD[Int] = ParallelCollectionRDD[0] at parallelize at <console>:24

scala> val rdd=sc.makeRDD(List(1,2,3,4,5,6))
rdd: org.apache.spark.rdd.RDD[Int] = ParallelCollectionRDD[1] at makeRDD at <console>:24

從返回信息可以看出,上述創建的RDD中存儲的是Int類型數據,實際上,RDD也是一個集合,與常用的List集合不同的是,RDD集合的數據分佈在多臺計算機上。

2、從外部存儲創建RDD

(1)從HDFS文件創建RDD

直接通過textFile命令讀取HDFS文件的位置即可。

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

scala> rdd.collect
res0: Array[String] = Array(hello hadoop, hello spark, hello scala)
(2)從Linux本地文件創建RDD

本地文件讀取也是通過sc.textFile(“路徑”)的方法,在路徑前面加上“file://”表示從本地Linux文件系統讀取。

scala> val rdd=sc.textFile("file:///usr/local/spark/words.txt")
rdd: org.apache.spark.rdd.RDD[String] = file:///usr/local/spark/words.txt MapPartitionsRDD[7] at textFile at <console>:24

scala> rdd.collect
res2: Array[String] = Array(hello hadoop, hello spark, hello scala)

從上述rdd.collect的輸出內容可以看到,textFile()方法將源文件中的內容按行拆分成了RDD集合中的多個元素。

二、轉換算子

1、map()算子

map()是一種基礎的RDD轉換操作,它接收一個函數作爲參數,並把這個函數應用於RDD的每個元素,最後將函數的返回結果作爲結果RDD中對應元素的值。
例如,將rdd1中的每個元素加1(_+1等同於x=>x+1)並返回一個名爲rdd2的新RDD:

scala> val rdd1=sc.parallelize(List(1,2,3,4,5))
rdd1: org.apache.spark.rdd.RDD[Int] = ParallelCollectionRDD[8] at parallelize at <console>:24

scala> val rdd2=rdd1.map(_+1)
rdd2: org.apache.spark.rdd.RDD[Int] = MapPartitionsRDD[9] at map at <console>:25

scala> rdd2.collect
res3: Array[Int] = Array(2, 3, 4, 5, 6)

2、filter()算子

通過函數對源RDD的每個元素進行過濾,並返回一個新的RDD。

scala> val rdd1=sc.parallelize(List(1,2,3,4,5))
rdd1: org.apache.spark.rdd.RDD[Int] = ParallelCollectionRDD[10] at parallelize at <console>:24

scala> val rdd2=rdd1.filter(_>3)
rdd2: org.apache.spark.rdd.RDD[Int] = MapPartitionsRDD[11] at filter at <console>:25

scala> rdd2.collect
res4: Array[Int] = Array(4, 5)

3、flatMap()算子

與map()算子類似,但是每個傳入給函數func的RDD元素會返回0到多個元素,最終會將返回的所有元素合併到一個RDD。
例如:將集合List轉化爲rdd1,然後調用rdd1的flatMap()算子將rdd1的每個元素按照空格分割成多個元素,最終合併所有元素到一個新的RDD。

scala> val rdd1=sc.parallelize(List("hadoop hbase hive" ,"hadoop spark"))
rdd1: org.apache.spark.rdd.RDD[String] = ParallelCollectionRDD[12] at parallelize at <console>:24

scala> val rdd2=rdd1.flatMap(_.split(" "))
rdd2: org.apache.spark.rdd.RDD[String] = MapPartitionsRDD[13] at flatMap at <console>:25

scala> rdd2.collect
res5: Array[String] = Array(hadoop, hbase, hive, hadoop, spark)

4、distinct()算子

distinct()是一個轉換操作,用於RDD的數據去重,去除兩個完全相同的元素,沒有參數。
例如:將flatMap()算子的例子的rdd2去重

scala> rdd2.distinct().collect
res6: Array[String] = Array(spark, hive, hadoop, hbase)

5、groupByKey()算子

groupByKey()是對具有相同鍵的值進行分組,分組常常是爲了對同一組的數據進行計數、統計等。

scala> val rdd1=sc.parallelize(List(("hadoop",1),("hadoop",2),("spark",1),("spark",1)))
rdd1: org.apache.spark.rdd.RDD[(String, Int)] = ParallelCollectionRDD[17] at parallelize at <console>:24

scala> val rdd2=rdd1.groupByKey()
rdd2: org.apache.spark.rdd.RDD[(String, Iterable[Int])] = ShuffledRDD[18] at groupByKey at <console>:25

scala> rdd2.collect
res7: Array[(String, Iterable[Int])] = Array((spark,CompactBuffer(1, 1)), (hadoop,CompactBuffer(1, 2)))

6、reduceByKey()算子

reduceByKey()算子的作用對象是元素爲(key,value)形式的RDD,可以將相同的key的元素聚集到一起,最終把所有相同key的元素合併成爲一個元素。

scala> val rdd1=sc.parallelize(List(("hadoop",1),("hadoop",2),("spark",1),("spark",1)))
rdd1: org.apache.spark.rdd.RDD[(String, Int)] = ParallelCollectionRDD[19] at parallelize at <console>:24

scala> val rdd2=rdd1.reduceByKey((x,y)=>x+y)
rdd2: org.apache.spark.rdd.RDD[(String, Int)] = ShuffledRDD[20] at reduceByKey at <console>:25

scala> rdd2.collect
res8: Array[(String, Int)] = Array((spark,2), (hadoop,3))

7、sortBy()算子

將RDD中的元素按照某個規則進行排序,該算子的第一個參數爲排序函數,第二個參數是一個布爾值,指定升序(默認)或降序。如需要降序排列,則將第二個參數置爲false。

scala> val rdd1=sc.parallelize(List(("hadoop",5),("Spark",7),("scala",3)))
rdd1: org.apache.spark.rdd.RDD[(String, Int)] = ParallelCollectionRDD[21] at parallelize at <console>:24

scala> val rdd2=rdd1.sortBy(x=>x._2,false)
rdd2: org.apache.spark.rdd.RDD[(String, Int)] = MapPartitionsRDD[24] at sortBy at <console>:25

scala> rdd2.collect
res9: Array[(String, Int)] = Array((Spark,7), (hadoop,5), (scala,3))

8、union()算子

將兩個RDD合併爲一個新的RDD,主要用於對不同的數據來源進行合併,兩個RDD中的數據類型要保持一致。

scala> val rdd1=sc.parallelize(List(1,2,3))
rdd1: org.apache.spark.rdd.RDD[Int] = ParallelCollectionRDD[25] at parallelize at <console>:24

scala> val rdd2=sc.parallelize(List(4,5,6))
rdd2: org.apache.spark.rdd.RDD[Int] = ParallelCollectionRDD[26] at parallelize at <console>:24

scala> val rdd3=rdd1.union(rdd2)
rdd3: org.apache.spark.rdd.RDD[Int] = UnionRDD[27] at union at <console>:27

scala> rdd3.collect
res10: Array[Int] = Array(1, 2, 3, 4, 5, 6)

三、行動算子

1、reduce()算子

將數字1-100所組成的集合轉化爲RDD,然後對該RDD進行reduce()算子計算,統計RDD中所有元素的總和。

scala> val rdd1=sc.parallelize(1 to 100)
rdd1: org.apache.spark.rdd.RDD[Int] = ParallelCollectionRDD[29] at parallelize at <console>:24

scala> rdd1.reduce(_+_)
res12: Int = 5050

2、count()算子

統計RDD集合中元素的數量。

scala> val rdd1=sc.parallelize(1 to 100)
rdd1: org.apache.spark.rdd.RDD[Int] = ParallelCollectionRDD[29] at parallelize at <console>:24

scala> rdd1.count
res13: Long = 100

3、take()算子

返回集合中前n個元素組成的數組。

scala> val rdd1=sc.parallelize(1 to 100)
rdd1: org.apache.spark.rdd.RDD[Int] = ParallelCollectionRDD[29] at parallelize at <console>:24

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

四、使用Spark RDD實現單詞計數

我的另一篇博客有介紹 :使用Spark RDD實現單詞計數

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