Spark核心講解之彈性分布資料集(一)

2021-07-10 13:46:20 字數 2181 閱讀 9047

相信大資料工程師都非常了解hadoop mapreduce乙個最大的問題是在很多應用場景中速度非常慢,只適合離線的計算任務。這是由於mr需要將任務劃分成map和reduce兩個階段,map階段產生的中間結果要寫回磁碟,而在這兩個階段之間需要進行shuffle操作。shuffle操作需要從網路中的各個節點進行資料拷貝,使其往往成為最為耗時的步驟,這也是hadoop mapreduce慢的根本原因之一,大量的時間耗費在網路磁碟io中而不是用於計算。在一些特定的計算場景中,例如像邏輯回歸這樣的迭代式的計算mapreduce的弊端會顯得更加明顯。

那spark是如果設計分布式計算的呢?首先我們需要理解spark中最重要的概念–彈性分布資料集rdd。

rdd是spark中對資料和計算的抽象,是spark中最核心的概念,它表示已被分片(partition),不可變的並能夠被並行操作的資料集合。對rdd的操作分為兩種transformation和action。transformation操作是通過轉換從乙個或多個rdd生成新的rdd。action操作是從rdd生成最後的計算結果。在spark最新的版本中,提供豐富的transformation和action操作,比起mapreduce計算模型中僅有的兩種操作,會大大簡化程式開發的難度。

rdd的生成方式只有兩種,一是從資料來源讀入,另一種就是從其它rdd通過transformation操作轉換。乙個典型的spark程式就是通過spark上下文環境spark context生成乙個或多個rdd,在這些rdd上通過一系列的transformation操作生成最終的rdd,最後通過呼叫最終rdd的action方法輸出結果。

雖然spark是基於記憶體的計算,但rdd不光可以儲存在記憶體中,根據usedisk、usememory、useoffheap, deserialized、replication五個引數的組合spark提供了12種儲存級別,在後面介紹rdd的容錯機制時,我們會進一步理解。值得注意的是當storagelevel設定成off_heap時,rdd實際被儲存到tachyon中。tachyon是乙個基於記憶體的分布式檔案系統,目前正在快速發展,本文不做詳細介紹,可以通過其官方**進一步了解。

spark的計算發生在rdd的action操作,而對action之前的所有transformation,spark只是記錄下rdd生成的軌跡,而不會觸發真正的計算。

spark核心會在需要計算發生的時刻繪製一張關於計算路徑的有向無環圖,也就是dag。舉個例子,在圖2中,從輸入中邏輯上生成a和c兩個rdd,經過一系列transformation操作,邏輯上生成了f,注意,我們說的是邏輯上,因為這時候計算沒有發生,spark核心做的事情只是記錄了rdd的生成和依賴關係。當f要進行輸出時,也就是f進行了action操作,spark會根據rdd的依賴生成dag,並從起點開始真正的計算。

圖2 邏輯上的計算過程:dag

有了計算的dag圖,spark核心下一步的任務就是根據dag圖將計算劃分成任務集,也就是stage,這樣可以將任務提交到計算節點進行真正的計算。spark計算的中間結果預設是儲存在記憶體中的,spark在劃分stage的時候會充分考慮在分布式計算中可流水線計算(pipeline)的部分來提高計算的效率,而在這個過程中,主要的根據就是rdd的依賴型別。根據不同的transformation操作,rdd的依賴可以分為窄依賴(narrow dependency)和寬依賴(wide dependency,在**中為shuffledependency)兩種型別。窄依賴指的是生成的rdd中每個partition只依賴於父rdd(s) 固定的partition。寬依賴指的是生成的rdd的每乙個partition都依賴於父rdd所有partition。窄依賴典型的操作有map, filter, union等,寬依賴典型的操作有groupbykey,sortbykey等。可以看到,寬依賴往往意味著shuffle操作,這也是spark劃分stage的主要邊界。對於窄依賴,spark會將其盡量劃分在同乙個stage中,因為它們可以進行流水線計算。

圖3 rdd的寬依賴和窄依賴

我們再通過圖4詳細解釋一下spark中的stage劃分。我們從hdfs中讀入資料生成3個不同的rdd,通過一系列transformation操作後再將計算結果儲存hdfs。可以看到這幅dag中只有join操作是乙個寬依賴,spark核心會以此為邊界將其前後劃分成不同的stage。同時我們可以注意到,在圖中stage2中,從map到union都是窄依賴,這兩步操作可以形成乙個流水線操作,通過map操作生成的partition可以不用等待整個rdd計算結束,而是繼續進行union操作,這樣大大提高了計算的效率。

圖4 spark中的stage劃分

spark核心構件之partitioner

spark 核心思想之一就是資料分割槽,將資料分成很多個part,乙個乙個的進行處理這樣的設定達到了以下的目的。1 實現分布式 2 可以減少記憶體占用 3 還能方便的做任務重跑 4 而且將統一個key的資料聚集到一起,方便join group等操作 首先我們來看下partition的定義 trait...

Spark學習筆記(二) 彈性分布式資料集RDDs

在閱讀很多的spark簡介中,都及多的提到rdds這個名詞。官方文件指出 spark 核心的概念是 resilient distributed dataset rdd 乙個可並行操作的有容錯機制的資料集合。這句話說明rdd的本質是集合,這個集合帶有並行操作和容錯機制。官方文件指出有兩種方式建立rdd...

分布式系統核心要求 分布式鎖實現之關係型資料庫

利用關係型資料庫特性 實現排它鎖 insert唯一約束 和樂觀鎖 update version一致性 表結構 獲取鎖insert into method lock method name,desc values methodname methodname 對method name做了唯一性約束,這裡...