Apache Spark Job的剖析
Apache Spark是通用的大規模數據處理框架。 了解spark如何執行作業對于獲取大部分作業非常重要。
關于Spark評估范式的簡短回顧:Spark使用的是惰性評估范式,在該范式中,Spark應用程序在驅動程序調用“ Action”之前不會執行任何操作。
惰性評估是所有運行時/編譯時優化火花可以完成的關鍵。
懶惰的評估不是新概念。 它在函數式編程中使用了數十年。 數據庫還使用它來創建邏輯和物理執行計劃。 像tensorflow這樣的神經網絡框架也基于惰性評估。 首先,它構建計算圖,然后執行它。
Spark應用程序由工作,階段和任務組成。 作業和任務由Spark并行執行,但作業內部階段是順序執行的。 當您想要調整火花作業時,知道并行執行和順序執行的內容非常重要。
階段是按順序執行的,因此具有多個階段的作業將使它窒息,并且前一階段將進入下一個階段,并且這會帶來一些開銷,其中涉及將階段輸出寫入持久性源(即磁盤,hdfs,s3等)并再次讀取。 這也稱為廣泛轉換/混洗依賴性。
單階段作業將非常快,但是您無法使用單階段構建任何有用的應用程序。
例子
讓我們看一些代碼示例以更好地理解這一點。
val topXNumbers = randomNumbers.filter(_ > 1000) //Stage 1.map(value => (value, 1)) // Stage 1.groupByKey() //Stage 2.map(value => (value._1, value._2.sum)) //Stage 2.sortBy(_._2, false) //Stage 3.count() // Stage 3 星火DAG
spark ui的DAG視圖非常清楚地表明Spark如何查看/執行應用程序。
上面的代碼創建了3個階段,每個階段的邊界都有一些開銷,例如(Shuffle讀/寫)。
單階段(例如階段1)中的步驟已合并過濾器和地圖。
該視圖還具有“任務”,這是執行的最小工作單元。 該應用程序每個階段有2個任務。
spark應用程序如何執行? 讓我們深入研究如何執行它。 Spark應用程序需要3個組件來執行:
- 驅動程序–提交請求以掌握和協調所有任務。
- 集群管理器–根據驅動程序的請求啟動spark執行程序。
- 執行程序–執行作業并將結果發送回驅動程序。
Spark應用程序涉及的2個重要組件是Driver&Executor,當這些組件中的任何一個承受壓力時,它可能是內存/ CPU /網絡/磁盤,Spark作業可能會失敗。
在下一節中,我將分享我在執行人方面的一些經驗。
執行器問題 :每個執行器需要2個參數Cores&Memory。 核心決定執行者可以處理多少個任務,并且該執行者中所有核心/任務之間共享內存。 每個火花作業都有不同類型的需求,因此
反模式,以對所有Spark應用程序使用單一配置。
問題1 –執行者的任務過多 :如果任務太大而無法容納在內存中,執行者將無法處理任務或運行緩慢。 沒什么可尋找這個問題的:
- 驅動程序日志文件長時間停頓(即日志文件不移動)
- GC時間過長,可以從spark UI的“執行者”頁面進行驗證
- 重試舞臺
- 執行器記錄完整的“內存映射圖”消息
- 執行器日志出現OOM錯誤
如何解決呢?
很快出現的一種選擇是在執行器端增加內存。 它可以工作,但是可以在執行程序端添加多少內存將受到限制,因此很快您將用盡該選項,因為大多數集群都是共享的,并且它對可分配給執行程序的最大內存有限制。
下一個更好的選擇是減小單個任務的大小,一切由您控制。 這需要更多的洗牌權衡,但是仍然比以前更好。
Spark UI快照,可用于不良運行和良好運行。
不良運行
好運
第二個是調整分區大小。 不良運行表明所有需要調整分區大小的指標。
問題2 –執行程序中的內核過多 :這也是一個非常常見的問題,因為我們想通過拋出太多任務來使執行程序過載。 讓我們看看如何確定是否存在此問題:
- 執行者方面花費在GC上的時間
- 執行器日志和消息–溢出的內存映射
- 任務執行期間執行程序上的峰值執行內存 。 僅當作業不在歷史記錄服務器上運行時,此選項才可用。
我將放置來自sparkUI的2個快照
Partition Executor Cores MemoryRun 1 100 2 4 2gRun 1 100 2 2 2g4核/ 2執行器
2核心/ 2執行器
8核(4 * 2 Exe)一個人忙于GC開銷,而4核(2 * 2 Executor)的一切都減少了一半,僅使用4個核就更高效。
如果您看到這樣的模式,請減少執行程序核心,并增加執行程序數量,以使Spark工作更快。
問題3 –紗線內存開銷 :這是我的最愛,并且以下錯誤確認Spark應用程序存在此問題
“ ExecutorLostFailure(執行器2退出是由于正在運行的任務之一引起的)原因:容器因超出內存限制而被YARN殺死。
已使用XXX GB的XXX GB物理內存。 考慮提高spark.yarn.executor.memoryOverhead”
每當出現此錯誤時,大多數開發人員都會在堆棧上溢出并增加“ spark.yarn.executor.memoryOverhead”參數值。
這是不錯的選擇,因為短期內它很快就會再次失敗,您將繼續增加它,最終用盡選擇權。
我認為增加“ spark.yarn.executor.memoryOverhead”作為反模式,因為指定的任何內存都會添加到執行程序的總內存中。
此錯誤表示執行程序過載,最好的選擇是嘗試我上面提到的其他解決方案。
Spark有太多的調整參數,以至于有時看起來像是在計劃駕駛艙中選址。
此博客中使用的所有代碼都可以在@sparkperformance github repo上找到
翻譯自: https://www.javacodegeeks.com/2018/10/anatomy-apache-spark-job.html
總結
以上是生活随笔為你收集整理的Apache Spark Job的剖析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 玩家花2个月打造出史上最酷炫吃鸡电脑玩家
- 下一篇: 通过这5个简单的技巧减少GC开销