Spark RDD彈性分佈式數據集 spark——spark中常說RDD,究竟RDD是什麼?

爲啥要學Spark中的RDD??

RDD的全稱叫做Resilient Distributed Datasets,即彈性分佈式數據集。

之前我們學過MapReduce,它具有自動容錯、平衡負載和可拓展性的優點,但是其最大缺點是採用非循環式的數據流模型,使得在迭代計算式要進行大量的磁盤IO操作。Spark中的RDD可以很好的解決這一缺點。

如何理解RDD   ------------>          可以將RDD理解爲一個分佈式存儲在集羣中的大型數據集合,不同RDD之間可以通過轉換操作形成依賴關係實現管道化,從而避免了中間結果的I/O操作,提高數據處理的速度和性能。

RDD是一個彈性可復原的分佈式數據集!
RDD是一個邏輯概念,一個RDD中有多個分區,一個分區在Executor節點上執行時,他就是一個迭代器。
一個RDD有多個分區,一個分區肯定在一臺機器上,但是一臺機器可以有多個分區,我們要操作的是分佈在多臺機器上的數據,而RDD相當於是一個代理,對RDD進行操作其實就是對分區進行操作,就是對每一臺機器上的迭代器進行操作,因爲迭代器引用着我們要操作的數據!

還是不懂啥是RDD?   看這個試試      請用通俗形象的語言解釋下:Spark中的RDD到底是什麼意思?              spark——spark中常說RDD,究竟RDD是什麼?


五大特點:

 

 

1. RDD的創建

我們通過Spark中的SparkContext對象調用textFile()方法加載數據創建RDD。(首先啓動Spark集羣,hadoop集羣    一個是在spark下的bin裏啓動start-all.sh    一個是隨便啓動start.all-sh)

①通過本地文件創建RDD

啓動Spark-shell   輸入:/export/servers/spark/bin/spark-shell --master local[1]

從文件系統中加載                     我在這個路徑下創建了一個txt       /export/data/temp/words.txt        導進去

 

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

 

 從hdfs上加載    剛纔沒開hadoop集羣的現在開,並且重啓spark服務  

這次從hdfs上加載   輸入:/export/servers/spark/bin/spark-shell --master spark://hadoop01:7077

 

 

 從hadoop上拿東西下來   我的hadoop在   spark/input/words.txt  有文件(注意hadoop與文件系統的區別    文件系統有file://)

 

 

 

 

 

 ③通過並行方式創建RDD(建一個數組,通過數組建)

 

 

 

 

 

 2.RDD處理過程

Spark用Scala語言實現了RDD的API,程序開發者可以通過調用API對RDD進行操作處理。RDD經過一系列的“轉換”操作,每一次轉換都會產生不同的RDD,以供給下一次“轉換”操作使用,直到最後一個RDD經過“行動”操作纔會被真正計算處理,並輸出到外部數據源中,若是中間的數據結果需要複用,則可以進行緩存處理,將數據緩存到內存中。

轉換算子和行動算子的區別:  (不太懂可以看看這個       區別)
    Ⅰ.轉換算子返回的是一個新的RDD。行動算子返回的不是RDD,可能是map,list,string等,也可以沒有返回。
    Ⅱ.轉換算子相當於邏輯的封裝。行動算子調用sc.runjob執行作業,是對邏輯計算產生結果。
    Ⅲ.sortBy算子 既有轉換又有行動的功能,產生一個job,返回一個新的RDD。

①行動算子

行動算子主要是將在數據集上運行計算後的數值返回到驅動程序,從而觸發真正的計算。下面,通過一張表來列舉一些常用行動算子操作的API。

 

 

 

 

 

 

 

foreach不太會用

 

 

 

 

 

 

 

 

② 轉換算子

RDD處理過程中的“轉換”操作主要用於根據已有RDD創建新的RDD,每一次通過Transformation算子計算後都會返回一個新RDD,供給下一個轉換算子使用。下面,通過一張表來列舉一些常用轉換算子操作的API

 

 

 filter(func) 篩選東西  舉個例子,比如篩選words.txt中的

 

把hello篩選出來

 

 

 啥!?竟然說我這個文件不存在,很明顯是存在的,但最後結果是出來的

 

 

 換成本地進入試試,也成功

 

 在上述代碼中,filter() 輸入的參數 line => line.contains("spark") 是一個匿名函數,其含義是依次取出lines這個rdd中的每一個元素,對於當前取到的元素,把它賦值給匿名函數中的line變量。若line中包含spark單詞,就把這個元素加入到rdd(即 linesWithSpark)中,否則就丟棄該元素。

map(func)

將每個元素傳遞到函數func中,返回的結果是一個新的數據集

以下演示從words.txt 文件中加載數據的方式創建rdd,然後通過map操作將文件中的每一行內容都拆分成一個個的單詞元素,這些單詞組成的集合是一個新的rdd

 

 

 

因爲我有幾個空行,所以顯示了幾個Array("")

 

 

 上述代碼中,lines.map(line => line.split(" ")) 的含義是依次取出lines這個rdd中的每個元素,對於當前取到的元素,把它賦值給匿名函數中的line變量。由於line是一行文本,一行文本中包含多個單詞,且用空格分隔,通過line.split("")匿名函數,將文本分成一個個的單詞,每一行拆分後的單詞都被封裝到一個數組中,成爲新的rdd(即words)中的一個元素。 

flatMap(func)

不知道爲何全拆了

又試了試,發現我拆分的時候少個空格

 

 

 groupByKey()

groupByKey() 主要用於(key,value)鍵值對的數據集,將具有相同key的value進行分組,會返回一個新的(key,Iterable)形式的數據集。同樣以文件words.txt 爲例,描述如何通過groupByKey算子操作將文件內容中的所有單詞進行分組。

 

 

 

 還是全拆了,我把空格刪除再試試

 

 

 

 reduceByKey(func)

reduceByKey(func)主要用於(key,value) 鍵值對的數據集,返回的是一個新的(key,value)形式的數據集,該數據集是每個key傳遞給func函數進行聚合運算後得到的結果。

執行words.reduceByKey((a,b) => a + b) 操作,共分爲兩個步驟,分別是先執行reduceByKey操作,將所有key相同的value值合併到一起,生成一個新的鍵值對,比如(“spark”,(1,1,1));然後執行函數func的操作,即使用(a,b)=> a + b函數把(1,1,1)進行聚合求和,得到最終的結果,即(“spark”,3)

 

 

 

 

 

 三個小案例

案例一    spark實現運營案例   

模擬從網頁上獲取日誌,通過日誌分析用戶的pv操作進行了多少次

1.把logs日誌文件建立在linux上

 

 2.進入scala-shell中上傳文件   /export/servers/spark/bin/spark-shell --master local         

 

 

 3.進行區分,整成(pv ,1)

 

 4.進行合併操作用  通過 reduceByKey()

 

 

 

案例二   查看訪問時間

 

上傳文件

 

 

拆分

 

 

 

 

 計數

 

 合併

 

 

 

 排序

 

 

案例三 獨立訪客

所謂獨立訪客,就是把每個IP給分出來,然後計數

上傳文件

 

 按照空格分割

 

 去重

 寫1

 

 相加求和  記得用reduceByKey

 

 下載文件

 

 

 

 

 

嘿嘿,結束昨天的任務~

 

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