Spark系列修煉 入門筆記17

2021-07-25 02:36:08 字數 4064 閱讀 3317

核心內容:

1、rdd入門筆記1

今天又邁出了一步—涉獵rdd,好吧,進入文章的正題:rdd是乙個容錯的,並行的資料結構,可以控制將資料儲存到磁碟或記憶體中,能夠獲取資料的分割槽。通常資料處理的模型包括:迭代計算、關係查詢、mapreduce、流失處理等。hadoop採用mapreduce模型,storm採用流式處理模型,而spark則實現了以上所有的資料處理模型。(呵呵,spark就是厲害啊!)

首先我們先談一談資料集和工作集的工作方式:

資料集:基於資料集的處理工作方式就是從物理儲存裝置上載入資料,然後運算元據,然後寫入物理儲存裝置,基於資料集的處理方式的代表就是hadoop的mapreduce。

然而由於基於資料集的處理工作方式每次都要從物理儲存裝置上讀取資料,然後運算元據,然後寫回物理裝置。導致基於資料集的處理方式有幾種場景不試用

1、不適合於大量的迭代演算法。所謂迭代就是每一步對資料執行相似的函式(操作),hadoop的mapreduce不適用這種場景。

2、不適合於互動式查詢。

呵呵,互動式的含義—-計算機術語「互動式」:

系統與操作人員以人機對話的方式一問一答,直至獲得最後處理結果。採用這種方式,程式設計人員可以邊設計,邊調整,邊修改,使錯誤和不足之處及時得到改正和補充。特別對於非專業的操作人員,系統能提供提示資訊,逐步引導操作者完成所需的操作,得出處理結果。這種方式和非互動式處理相比具有靈活、直觀、便於控制等優點,因而被越來越多的資訊處理系統所採用。

由於基於資料集的工作方式每次的查詢都需要從磁碟上讀取資料,然後執行查詢,然後在寫回資料結果,每一次都必須這樣,這樣效率等等都是乙個問題。

3、基於資料流的方式不能夠復用曾經的結果或中間計算結果,這點是最致命的。

場景:假設有數千人併發資料倉儲,而其中100人的查詢完全相同,從hadoop的mapreduce基於資料流的角度講,那麼每個人都需要重新查詢。因為基於資料流的方式不能夠復用曾經的結果。但是spark就可以避免,因為spark可以對結果進行復用,(呵呵,mapreduce不服不行啊!)

好的,接下來我們在談一下工作集:

工作集:曾經執行的工作,其他人在執行的話,不需要重新執行,而基於資料流需要重新執行(如果是hadoop的話1000個人執行同樣的查詢,就需要重複執行1000次)。

注意:基於工作集的工作方式,即使結果放在磁碟上也是直接拿結果,不需要重新計算,只不過(spark)現在是快取在磁碟上而已,快取在磁碟上比你直接在算一遍在放在磁碟上肯定要快,當然快取多久看我們的執行了,我們當然可以將快取清除掉:快取隨時可以清理掉,如果記憶體或磁碟不足就需要根據優先度將不常使用的快取內容清理掉。

rdd的cache是直接放在記憶體中的;最安全的措施就是checkpoint,但是checkpoint是重量級的:sparkstreaming經常要進行checkpoint(checkpoint一般就要放在磁碟嘛),原因是經常要用到以前的內容。

結論:hadoop的mapreduce是基於資料集的工作方式,spark(rdd)是基於工作集的工作方式,資料處理方式的不同,從先天上就導致了spark相比於mapreduce具有巨大的優勢。

呵呵,來張圖惡搞一下:

spark中的rdd是基於工作集的應用抽象,本身除了具有位置感知、容錯、負載均衡的特點之外,spark中的rdd還增加了resillient distributed dataset。

rdd的彈性表現為7個方面

1、自動的進行記憶體和磁碟資料儲存的切換

2、基於lineage(依賴,迭代)的高效容錯

3.、task如果失敗會自動進行特定次數的重試 (即失敗了不立即就掛了,這也是彈性)

4、stage如果失敗會自動進行特定次數的重試而且重試時只會試算失敗的分片。

5、checkpoint(其實是乙個重量級的操作,我們每次對rdd進行操作,一般都會採用新的rdd,當然除了最後乙個action觸發作業以外,當然如果有的時候鏈條比較長或者計算比較笨重的時候,我們就考慮將資料都放在磁碟上,這就是checkpoint)和persist(在記憶體中或在磁碟中對資料進行復用,cache是persist的一種特殊情況),實際上這2個特點是效率和容錯的延伸,同時也是復用方面的內容

6、資料排程彈性:dag task和資源管理無關

7、資料分片的高度彈性(自由設定分片函式)即partition可伸縮。

我們在計算的過程中可能會產生很多資料碎片,這種時候乙個partition就會非常小,如果每個小partition都消耗乙個執行緒進行處理的話,就會降低處理效率。這種時候就可以考慮把小檔案(小的partition)合併成乙個大檔案(較大的partition);另外乙個方面,如果記憶體不多,而每個partition資料比較大(比block大),此時就可能考慮將資料變成更小的分片,此時儘管spark將會出現更多的處理批次但是不會出現oom。所以說通過改變資料分片的大小來提高並行度或降低並行度也是spark高度彈性的表現。同時需要指出的是,不管是提高並行度還是降低並行度,在處理資料時仍具有資料本地性。當然,提高並行度還是降低度行度都是人工通過**來調整的。

接下來我們談一下spark中rdd的本質

spark的每一步操作都是對rdd進行操作,而rdd是唯讀分割槽的集合,rdd本身就是乙個資料的集合,可以簡單將rdd理解為乙個list或array。用一句話概括:rdd是分布式函式式程式設計的抽象。

基於rdd的程式設計一般都是通過高階函式的方式,之所以採用高階函式是因為函式裡面傳函式要對我們當前的這個函式(如map函式)作用的資料集進行每條記錄的明細化操作,另外由於我們是分布式的集群,所以rdd叫做分布式函式式程式設計。

假設spark有1000個rdd,一般不會產生中間結果,預設情況下只產生一次中間結果。為了不讓其產生中間結果,就不能讓他立即計算。而這就是lazy:不用時不算,用時才計算,所以不會產生中間結果。

rdd的核心之一就是它的lazy級別,因為它不計算,開始的時候只是對資料的處理進行標記而已,比如我們的textfile根本就不從磁碟上讀資料,map、flatmap其實並不計算資料,只是產生了操作的標記而已,只有觸發的時候才計算。

由於spark本身的rdd本身是唯讀的,為了應對計算模型,rdd又是lazy級別的。rdd每次操作都會產生新的rdd,每次構建新的rdd都是把父rdd作為第乙個引數傳入,這就構成了乙個鏈條。在計算的最後action才觸發操作,這就構成了乙個從後往前回溯的過程,其實就是函式展開的過程。

總結一下:rdd是lazy級別的且是不可變的,構成了鏈條,這種機制導致兩點結果

第一:計算的時候是從後往前回溯,不會每次計算的時候都會產生中間的計算結果。僅僅是記錄了對其進行了

什麼操作,即僅僅是乙個標記。

第二:容錯的時候會記錄前面的東西,在前面某乙個步驟的基礎上,而不是從頭開始算。

問題1:從第900步驟恢復的前提是要在第900步驟步驟持久化嗎?

是的,需要在第900步驟持久化,或者說第900步驟是上乙個stage的結束,或者說第900步驟進行了checkpoint,或者進行了persist。即恢復點要麼是checkpoint要麼是前乙個stage的結果(因為stage結束時會自動寫磁碟)

問題2:rdd是粗粒度的還是細粒度的呢?

所謂粗粒度就是每次操作的時候都作用於所有的資料集合。如果說更新粒度太細太多,記錄成本就會非常高,效率就不會那麼高。rdd的寫操作或者改變操作都是粗粒度的。即我們所說的rdd是粗粒度的指的是rdd的寫操作是粗粒度的,但是rdd的讀操作既可以是粗粒度的又可以是細粒度的。(寫操作就是修改資料,讀就是查詢資料),我們如果通過rdd讀取資料,可以直接讀取其中的一條記錄(即讀操作可以是細粒度的)。

問題3:rdd的缺陷

不支援細粒度的更新(寫)操作和不支援增量迭代計算(如網路爬蟲),即spark框架本身不支援增量迭代計算,因為增量迭代的時候每次可能只迭代其中的一部分資料,但由於rdd本身是粗粒度的,不能很好的進行增量迭代。無法考慮是不是只是一部分資料。

ok,繼續努力!

Spark系列修煉 入門筆記15

核心內容 1 spark架構入門筆記 2 clustermanager 資源排程 driver 作業執行排程的詳解 今天進一步深入學習了spark,主要學習的內容為spark的核心架構,好的,進入本篇文章的正題。注意 本篇文章談的是spark的stanalone模式。先談一下我自己對於spark程式...

Spark系列修煉 入門筆記18

核心內容 1 spark當中常用的3種建立rdd的方式 2 自定義分片個數 並行度 今天又學習了一講spark spark本身就是乙個計算框架,就是乙個jvm計算框架而已 2016年12月份注定不平凡了,希望在2016年的最後乙個月份多做一些有意義的事情,畢業在即 好了,進入文章的正題,從學習spa...

Spark入門系列

讀完spark官方文件後,在研究別人的原始碼以及spark的原始碼之前進行一番入門學習,這個系列不錯。spark系列 除此之外,databricks也是乙個非常不錯的 上面可以使用免費的spark集群進行 提交與測試,在youtube以及spark大會中都有其發布教程以及spark應用部署的相關細節...