Spark RDD的簡單使用

本文首發於我的個人博客QIMING.INFO,轉載請帶上鍊接及署名。

RDD(Resilient Distributed Dataset)即彈性分佈式數據集。

RDD是Spark的核心,在Spark中,對數據的所有操作不外乎創建RDD、轉化已有RDD以及調用RDD操作進行求值。而在這一切的背後,Spark會自動將RDD中的數據分發到集羣上,並將操作並行化執行。

RDD的創建

創建RDD有兩種方式,一種爲讀取外部數據集,Spark從外部數據集中讀取數據一文中提到的各種方式都屬於此種;另一種較爲簡單,直接調用parallelize()方法對一個集合進行並行化即可,如下:

val rdd = sc.parallelize(List("spark","hello spark"))

即用此List創建了一個rdd,打印輸出此rdd:

scala> rdd.collect().foreach(println)
spark
hello spark

RDD的轉化操作

RDD的轉化操作即爲將1個或多個RDD轉化成一個新的RDD,常見操作有:
- map():將函數應用於RDD中的每個元素,將返回值構成新的RDD
- flatMap():將函數應用於RDD中的每個元素,將返回的迭代器的所有內容構成新的RDD。通常用來切分單詞。
- filter():返回一個由通過傳給filter()的函數的元素組成的RDD(即起篩選作用)

我們選取Spark從外部數據集中讀取數據一文中從HDFS中取出的RDD進行舉例說明:
hdfsresult
如圖,從HDFS中讀取的文本文件是按行存儲在rdd中的,即一行爲rdd的一個元素。
現在我們要將此rdd中的所有數字都存成元素以便後續操作,即1個元素變爲多個元素則應使用flatMap()方法:

val newRdd = rdd.flatMap(x=>x.split(" "))

然後輸出:

可以看出,newRdd有8個元素。
然後用map()將每個元素轉成int類型的並加1:

val newIntRdd = newRdd.map(x=>x.toInt).map(x=>x+1)

打印輸出:

再舉一個關於filter()的例子,假如我們要找出上述的所有奇數,代碼如下:

val oddNumRdd = newIntRdd.filter(x=>x%2==1)

(下文將對此oddNumRdd的操作進行舉例說明)

RDD的行動操作

RDD的行動操作即對RDD進行實際的計算,並將結果打印輸出或保存到外部存儲系統中,常見操作有:
- collect():返回RDD中的所有元素
- count():返回RDD中的元素個數
- take(n):返回RDD中前n個元素
- reduce(func):並行整合RDD中所有數據(例如sum)
- foreach(func):讓RDD中的每個元素使用func

collect()、count()和take()較爲簡單,舉例如下:

scala> oddNumRdd.collect()
res3: Array[Int] = Array(79, 23, 33, 5, 51)

scala> oddNumRdd.count()
res4: Long = 5

scala> oddNumRdd.take(3)
res5: Array[Int] = Array(79, 23, 33)

注:需要說明的是,collect()會將RDD中的所有元素都存放在內存中,所以不適合大規模數據集。

上文已多次用過foreach(println),即對RDD中的每個元素都進行打印輸出操作。
reduce()經常用來求和,如:

oddNumRdd.reduce((x,y)=>x+y)
res6: Int = 191
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章