Spark學習整理之一
一、什麼是Spark
Apache Spark是一個開源的分散式計算框架,用於處理大規模的資料。旨在快速進行資料分析、快速執行和快速開發。Spark不是由一個人開發的,而是誕生於美國加州大學伯克利分校的AMP實驗室。於2010年開放原始碼,2012年釋出了0.6.0版本,距今已有6年曆史,最新版本為2.4.0。
開發Spark可以使用Scala、Java、Python以及R語言。
二、RDD的五大特性
RDD(Resilient Distributed Dataset)彈性分散式資料集
RDD是由一些列的partition組成
RDD提供的每一個函式實際上是作用於每一個partition上
RDD具有一系列的依賴關係,依賴於其他的RDD,RDD的依賴關係也叫RDD的血統(Lineage)
可選項 分割槽器是作用在KV格式的RDD上的
可選項 RDD會提供一系列的最佳的計算位置
注:
Spark中沒有讀檔案的方法,它依賴MapReduce讀檔案的方法,即需要MapReduce中的jar包。MapReduce在讀檔案之前會將檔案劃分為一個個的split,為了保證資料的完整性,split的大小約等於block的大小。第一個RDD的分割槽數等於split的個數。大多數情況下,split的個數約等於block的個數,特殊情況下block的個數大於split的個數。
特殊情況:
假如前兩個block中都存了128M資料,第三個block中只存了第二個block中的最後半行資料,此時第三個block中資料的大小就是半行資料的大小,由於split要保證資料的完整性需要將第三個block中的半行資料劃分到第二個split中,此時split數就小於block的個數。因此,不能說block的個數等於split的個數,只能說大多數情況下兩者相等。
三、解釋RDD的五大特性
1、由圖可知每一個RDD由一系列partition組成。
2、例如將flatMap作用在每一個分割槽上,即父RDD作為flatMap的輸入,子RDD作為flatMap的輸出。
3、當一個partition內丟失,由於子RDD知道父RDD是誰,所以子RDD可以將函式再次作用在父RDD的partition上,重新生成新的partition,正是由於RDD的依賴性(單向依賴),計算的容錯性才高。
4、什麼是KV格式RDD?如果RDD中的資料是二元組型別的,那麼我們就稱RDD是KV格式的RDD。即非KV格式RDD不能使用partitionBy方法。
5、RDD提供了一個方法介面,只要呼叫這個方法介面,就可以找到每一個partition所在的位置。然後將task分發到partition所在節點上執行,這樣有利於資料本地化(計算向資料移動)。
四、RDD的三類運算元
什麼是運算元?運算元也稱為方法、函式。
1、Transformation類
Transformation屬於延遲計算,當使用Transformation類運算元的時候,RDD並沒有立即進行轉換,只是有了對應的邏輯。當出現Action類運算元時,Transformation類運算元才會被執行。
常見的Transformation類運算元:
map()
filter()
flatMap()扁平,返回一組RDD,即一對多。
groupByKey()
作用在KV格式的RDD上,返回一個(K,Seq[V])對的資料集
注意:預設情況下,使用8個並行任務進行分組,你可以傳入numTask可選引數,根據資料量設定不同數目的Task
reduceByKey()
作用在KV格式的RDD上,相同的Key值,都被使用指定的reduce函式聚合到一起。和groupbykey類似,任務的個數可以通過第二個可選引數來配置。
sample(withReplacement,fraction,seed)
withReplacement(Boolean型別): 抽樣的方式。true表示放回式抽樣,false 不放回式抽樣
fraction(Double型別):抽樣比例。隨機抽樣出比例為fraction的資料
seed(Lang型別):隨機演算法的初始值,根據給定的隨機種子seed
union() 返回一個新的資料集,由原資料集和引數聯合而成
join()內連線
在型別為(K,V)和(K,W)型別的資料集上呼叫,返回一個(K,(V,W))對,每個key中的所有元素都在一起的資料集
2、Action類
觸發Transformation類運算元的執行。每當遇見一次Action類運算元,就會執行一個job。
常見的Action類運算元有:
collect()
count() 返回資料集的元素個數
foreach()
reduce()
3、Control類
將資料持久化到記憶體或磁碟。
常見的Control類運算元
cache()
persist()
注:
當persist()的持久化級別是MEMORY_ONLY的時候與cache()作用一樣,所以說cache()是persist()的特例。
注意:
控制類運算元都是懶執行的,需要action類運算元觸發執行
控制類運算元後面不能緊跟action類運算元例如:rdd.cache().count()
cache和persist運算元的返回值可以賦給一個變數,在其他job中直接使用這個變數就可以使用持久化的資料。持久化的單位是partition。
五、Spark Application的大概執行流程
由圖可知:
每一個task都由Driver分發到相應的節點上。
每一個task的計算結果都會被拉回到Driver程序中。但是這個情況是十分危險的,容易造成Driver程序的OOM。可以通過程式碼控制是否將計算結果拉回Driver端。
Driver的作用:
分發task到計算節點
監控task的執行情況
如果task執行失敗,會進行重試
將計算結果拉回Driver端
結論:Driver程序會和叢集進行頻繁的通訊