大數據第十四周——Spark編程(RDD編程)

第十五週 Spark編程基礎

  1. 啓動集羣並檢查Spark
  • 基於上週未完成部分,這周補上。直接輸入以下命令,

~/spark-2.4.5/bin/spark-submit --class org.apache.spark.examples.SparkPi --master yarn-cluster ~/spark-2.4.5/examples/jars/spark-examples_2.11-2.4.5.jar

  • 當出現下圖結果是表示運行成功,並在瀏覽器中輸入結果中的URL,查看結果。

  • 如下圖所示,結果在"Logs"中的"stdout"裏。

  1. RDD創建
  • RDD:是Resillient Distributed Dataset(彈性分佈式數據集)的簡稱,是分佈式內存的一個抽象概念,提供了一種高度受限的共享內存模型
  • 目前的MapReduce框架都是把中間結果寫入到HDFS中,帶來了大量的數據複製、磁盤IO和序列化開銷。RDD就是爲了滿足這種需求而出現的,它提供了一個抽象的數據架構,我們不必擔心底層數據的分佈式特性,只需將具體的應用邏輯表達爲一系列轉換處理,不同RDD之間的轉換操作形成依賴關係,可以實現管道化,避免中間數據存儲。
  • RDD提供了一組豐富的操作以支持常見的數據運算,分爲"動作"(Action)和"轉換"(Transformation)兩種類型。RDD提供的轉換接口都非常簡單,都是類似map、filter、groupBy、join等粗粒度的數據轉換操作,而不是針對某個數據項的細粒度修改。
  • Spark採用textFile()方法來從文件系統中加載數據創建RDD。該方法把文件的URI作爲參數,這個URI可以是:
    • 本地文件系統的地址
    • 或者是分佈式文件系統HDFS的地址
    • 或者是Amazon S3的地址等等

2.1    從文件系統中加載數據創建RDD

2.1.1 從本地文件系統中加載數據創建RDD

  • scala> val lines = sc.textFile("file:///usr/local/spark/mycode/rdd/word.txt")

    文件中的信息如下圖所示:

  • 直接在scala下"sc"會出問題,因爲scala下並沒有封裝spark的上下文。要在spark下編程。

  • 如下圖所示,運行成功,但這只是一個轉化操作,它只是記錄了以下。

  • 執行一個action操作,檢查是否可以正常運行。用lines.count(),返回的是文件中的行數,因爲RDD是一行行讀取文件信息的,如下圖所示。

  1. 從分佈式文件系統HDFS中加載數據
  • 在hdfs文件系統中新建文件夾,再上傳文件。

    hadoop fs –mkdir testSpark

    hadoop fs –put word.txt /testSpark

    在瀏覽器中輸入master:50070可以查看hdfs詳細信息。

  • 輸入轉換命令,以下三條語句完全等價,可以選擇任何一種。

    scala> val lines = sc.textFile("hdfs://localhost:9000/user/hadoop/word.txt")

    scala> val lines = sc.textFile("/user/hadoop/word.txt")

    scala> val lines = sc.textFile("word.txt")

  1. 通過並行集合(數組)創建RDD
  • 可以調用SparkContext的parallelize方法,在Driver中一個已經存在的集合(數組)上創建。從數組創建RDD示意圖如下圖所示。

    scala>val array = Array(1,2,3,4,5)

    scala>val rdd = sc.parallelize(array)

  • 或者,也可以從列表中創建。

    scala>val list = List(1,2,3,4,5)

    scala>val rdd = sc.parallelize(list)

  1. RDD操作

2.3.1 轉化操作

  • 下表是常用的RDD轉換操作API

  • 對於RDD而言,每一次轉換操作都會產生不同的RDD,供給下一個"轉換"使用。轉換得到的RDD是惰性求值的,也就是說,整個轉換過程只是記錄了轉換的軌跡,並不會發生真正的計算,只有遇到行動操作時,纔會發生真正的計算,開始從血緣關係源頭開始,進行物理的轉換操作。如下圖所示。

  1. filter(func)
  • filter()操作實例執行過程示意圖如下。

  • 命令如下:

    scala> val lines =sc.textFile(file:///usr/local/spark/mycode/rdd/word.txt)

    scala> val linesWithSpark=lines.filter(line => line.contains("Spark"))

  • 嘗試一個例子,挑出所有還有"hello"這個詞的行,並輸出。文件內容如圖所示。

  • 命令如下

scala>val filterlines=sc.textFile("hdfs://master:9000/testSpark2/word2.txt")

scala>filterlines.collect()

scala> val filterlines=sc.textFile("hdfs://master:9000/testSpark2/word2.txt")

scala> filterlines.collect()

scala> val afterfilter=filterlines.filter(abc=>abc.contains("hello"))

scala> afterfilter.collect()

(2)map(func)

  • map(func)操作將每個元素傳遞到函數func中,並將結果返回爲一個新的數據集。
  • map操作的例子如下圖所示。

scala> val dat=Array(1,2,3,4,5)

scala> val indat=sc.parallelize(dat)

scala> val outdat=indat.map(aa=>aa+10)

scala> outdat.collect()

(3)flatMap(func)

  • flatMap()操作實例執行過程示意圖如下圖所示。

  • 嘗試一個例子,命令和結果如下。

    scala> filterlines.collect()

    scala> val afterflatmap=filterlines.flatMap(x=>x.split(" "))

    scala> afterflatmap.collect()

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