即使採用pipeline的方式,函式f對依賴的rdd中的資料操作也會有兩種方式:
1,f(record),f作用於集合的每一條記錄,每次只作用於一條記錄
2,f(records), f一次性作用於集合的全部資料
spark的實現,是採用第一種方式,為什麼採用第一種方式,
原因 1,無需等待,可以最大化的使用集群的計算資源
2,可以減少oom的發生,
3,最大化的有利於併發
4,可以精準的控制每個partiton本身(dependency)及其內部的計算(compute)
5,基於lineage的運算元流動式函式式程式設計,節省了中間結果的產生,並且可以最快的恢復
疑問:會不會增加網路的通訊?當然不會,因為在pipeline,在乙個stage中
二:思考spark job具體的物理執行
例如spark-shell預設啟動的時候內部就沒有job,只是作為資源的分配程式,
可以在裡面寫**產生若干個job,普通程式中一般而言可以有不同的action,每個action一般也會觸發乙個job(當然也有二般的情況乙個
action可以觸發其他的action)
spark演算法構造和物理執行時最基本的核心:
最大化pipeline
基於pipeline的思想,資料被使用的時候才開始計算,從資料流動的視角來書,資料流動到計算的位置!!!
實質上從邏輯的角度來看,是運算元在資料上流動!
從演算法構建的角度而言:肯定是運算元作用於資料,所以是運算元在資料上流動,方便演算法的構建
從物理執行的角度而言:是資料流動到計算的位置,方便系統最為高效的執行!
對於pipeline而言,資料計算的位置就是每個stage中最後的rdd,乙個震撼人心內部真想就是
:每個stage中除了最後乙個rdd運算元是真實的以外,前面的運算元都是假的
由於計算的lazy特性,導致計算從後向前回溯,形成computing chain,導致的結果就是需要首先計算出具體乙個stage內部左側的rdd中本次計算依賴的partition
三,窄依賴的物理執行內幕
乙個stage內部的rdd都是窄依賴,窄依賴計算本身從邏輯上看是從stage內部最左側的rdd開始立即計算的,根據computing chain ,資料(record)從乙個計算步驟流動到下乙個計算步驟,以此類推,知道計算到stage內部的最後乙個rdd來產生計算結果。
computing chain的構建是從從後向前構建的,而實際的物理計算則是讓資料從前往後在運算元上流動,直到流動到不能流動為止,才計算下乙個record。這就導致乙個美好的結果:
後面的rdd對前面的rdd的依賴雖然是partition級別的資料集合依賴,但是並不需要父rdd把partiton中所有的records計算完畢才整體往後流動資料進行計算,這就極大的提高了計算速率
四: 寬依賴物理執行內幕
必須等到依賴的父stage中的最後乙個rdd全部資料徹底計算完畢,才能夠經過shuffle來計算當前的stage,
下乙個stage只需接受上個stage部分的資料就可以開始計算,並不是把上個stage中的全部資料接受過來就開始計算的。
從資源池和管理的角度理解物理記憶體
乙個任務所需要的記憶體大小以及位置不應該依賴其它任務的記憶體的大小和位置,並且記憶體的位置也不應該是永久性的,任務使用記憶體就應該和人們使用公共廁所一樣。程式任務只管自己的計算邏輯,用到記憶體的時候,不必自己操心,應該有乙個服務機構為其現場分配記憶體,分配多少算好呢,答案就是就可能少,按照基本單位分...
從系統的角度分析影響程式執行效能的因素
從使用者的角度到系統底層的順序來看,linux系統包含以下幾個部分 應用程式 linux系統能夠執行的程式,用於完成使用者所希望的功能 shell程式 用於執行使用者所寫的或者自帶的應用程式 檔案系統 用於組織磁碟上的檔案,規定了檔案的組織和儲存方式 系統呼叫和公用函式庫 作業系統提供的功能函式以及...
從系統的角度分析影響程式執行效能的因素
目錄1.2 記憶體管理 1.3 檔案管理 1.4 驅動裝置程式 1.5 具體例子 2.影響應用程式效能表現的因素 作業系統按照功能可以劃分為程序管理 記憶體管理 檔案管理以及裝置管理,而linux核心也對此進行了實現 程序管理可以說是作業系統核心中最為核心的部分,其主要完成的一些功能可以概述為如下幾...