第十五週 Spark編程基礎
-
啓動集羣並檢查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"裏。
-
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是一行行讀取文件信息的,如下圖所示。
、
-
從分佈式文件系統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")
-
通過並行集合(數組)創建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)
-
RDD操作
2.3.1 轉化操作
-
下表是常用的RDD轉換操作API
-
對於RDD而言,每一次轉換操作都會產生不同的RDD,供給下一個"轉換"使用。轉換得到的RDD是惰性求值的,也就是說,整個轉換過程只是記錄了轉換的軌跡,並不會發生真正的計算,只有遇到行動操作時,纔會發生真正的計算,開始從血緣關係源頭開始,進行物理的轉換操作。如下圖所示。
-
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()